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 @@ ${_('Proposal Category')} %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 -
-
-
- %if c.user is None: -
- %if h.allow_user_registration(): - ${_('Register')} - ${_("or")} - %endif - ${_('Login')} -
-

- %if h.allow_user_registration(): - ${_('Get an account to participate in the discussion.')} - %else: - ${_('Log in to participate in the discussion.')} - %endif -

- %elif can.instance.join(c.instance): - -

- ${_('Join this instance to start contributing.')} -

- %elif c.instance.require_valid_email and c.user and not c.user.is_email_activated(): - %if c.user.email is None: - -

- ${_('You need to set an email in your profile in order to contribute to this instance.')} -

- %else: - -

- ${_('Please validate your email address in order to contribute to this instance.')}
- ${_('Your registered email address is:')} ${c.user.email} -

- %endif - %else: # h.config.get('adhocracy.propose_optional_attributes') and c.user.optional_attributes is None)): - -

- ${_(u'Please provide statistical information to help scientific evaluation!')}
-

-
- %endif -
-
- - %endif +<% show_attention_getter = ( + 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() + and not c.hide_activate_attention_getter) + or (h.config.get('adhocracy.propose_optional_attributes') + and c.user.optional_attributes is None))) %> + +%if show_attention_getter: +
+
+
+ %if c.user is None: +
+ %if h.allow_user_registration(): + ${_('Register')} + ${_("or")} + %endif + ${_('Login')} +
+

+ %if h.allow_user_registration(): + ${_('Get an account to participate in the discussion.')} + %else: + ${_('Log in to participate in the discussion.')} + %endif +

+ %elif can.instance.join(c.instance): + +

+ ${_('Join this instance to start contributing.')} +

+ %elif c.instance.require_valid_email and c.user and not c.user.is_email_activated(): + %if c.user.email is None: + +

+ ${_('You need to set an email in your profile in order to contribute to this instance.')} +

+ %else: + +

+ ${_('Please validate your email address in order to contribute to this instance.')}
+ ${_('Your registered email address is:')} ${c.user.email} +

+ %endif + %else: # h.config.get('adhocracy.propose_optional_attributes') and c.user.optional_attributes is None)): + +

+ ${_(u'Please provide statistical information to help scientific evaluation!')} +

+ %endif +
+
+
+%endif diff --git a/src/adhocracy/templates/instance/ask_join.html b/src/adhocracy/templates/instance/ask_join.html new file mode 100644 index 000000000..7ab108703 --- /dev/null +++ b/src/adhocracy/templates/instance/ask_join.html @@ -0,0 +1,21 @@ +<%inherit file="/template.html" /> +<%namespace name="components" file="/components.html"/> +<%def name="title()">${_(u'Join %s' % c.instance.label)} + +<%def name="breadcrumbs()"> + ${h.instance.breadcrumbs(c.page_instance)|n} ${_(u'Join')} + + +<%block name="headline"> +

${_(u'Join instance')}

+ + +<%block name="main_content"> +
+ ${h.field_token()|n} + + ${_(u'In order to perform the requested action, you need to join this instance.')} + ${components.savebox(cancel_url=None, save_text=u'Join')} +
+ diff --git a/src/adhocracy/templates/root.html b/src/adhocracy/templates/root.html index 1ae2f1e16..492a49a42 100644 --- a/src/adhocracy/templates/root.html +++ b/src/adhocracy/templates/root.html @@ -112,7 +112,7 @@

${_('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 name="breadcrumbs()"> + ${h.instance.breadcrumbs(c.page_user)|n} ${_(u'Validate email address')} + + +<%block name="headline"> +

${_(u'Validate email address')}

+ + +<%block name="main_content"> +
+ ${h.field_token()|n} + + +

${_(u'You have not yet validated your email address.')}

+

${_(u'An email with a validation link has been sent to your email address (%s) right after registration. Please follow that link in order to proceed.' % c.user.email)}

+

${_(u'If you click on the button below, the validation link will be resent to you.')}

+ + ${components.savebox(cancel_url=None, save_text=u'Resend activation link')} +
+ diff --git a/src/adhocracy/templates/user/pending_activate.html b/src/adhocracy/templates/user/pending_activate.html new file mode 100644 index 000000000..b6c9d4012 --- /dev/null +++ b/src/adhocracy/templates/user/pending_activate.html @@ -0,0 +1,16 @@ +<%inherit file="/template.html" /> +<%namespace name="components" file="/components.html"/> +<%def name="title()">${_(u'Validate email address')} + +<%def name="breadcrumbs()"> + ${h.instance.breadcrumbs(c.page_user)|n} ${_(u'Validate email address')} + + +<%block name="headline"> +

${_(u'Validation email sent')}

+ + +<%block name="main_content"> + ${_(u'An email has been sent to you. Please click on the validation link in this email in order to proceed.')} + +