Revision 0a7a4104
b/snf-astakos-app/astakos/im/functions.py | ||
---|---|---|
42 | 42 |
from django.contrib.auth import ( |
43 | 43 |
login as auth_login, |
44 | 44 |
logout as auth_logout) |
45 |
from django.conf import settings |
|
46 | 45 |
from django.contrib.auth.models import AnonymousUser |
47 | 46 |
from django.core.exceptions import PermissionDenied |
48 | 47 |
from django.db import IntegrityError |
... | ... | |
54 | 53 |
from datetime import datetime |
55 | 54 |
from functools import wraps |
56 | 55 |
|
57 |
import astakos.im.settings as astakos_settings |
|
58 | 56 |
from astakos.im.settings import ( |
59 | 57 |
CONTACT_EMAIL, SITENAME, BASEURL, LOGGING_LEVEL, |
60 | 58 |
VERIFICATION_EMAIL_SUBJECT, ACCOUNT_CREATION_SUBJECT, |
... | ... | |
64 | 62 |
PROJECT_CREATION_SUBJECT, PROJECT_APPROVED_SUBJECT, |
65 | 63 |
PROJECT_TERMINATION_SUBJECT, PROJECT_SUSPENSION_SUBJECT, |
66 | 64 |
PROJECT_MEMBERSHIP_CHANGE_SUBJECT, |
67 |
PROJECT_MEMBER_JOIN_POLICIES, PROJECT_MEMBER_LEAVE_POLICIES, HELPDESK, |
|
68 |
ADMINS, MANAGERS) |
|
65 |
PROJECT_MEMBER_JOIN_POLICIES, PROJECT_MEMBER_LEAVE_POLICIES) |
|
69 | 66 |
from astakos.im.notifications import build_notification, NotificationError |
70 | 67 |
from astakos.im.models import ( |
71 | 68 |
AstakosUser, Invitation, ProjectMembership, ProjectApplication, Project, |
... | ... | |
79 | 76 |
application_submit_notify, application_approve_notify, |
80 | 77 |
application_deny_notify, |
81 | 78 |
project_termination_notify, project_suspension_notify) |
82 |
|
|
79 |
from astakos.im import settings |
|
83 | 80 |
import astakos.im.messages as astakos_messages |
84 | 81 |
from astakos.quotaholder.exception import NoCapacityError |
85 | 82 |
|
... | ... | |
147 | 144 |
dictionary = dictionary or {} |
148 | 145 |
message = render_to_string(template_name, dictionary) |
149 | 146 |
sender = settings.SERVER_EMAIL |
150 |
recipient_list = [e[1] for e in HELPDESK + MANAGERS]
|
|
147 |
recipient_list = [e[1] for e in settings.HELPDESK + settings.MANAGERS]
|
|
151 | 148 |
try: |
152 | 149 |
send_mail(subject, message, sender, recipient_list, |
153 | 150 |
connection=get_connection()) |
... | ... | |
177 | 174 |
{'user': user} |
178 | 175 |
) |
179 | 176 |
sender = settings.SERVER_EMAIL |
180 |
recipient_list = [e[1] for e in HELPDESK + MANAGERS]
|
|
177 |
recipient_list = [e[1] for e in settings.HELPDESK + settings.MANAGERS]
|
|
181 | 178 |
try: |
182 | 179 |
send_mail(_(HELPDESK_NOTIFICATION_EMAIL_SUBJECT) % {'user': user.email}, |
183 | 180 |
message, sender, recipient_list, connection=get_connection()) |
... | ... | |
246 | 243 |
def send_feedback(msg, data, user, email_template_name='im/feedback_mail.txt'): |
247 | 244 |
subject = _(FEEDBACK_EMAIL_SUBJECT) |
248 | 245 |
from_email = settings.SERVER_EMAIL |
249 |
recipient_list = [e[1] for e in HELPDESK] |
|
246 |
recipient_list = [e[1] for e in settings.HELPDESK]
|
|
250 | 247 |
content = render_to_string(email_template_name, { |
251 | 248 |
'message': msg, |
252 | 249 |
'data': data, |
... | ... | |
894 | 891 |
user=user_id, setting=key) |
895 | 892 |
return setting.value |
896 | 893 |
except UserSetting.DoesNotExist: |
897 |
return getattr(astakos_settings, key)
|
|
894 |
return getattr(settings, key) |
|
898 | 895 |
|
899 | 896 |
|
900 | 897 |
def set_user_setting(user_id, key, value): |
b/snf-astakos-app/astakos/im/settings.py | ||
---|---|---|
26 | 26 |
IM_MODULES = getattr(settings, 'ASTAKOS_IM_MODULES', ['local']) |
27 | 27 |
|
28 | 28 |
# Force user profile verification |
29 |
FORCE_PROFILE_UPDATE = getattr(settings, 'ASTAKOS_FORCE_PROFILE_UPDATE', True)
|
|
29 |
FORCE_PROFILE_UPDATE = getattr(settings, 'ASTAKOS_FORCE_PROFILE_UPDATE', False)
|
|
30 | 30 |
|
31 | 31 |
#Enable invitations |
32 | 32 |
INVITATIONS_ENABLED = getattr(settings, 'ASTAKOS_INVITATIONS_ENABLED', False) |
b/snf-astakos-app/astakos/im/tests.py | ||
---|---|---|
66 | 66 |
|
67 | 67 |
settings.LOGGING_SETUP['disable_existing_loggers'] = False |
68 | 68 |
|
69 |
|
|
70 |
prefixes = {'im': 'ASTAKOS_', 'providers': 'AUTH_PROVIDER_', |
|
71 |
'shibboleth': 'AUTH_PROVIDER_SHIBBOLETH_', |
|
72 |
'local': 'AUTH_PROVIDER_LOCAL_'} |
|
69 |
# shortcut decorators to override provider settings |
|
70 |
# e.g. shibboleth_settings(ENABLED=True) will set |
|
71 |
# ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_ENABLED = True in global synnefo settings |
|
72 |
prefixes = {'providers': 'AUTH_PROVIDER_', |
|
73 |
'shibboleth': 'ASTAKOS_AUTH_PROVIDER_SHIBBOLETH_', |
|
74 |
'local': 'ASTAKOS_AUTH_PROVIDER_LOCAL_'} |
|
73 | 75 |
im_settings = functools.partial(with_settings, astakos_settings) |
74 |
provider_settings = functools.partial(with_settings, astakos_settings, |
|
75 |
prefix=prefixes['providers']) |
|
76 | 76 |
shibboleth_settings = functools.partial(with_settings, |
77 |
astakos_settings,
|
|
77 |
settings, |
|
78 | 78 |
prefix=prefixes['shibboleth']) |
79 |
localauth_settings = functools.partial(with_settings, astakos_settings,
|
|
79 |
localauth_settings = functools.partial(with_settings, settings, |
|
80 | 80 |
prefix=prefixes['local']) |
81 | 81 |
|
82 |
|
|
82 | 83 |
class AstakosTestClient(Client): |
83 | 84 |
pass |
84 | 85 |
|
86 |
|
|
85 | 87 |
class ShibbolethClient(AstakosTestClient): |
86 | 88 |
""" |
87 | 89 |
A shibboleth agnostic client. |
... | ... | |
182 | 184 |
astakos_settings.IM_MODULES = ['local', 'shibboleth'] |
183 | 185 |
astakos_settings.MODERATION_ENABLED = True |
184 | 186 |
|
187 |
@im_settings(FORCE_PROFILE_UPDATE=False) |
|
185 | 188 |
def test_create_account(self): |
186 | 189 |
|
187 | 190 |
client = ShibbolethClient() |
... | ... | |
233 | 236 |
'last_name': 'Mitroglou', |
234 | 237 |
'provider': 'shibboleth'} |
235 | 238 |
|
239 |
signup_url = reverse('signup') |
|
240 |
|
|
236 | 241 |
# invlid email |
237 | 242 |
post_data['email'] = 'kpap' |
238 |
r = client.post('/im/signup', post_data)
|
|
243 |
r = client.post(signup_url, post_data)
|
|
239 | 244 |
self.assertContains(r, token) |
240 | 245 |
|
241 | 246 |
# existing email |
242 | 247 |
existing_user = get_local_user('test@test.com') |
243 | 248 |
post_data['email'] = 'test@test.com' |
244 |
r = client.post('/im/signup', post_data)
|
|
249 |
r = client.post(signup_url, post_data)
|
|
245 | 250 |
self.assertContains(r, messages.EMAIL_USED) |
246 | 251 |
existing_user.delete() |
247 | 252 |
|
248 | 253 |
# and finally a valid signup |
249 | 254 |
post_data['email'] = 'kpap@grnet.gr' |
250 |
r = client.post('/im/signup', post_data, follow=True)
|
|
255 |
r = client.post(signup_url, post_data, follow=True)
|
|
251 | 256 |
self.assertContains(r, messages.NOTIFICATION_SENT) |
252 | 257 |
|
253 | 258 |
# everything is ok in our db |
... | ... | |
267 | 272 |
cn="Kostas Papadimitriou", ) |
268 | 273 |
r = client.get("/im/login/shibboleth?", follow=True) |
269 | 274 |
self.assertContains(r, 'is pending moderation') |
270 |
r = client.get("/im/profile", follow=True) |
|
271 |
self.assertRedirects(r, 'http://testserver/im/?next=/im/profile') |
|
272 | 275 |
|
273 | 276 |
# admin activates our user |
274 | 277 |
u = AstakosUser.objects.get(username="kpap@grnet.gr") |
... | ... | |
434 | 437 |
|
435 | 438 |
# we can reenable the local provider by setting a password |
436 | 439 |
r = client.get("/im/password_change", follow=True) |
437 |
r = client.post("/im/password_change", {'new_password1':'111', |
|
440 |
r = client.post("/im/password_change", {'new_password1': '111',
|
|
438 | 441 |
'new_password2': '111'}, |
439 | 442 |
follow=True) |
440 | 443 |
user = r.context['request'].user |
... | ... | |
539 | 542 |
form = forms.LocalUserCreationForm(data) |
540 | 543 |
self.assertFalse(form.is_valid()) |
541 | 544 |
|
542 |
@with_settings(settings, HELPDESK=(('support','support@synnefo.org'),)) |
|
545 |
@im_settings(HELPDESK=(('support', 'support@synnefo.org'),)) |
|
546 |
@im_settings(FORCE_PROFILE_UPDATE=False) |
|
543 | 547 |
def test_local_provider(self): |
544 | 548 |
self.helpdesk_email = astakos_settings.HELPDESK[0][1] |
545 | 549 |
# enable moderation |
... | ... | |
564 | 568 |
self.assertFalse(user.activation_sent) # activation automatically sent |
565 | 569 |
|
566 | 570 |
# admin gets notified and activates the user from the command line |
567 |
|
|
568 | 571 |
self.assertEqual(len(get_mailbox(self.helpdesk_email)), 1) |
569 | 572 |
r = self.client.post('/im/local', {'username': 'kpap@grnet.gr', |
570 | 573 |
'password': 'password'}) |
... | ... | |
782 | 785 |
@shibboleth_settings(AUTOMODERATE_POLICY=True) |
783 | 786 |
@im_settings(IM_MODULES=['shibboleth', 'local']) |
784 | 787 |
@im_settings(MODERATION_ENABLED=True) |
788 |
@im_settings(FORCE_PROFILE_UPDATE=False) |
|
785 | 789 |
def test_user(self): |
786 | 790 |
Profile = AuthProviderPolicyProfile |
787 | 791 |
Pending = PendingThirdPartyUser |
788 | 792 |
User = AstakosUser |
789 | 793 |
|
790 |
oldpendinguser = User.objects.create(email="newuser@grnet.gr")
|
|
791 |
olduser = get_local_user("olduser@grnet.gr")
|
|
794 |
User.objects.create(email="newuser@grnet.gr") |
|
795 |
get_local_user("olduser@grnet.gr") |
|
792 | 796 |
cl_olduser = ShibbolethClient() |
793 |
olduser2 = get_local_user("olduser2@grnet.gr")
|
|
794 |
cl_olduser2 = ShibbolethClient()
|
|
797 |
get_local_user("olduser2@grnet.gr") |
|
798 |
ShibbolethClient() |
|
795 | 799 |
cl_newuser = ShibbolethClient() |
796 | 800 |
cl_newuser2 = Client() |
797 | 801 |
|
798 |
policy = ('only_academic', 'shibboleth') |
|
799 | 802 |
academic_group, created = Group.objects.get_or_create( |
800 | 803 |
name='academic-login') |
801 | 804 |
academic_users = academic_group.user_set |
... | ... | |
1201 | 1204 |
self.service = Service.objects.create(name="service1", |
1202 | 1205 |
api_url="http://service.api") |
1203 | 1206 |
self.resource = Resource.objects.create(name="service1.resource", |
1204 |
uplimit=100) |
|
1207 |
uplimit=100, |
|
1208 |
service=self.service) |
|
1205 | 1209 |
self.admin = get_local_user("projects-admin@synnefo.org") |
1206 | 1210 |
self.admin.uuid = 'uuid1' |
1207 | 1211 |
self.admin.save() |
b/snf-astakos-app/astakos/im/urls.py | ||
---|---|---|
37 | 37 |
ExtendedPasswordResetForm, |
38 | 38 |
ExtendedPasswordChangeForm, |
39 | 39 |
ExtendedSetPasswordForm, LoginForm) |
40 |
from astakos.im.settings import IM_MODULES, INVITATIONS_ENABLED, EMAILCHANGE_ENABLED |
|
40 |
|
|
41 |
from astakos.im import settings |
|
41 | 42 |
|
42 | 43 |
urlpatterns = patterns( |
43 | 44 |
'astakos.im.views', |
... | ... | |
81 | 82 |
) |
82 | 83 |
|
83 | 84 |
|
84 |
if EMAILCHANGE_ENABLED: |
|
85 |
if settings.EMAILCHANGE_ENABLED:
|
|
85 | 86 |
urlpatterns += patterns( |
86 | 87 |
'astakos.im.views', |
87 | 88 |
url(r'^email_change/?$', 'change_email', {}, name='email_change'), |
88 | 89 |
url(r'^email_change/confirm/(?P<activation_key>\w+)/?$', 'change_email', {}, |
89 | 90 |
name='email_change_confirm')) |
90 | 91 |
|
91 |
if 'local' in IM_MODULES: |
|
92 |
if 'local' in settings.IM_MODULES:
|
|
92 | 93 |
urlpatterns += patterns( |
93 | 94 |
'astakos.im.target', |
94 | 95 |
url(r'^local/?$', 'local.login'), |
... | ... | |
113 | 114 |
url(r'^local/password/reset/complete/?$', 'password_reset_complete') |
114 | 115 |
) |
115 | 116 |
|
116 |
if INVITATIONS_ENABLED: |
|
117 |
if settings.INVITATIONS_ENABLED:
|
|
117 | 118 |
urlpatterns += patterns( |
118 | 119 |
'astakos.im.views', |
119 | 120 |
url(r'^invite/?$', 'invite', {}, name='invite')) |
120 | 121 |
|
121 |
if 'shibboleth' in IM_MODULES: |
|
122 |
if 'shibboleth' in settings.IM_MODULES:
|
|
122 | 123 |
urlpatterns += patterns( |
123 | 124 |
'astakos.im.target', |
124 | 125 |
url(r'^login/shibboleth/?$', 'shibboleth.login'), |
125 | 126 |
) |
126 | 127 |
|
127 |
if 'twitter' in IM_MODULES: |
|
128 |
if 'twitter' in settings.IM_MODULES:
|
|
128 | 129 |
urlpatterns += patterns( |
129 | 130 |
'astakos.im.target', |
130 | 131 |
url(r'^login/twitter/?$', 'twitter.login'), |
131 | 132 |
url(r'^login/twitter/authenticated/?$', |
132 | 133 |
'twitter.authenticated')) |
133 | 134 |
|
134 |
if 'google' in IM_MODULES: |
|
135 |
if 'google' in settings.IM_MODULES:
|
|
135 | 136 |
urlpatterns += patterns( |
136 | 137 |
'astakos.im.target', |
137 | 138 |
url(r'^login/google/?$', 'google.login'), |
138 | 139 |
url(r'^login/google/authenticated/?$', |
139 | 140 |
'google.authenticated')) |
140 | 141 |
|
141 |
if 'linkedin' in IM_MODULES: |
|
142 |
if 'linkedin' in settings.IM_MODULES:
|
|
142 | 143 |
urlpatterns += patterns( |
143 | 144 |
'astakos.im.target', |
144 | 145 |
url(r'^login/linkedin/?$', 'linkedin.login'), |
b/snf-astakos-app/astakos/im/util.py | ||
---|---|---|
47 | 47 |
from django.utils.translation import ugettext as _ |
48 | 48 |
|
49 | 49 |
from astakos.im.models import AstakosUser, Invitation |
50 |
from astakos.im.settings import ( |
|
51 |
COOKIE_DOMAIN, FORCE_PROFILE_UPDATE, LOGIN_SUCCESS_URL) |
|
52 | 50 |
from astakos.im.functions import login |
51 |
from astakos.im import settings |
|
53 | 52 |
|
54 | 53 |
import astakos.im.messages as astakos_messages |
55 | 54 |
|
... | ... | |
170 | 169 |
except ValidationError, e: |
171 | 170 |
return HttpResponseBadRequest(e) |
172 | 171 |
|
173 |
next = restrict_next(next, domain=COOKIE_DOMAIN) |
|
172 |
next = restrict_next(next, domain=settings.COOKIE_DOMAIN)
|
|
174 | 173 |
|
175 |
if FORCE_PROFILE_UPDATE and not user.is_verified and not user.is_superuser: |
|
174 |
if settings.FORCE_PROFILE_UPDATE and \ |
|
175 |
not user.is_verified and not user.is_superuser: |
|
176 | 176 |
params = '' |
177 | 177 |
if next: |
178 | 178 |
params = '?' + urlencode({'next': next}) |
... | ... | |
186 | 186 |
request.session.set_expiry(user.auth_token_expires) |
187 | 187 |
|
188 | 188 |
if not next: |
189 |
next = LOGIN_SUCCESS_URL |
|
189 |
next = settings.LOGIN_SUCCESS_URL
|
|
190 | 190 |
|
191 | 191 |
response['Location'] = next |
192 | 192 |
response.status_code = 302 |
Also available in: Unified diff