diff --git a/src/adhocracy/config/routing.py b/src/adhocracy/config/routing.py index af1ac4e68..63a4ecca8 100644 --- a/src/adhocracy/config/routing.py +++ b/src/adhocracy/config/routing.py @@ -73,6 +73,8 @@ def make_map(config): 'revert': 'GET', 'reset': 'GET', 'activate': 'GET', + 'ask_activate': 'GET', + 'pending_activate': 'GET', 'resend': 'GET', 'set_password': 'POST', 'generate_welcome_link': 'POST'}, @@ -462,6 +464,7 @@ def make_map(config): conditions=dict(method=['POST'])) map.resource('instance', 'instance', member={'join': 'GET', + 'ask_join': 'GET', 'leave': 'POST', 'filter': 'GET', 'ask_leave': 'GET', diff --git a/src/adhocracy/controllers/instance.py b/src/adhocracy/controllers/instance.py index ec4ab8ffe..791b29a61 100644 --- a/src/adhocracy/controllers/instance.py +++ b/src/adhocracy/controllers/instance.py @@ -962,6 +962,12 @@ def delete(self, id, format='html'): c.page_instance.label, force_path='/') + @RequireInstance + def ask_join(self, id, format='html'): + c.page_instance = self._get_current_instance(id) + require.instance.join(c.page_instance) + return render('/instance/ask_join.html') + @RequireInstance @csrf.RequireInternalRequest() def join(self, id, format='html'): diff --git a/src/adhocracy/controllers/user.py b/src/adhocracy/controllers/user.py index da6f4eb51..d2593078b 100644 --- a/src/adhocracy/controllers/user.py +++ b/src/adhocracy/controllers/user.py @@ -726,13 +726,25 @@ def activate(self, id): instance_filter=False) code = self.form_result.get('c') + # If activate_came_from is set, we assume that we've tried to do + # validate email address during doing some other action. + activate_came_from = session.get('activate_came_from') + if activate_came_from: + c.came_from = activate_came_from + del session['activate_came_from'] + success_url = activate_came_from + no_success_url = h.validate_redirect_url() + else: + success_url = h.entity_url(c.page_user) + no_success_url = h.entity_url(c.page_user) + if c.page_user.activation_code != code: h.flash(_("The activation code is invalid. Please have it " "resent."), 'error') - redirect(h.entity_url(c.page_user)) + redirect(no_success_url) if c.page_user.activation_code is None: h.flash(_(u'Thank you, The address is already activated.')) - redirect(h.entity_url(c.page_user)) + redirect(success_url) c.page_user.activation_code = None model.meta.Session.commit() @@ -751,9 +763,33 @@ def activate(self, id): redirect(h.user.post_register_url(c.page_user)) else: h.flash(_("Your email has been confirmed."), 'success') - redirect(h.entity_url(c.page_user)) + redirect(success_url) - redirect(h.entity_url(c.page_user)) + redirect(success_url) + + def ask_activate(self, id): + c.page_user = get_entity_or_abort(model.User, id, + instance_filter=False) + if c.page_user.is_email_activated(): + if c.came_from: + redirect(c.came_from) + else: + redirect(h.entity_url(c.page_user)) + + c.hide_activate_attention_getter = True + return render('/user/ask_activate.html') + + def pending_activate(self, id): + c.page_user = get_entity_or_abort(model.User, id, + instance_filter=False) + if c.page_user.is_email_activated(): + if c.came_from: + redirect(c.came_from) + else: + redirect(h.entity_url(c.page_user)) + + c.hide_activate_attention_getter = True + return render('/user/pending_activate.html') @RequireInternalRequest() def resend(self, id): @@ -762,11 +798,18 @@ def resend(self, id): require.user.edit(c.page_user) libmail.send_activation_link(c.page_user) + if c.came_from: + session['activate_came_from'] = c.came_from + force_path = h.entity_url(c.page_user, member='pending_activate', + query={'came_from': c.came_from}) + else: + force_path = None + ret_success( message=_("The activation link has been re-sent to your email " "address."), category='success', entity=c.page_user, member='settings/notifications', - format=None, force_path=c.came_from) + format=None, force_path=force_path) @staticmethod def _get_profile_nav(user, active_key): diff --git a/src/adhocracy/lib/auth/__init__.py b/src/adhocracy/lib/auth/__init__.py index e67add1d7..a206c2b83 100644 --- a/src/adhocracy/lib/auth/__init__.py +++ b/src/adhocracy/lib/auth/__init__.py @@ -139,11 +139,19 @@ def check(self, *a, **kw): return self.closure() else: return auth_check - elif auth_check.need_login(): + elif auth_check.propose_login(): # Authentication might help from adhocracy.lib.helpers import login_redirect_url from pylons.controllers.util import redirect redirect(login_redirect_url()) + elif auth_check.propose_join(): + from adhocracy.lib.helpers import join_redirect_url + from pylons.controllers.util import redirect + redirect(join_redirect_url()) + elif auth_check.propose_validate_email(): + from adhocracy.lib.helpers import validate_redirect_url + from pylons.controllers.util import redirect + redirect(validate_redirect_url()) else: from adhocracy.lib.templating import ret_abort log.debug("Aborting due to authorisation error: %s" % diff --git a/src/adhocracy/lib/helpers/__init__.py b/src/adhocracy/lib/helpers/__init__.py index 157a082ee..a07c48a45 100644 --- a/src/adhocracy/lib/helpers/__init__.py +++ b/src/adhocracy/lib/helpers/__init__.py @@ -208,6 +208,15 @@ def register_redirect_url(entity=None, **kwargs): return get_redirect_url(u'register', entity, **kwargs) +def join_redirect_url(entity=None, **kwargs): + return get_redirect_url(u'instance/%s/ask_join' % c.instance.key, **kwargs) + + +def validate_redirect_url(entity=None, **kwargs): + return get_redirect_url(u'user/%s/ask_activate' % c.user.user_name, entity, + **kwargs) + + def entity_url(entity, **kwargs): if isinstance(entity, model.User): return user.url(entity, **kwargs) diff --git a/src/adhocracy/lib/helpers/user_helper.py b/src/adhocracy/lib/helpers/user_helper.py index 3c2cb58fa..3325fa43f 100644 --- a/src/adhocracy/lib/helpers/user_helper.py +++ b/src/adhocracy/lib/helpers/user_helper.py @@ -126,3 +126,9 @@ def can_change_password(user): return asbool(config.get('adhocracy.allow_password_change', 'false')) else: return True + + +def activation_url(): + from adhocracy.lib.auth.csrf import url_token + from adhocracy.lib.helpers import base_url + return base_url('/user/%s/resend?%s' % (c.user.user_name, url_token())) diff --git a/src/adhocracy/templates/components.html b/src/adhocracy/templates/components.html index 11f493143..cb65a348d 100644 --- a/src/adhocracy/templates/components.html +++ b/src/adhocracy/templates/components.html @@ -358,7 +358,7 @@ %if selected: <% (cat_id, key) = selected %> - + @@ -404,67 +404,77 @@ <%def name="attention_getter()"> - %if not h.config.get_bool(u'adhocracy.readonly') and c.instance is not None and (c.user is None or can.instance.join(c.instance) or (c.instance.requires_valid_email() and c.user and not c.user.is_email_activated()) or (h.config.get('adhocracy.propose_optional_attributes') and c.user.optional_attributes is None)): - <%doc>add an attention getter on instances%doc> -
${_('Validate email to start contributing.')}
- ${_('Send activation link')} + ${_('Send activation link')} ${_("or")} ${_("Edit profile")} diff --git a/src/adhocracy/templates/user/ask_activate.html b/src/adhocracy/templates/user/ask_activate.html new file mode 100644 index 000000000..50e29ade5 --- /dev/null +++ b/src/adhocracy/templates/user/ask_activate.html @@ -0,0 +1,25 @@ +<%inherit file="/template.html" /> +<%namespace name="components" file="/components.html"/> +<%def name="title()">${_(u'Validate email address')}%def> + +<%def name="breadcrumbs()"> + ${h.instance.breadcrumbs(c.page_user)|n} ${_(u'Validate email address')} +%def> + +<%block name="headline"> +