Skip to content

Commit 49b0b98

Browse files
authored
Merge pull request #23 from rdmorganiser/shibboleth
Shibboleth
2 parents ae535b8 + 59cabd5 commit 49b0b98

File tree

11 files changed

+192
-31
lines changed

11 files changed

+192
-31
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from django.core.management.base import BaseCommand
2+
from django.contrib.auth.models import User
3+
4+
5+
class Command(BaseCommand):
6+
7+
def add_arguments(self, parser):
8+
parser.add_argument('username', action='store', help='Username of the new admin.')
9+
10+
def handle(self, *args, **options):
11+
user = User.objects.get(username=options['username'])
12+
user.is_staff = True
13+
user.is_admin = True
14+
user.is_superuser = True
15+
user.save()

apps/core/static/core/css/base.scss

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ form {
5656
.navbar-default {
5757
border-bottom: none;
5858
}
59+
.navbar-default .dropdown li.divider:first-child {
60+
display: none;
61+
}
5962

6063
/* content */
6164

apps/core/templates/core/base_navigation.html

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,27 +66,35 @@
6666
<li class="dropdown">
6767
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">{% full_name user %}<span class="caret"></span></a>
6868
<ul class="dropdown-menu">
69+
{% if settings.ACCOUNT_UPDATE_PROFILE %}
6970
<li>
7071
<a href="{% url 'profile_update' %}">{% trans 'Update profile' %}</a>
7172
</li>
73+
{% endif %}
74+
{% if settings.ACCOUNT_UPDATE_EMAIL %}
7275
<li>
7376
<a href="{% url 'account_email' %}">{% trans 'Update email' %}</a>
7477
</li>
78+
{% endif %}
79+
{% if settings.ACCOUNT_UPDATE_PASSWORD %}
7580
<li>
7681
<a href="{% url 'account_change_password' %}">{% trans 'Change password' %}</a>
7782
</li>
83+
{% endif %}
84+
{% if settings.SOCIALACCOUNT %}
7885
<li>
7986
<a href="{% url 'socialaccount_connections' %}">{% trans 'Account connections' %}</a>
8087
</li>
88+
{% endif %}
8189
<li role="separator" class="divider"></li>
8290
<li>
83-
<a href="{% url 'account_logout' %}">{% trans 'Logout' %}</a>
91+
<a href="{{ settings.LOGOUT_URL }}">{% trans 'Logout' %}</a>
8492
</li>
8593
</ul>
8694
</li>
8795
{% else %}
8896
<li>
89-
<a href="{% url 'account_login' %}">{% trans 'Login' %}</a>
97+
<a href="{{ settings.LOGIN_URL }}">{% trans 'Login' %}</a>
9098
</li>
9199
{% endif %}
92100
</ul>

apps/core/templatetags/core_tags.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,9 @@
99
from django.utils.encoding import force_text
1010
from django.utils.safestring import mark_safe
1111

12-
from ..utils import get_script_alias
13-
1412
register = template.Library()
1513

1614

17-
@register.simple_tag(takes_context=True)
18-
def base_url(context):
19-
return get_script_alias(context.request) + '/'
20-
21-
2215
@register.simple_tag()
2316
def i18n_switcher():
2417
string = ''

apps/core/tests.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,6 @@
55
from django.test.client import RequestFactory
66
from django.utils import translation
77

8-
# from apps.core.testing.mixins import (
9-
10-
# )
11-
128

139
class CoreTestCase(TestCase):
1410

@@ -65,8 +61,7 @@ def test_i18n_switcher(self):
6561
self.assertIn('en', response['Content-Language'])
6662

6763

68-
class CoreTagsTests(CoreTestCase):
69-
64+
class CoreTagsTests(TestCase):
7065
def setUp(self):
7166
self.request = RequestFactory().get('/')
7267

docs/shibboleth.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
Shibboleth
2+
==========
3+
4+
In order to use Shibboleth with RDMO it needs to be deployed in a production environment using Apache2. The Setup is documented [here](docs/production-setup.md).
5+
6+
Next install the Shibboleth Apache module for service providers from your distirbutions repository, e.g. for debian/Ubuntu:
7+
8+
```
9+
apt-get install libapache2-mod-shib2
10+
```
11+
12+
In addition, [django-shibboleth-remoteuser](https://github.com/Brown-University-Library/django-shibboleth-remoteuser) needs to be installed in your RDMO virtual environment:
13+
14+
```
15+
pip install -r requirements/shibboleth.txt
16+
```
17+
18+
Configure your Shibboleth service provider using the files in `/etc/shibboleth/`. This may vary depending on your Identity Provider. RDMO needs the `RDMOTE_SERVER` to be set and 4 attributes from your identity provider:
19+
20+
* a username (usually `eppn`)
21+
* an email address (usually `mail` or `email`)
22+
* a first name (usually `givenName`)
23+
* a last name (usually `sn`)
24+
25+
In our test environent this is accomplished by editing '/etc/shibboleth/shibboleth2.xml':
26+
27+
```
28+
<ApplicationDefaults entityID="https://sp.vbox/shibboleth"
29+
REMOTE_USER="uid eppn persistent-id targeted-id">
30+
```
31+
32+
and '/etc/shibboleth/attribute-map.xml':
33+
34+
```
35+
<Attribute name="urn:oid:0.9.2342.19200300.100.1.1" id="uid"/>
36+
<Attribute name="urn:oid:2.5.4.4" id="sn"/>
37+
<Attribute name="urn:oid:2.5.4.42" id="givenName"/>
38+
<Attribute name="urn:oid:0.9.2342.19200300.100.1.3" id="mail"/>
39+
```
40+
41+
Restart the Shibboleth service provider demon.
42+
43+
```
44+
service shibd restart
45+
```
46+
47+
In your Apache2 virtual host configuration, add:
48+
49+
```
50+
<Location /Shibboleth.sso>
51+
SetHandler shib
52+
</Location>
53+
<Location />
54+
AuthType shibboleth
55+
require shibboleth
56+
ShibRequireSession On
57+
ShibUseHeaders On
58+
</Location>
59+
```
60+
61+
In your `rdmo/settings/local.py` add:
62+
63+
```
64+
INSTALLED_APPS += ['shibboleth']
65+
SHIBBOLETH_ATTRIBUTE_MAP = {
66+
'uid': (True, 'username'),
67+
'givenName': (True, 'first_name'),
68+
'sn': (True, 'last_name'),
69+
'mail': (True, 'email'),
70+
}
71+
```
72+
73+
where the keys of `SHIBBOLETH_ATTRIBUTE_MAP` need to be modified according to your setup.
74+
75+
Restart the webserver.
76+
77+
```
78+
service apache2 restart
79+
```
80+
81+
From now on, you will be directed to your identity provider login when visiting RDMO.
82+
83+
Since you cannot log in using the admin account created with `createsuperuser` anymore, you need to promote your Shibboleth user to superuser status using:
84+
85+
```
86+
./manage.py promote-user-to-superuser YOURUSERNAME
87+
```

rdmo/settings/base.py

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
]
4848

4949
MIDDLEWARE_CLASSES = [
50+
'django.middleware.security.SecurityMiddleware',
5051
'django.contrib.sessions.middleware.SessionMiddleware',
5152
'django.middleware.locale.LocaleMiddleware',
5253
'django.middleware.common.CommonMiddleware',
@@ -55,7 +56,6 @@
5556
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
5657
'django.contrib.messages.middleware.MessageMiddleware',
5758
'django.middleware.clickjacking.XFrameOptionsMiddleware',
58-
'django.middleware.security.SecurityMiddleware',
5959
'django.contrib.sites.middleware.CurrentSiteMiddleware'
6060
]
6161

@@ -71,7 +71,8 @@
7171
'django.template.context_processors.debug',
7272
'django.template.context_processors.request',
7373
'django.contrib.auth.context_processors.auth',
74-
'django.contrib.messages.context_processors.messages'
74+
'django.contrib.messages.context_processors.messages',
75+
'django_settings_export.settings_export',
7576
],
7677
},
7778
},
@@ -90,6 +91,12 @@
9091
}
9192
}
9293

94+
ACCOUNT_SIGNUP = True
95+
96+
ACCOUNT_UPDATE_PROFILE = True
97+
ACCOUNT_UPDATE_EMAIL = True
98+
ACCOUNT_UPDATE_PASSWORD = True
99+
93100
ACCOUNT_SIGNUP_FORM_CLASS = 'apps.accounts.forms.SignupForm'
94101
ACCOUNT_USER_DISPLAY = 'apps.accounts.utils.get_full_name'
95102
ACCOUNT_EMAIL_REQUIRED = True
@@ -100,6 +107,8 @@
100107
ACCOUNT_USERNAME_MIN_LENGTH = 4
101108
ACCOUNT_PASSWORD_MIN_LENGTH = 4
102109

110+
SOCIALACCOUNT = False
111+
103112
LANGUAGE_CODE = 'en-us'
104113

105114
TIME_ZONE = 'Europe/Berlin'
@@ -156,6 +165,16 @@
156165
'UNICODE_JSON': False
157166
}
158167

168+
SETTINGS_EXPORT = [
169+
'LOGIN_URL',
170+
'LOGOUT_URL',
171+
'ACCOUNT_SIGNUP',
172+
'ACCOUNT_UPDATE_PROFILE',
173+
'ACCOUNT_UPDATE_EMAIL',
174+
'ACCOUNT_UPDATE_PASSWORD',
175+
'SOCIALACCOUNT',
176+
]
177+
159178
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
160179
EMAIL_FROM = '[email protected]'
161180

@@ -178,13 +197,30 @@
178197
except ImportError:
179198
pass
180199

181-
try:
182-
ADDITIONAL_APPS
183-
except NameError:
184-
pass
185-
else:
186-
INSTALLED_APPS = INSTALLED_APPS + ADDITIONAL_APPS
200+
# check if any socialaccount providers are enabled
201+
if any([app.startswith('allauth.socialaccount.providers') for app in INSTALLED_APPS]):
202+
SOCIALACCOUNT = True
203+
204+
# add Shibboleth configuration if local.SHIBBOLETH_ATTRIBUTE_LIST is set
205+
if 'shibboleth' in INSTALLED_APPS:
206+
AUTHENTICATION_BACKENDS = (
207+
'shibboleth.backends.ShibbolethRemoteUserBackend',
208+
'django.contrib.auth.backends.ModelBackend',
209+
)
210+
211+
MIDDLEWARE_CLASSES.insert(
212+
MIDDLEWARE_CLASSES.index('django.contrib.auth.middleware.AuthenticationMiddleware') + 1,
213+
'shibboleth.middleware.ShibbolethRemoteUserMiddleware'
214+
)
215+
216+
LOGIN_URL = '/Shibboleth.sso/Login'
217+
LOGOUT_URL = '/Shibboleth.sso/Logout'
218+
219+
ACCOUNT_UPDATE_PROFILE = False
220+
ACCOUNT_UPDATE_EMAIL = False
221+
ACCOUNT_UPDATE_PASSWORD = False
187222

223+
# add static and templates from local.THEME_DIR to STATICFILES_DIRS and TEMPLATES
188224
try:
189225
THEME_DIR
190226
except NameError:
@@ -195,6 +231,7 @@
195231
]
196232
TEMPLATES[0]['DIRS'].append(os.path.join(THEME_DIR, 'templates/'))
197233

234+
# prepend the local.BASE_URL to the different URL settings
198235
try:
199236
BASE_URL
200237
except NameError:

rdmo/settings/sample.local.py

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from base import INSTALLED_APPS
2+
13
'''
24
Secret key, use something random in production
35
'''
@@ -21,14 +23,9 @@
2123
'''
2224
Additional Django app to be used.
2325
'''
24-
# ADDITIONAL_APPS = (
25-
# 'django_extensions',
26-
# 'allauth.socialaccount.providers.facebook',
27-
# 'allauth.socialaccount.providers.github',
28-
# 'allauth.socialaccount.providers.google',
29-
# 'allauth.socialaccount.providers.orcid',
30-
# 'allauth.socialaccount.providers.twitter',
31-
# )
26+
# INSTALLED_APPS += [
27+
# 'django_extensions'
28+
# ]
3229

3330
'''
3431
A directory with a `static` and a `templates` directory containing customisation.
@@ -94,6 +91,18 @@
9491
# EMAIL_HOST_PASSWORD = ''
9592
# EMAIL_USE_TLS = True
9693

94+
'''
95+
Social accounts configuration
96+
'''
97+
# INSTALLED_APPS += [
98+
# 'django_extensions',
99+
# 'allauth.socialaccount.providers.facebook',
100+
# 'allauth.socialaccount.providers.github',
101+
# 'allauth.socialaccount.providers.google',
102+
# 'allauth.socialaccount.providers.orcid',
103+
# 'allauth.socialaccount.providers.twitter',
104+
# ]
105+
97106
'''
98107
LDAP configuration
99108
'''
@@ -110,3 +119,14 @@
110119
# "last_name": "sn",
111120
# 'email': 'mail'
112121
# }
122+
123+
'''
124+
SHIBBOLETH configuration
125+
'''
126+
# INSTALLED_APPS += ['shibboleth']
127+
# SHIBBOLETH_ATTRIBUTE_MAP = {
128+
# 'uid': (True, 'username'),
129+
# 'givenName': (True, 'first_name'),
130+
# 'sn': (True, 'last_name'),
131+
# 'mail': (True, 'email'),
132+
# }

rdmo/urls.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from django.conf import settings
12
from django.conf.urls import include, url
23
from django.contrib import admin
34

requirements/base.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ django-mptt==0.8.6
88
django-compressor>=2.0
99
django-libsass>=0.4
1010
django-bower==5.2.0
11+
django-settings-export==1.2.1
1112

1213
jsonfield>=1.0.0
1314
Markdown==2.6.7

0 commit comments

Comments
 (0)