diff --git a/invenio/modules/accounts/templates/accounts/edit.html b/invenio/modules/accounts/templates/accounts/edit.html new file mode 100644 index 000000000..e61288078 --- /dev/null +++ b/invenio/modules/accounts/templates/accounts/edit.html @@ -0,0 +1,19 @@ +{# +## This file is part of Invenio. +## Copyright (C) 2014 CERN. +## +## Invenio is free software; you can redistribute it and/or +## modify it under the terms of the GNU General Public License as +## published by the Free Software Foundation; either version 2 of the +## License, or (at your option) any later version. +## +## Invenio is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Invenio; if not, write to the Free Software Foundation, Inc., +## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. +#} +{%- extends "accounts/edit_base.html" -%} \ No newline at end of file diff --git a/invenio/modules/accounts/templates/accounts/index.html b/invenio/modules/accounts/templates/accounts/index.html new file mode 100644 index 000000000..38bcf27b9 --- /dev/null +++ b/invenio/modules/accounts/templates/accounts/index.html @@ -0,0 +1,19 @@ +{# +## This file is part of Invenio. +## Copyright (C) 2014 CERN. +## +## Invenio is free software; you can redistribute it and/or +## modify it under the terms of the GNU General Public License as +## published by the Free Software Foundation; either version 2 of the +## License, or (at your option) any later version. +## +## Invenio is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Invenio; if not, write to the Free Software Foundation, Inc., +## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. +#} +{%- extends "accounts/index_base.html" -%} \ No newline at end of file diff --git a/invenio/modules/accounts/templates/accounts/login.html b/invenio/modules/accounts/templates/accounts/login.html new file mode 100644 index 000000000..d6c94b7f6 --- /dev/null +++ b/invenio/modules/accounts/templates/accounts/login.html @@ -0,0 +1,19 @@ +{# +## This file is part of Invenio. +## Copyright (C) 2014 CERN. +## +## Invenio is free software; you can redistribute it and/or +## modify it under the terms of the GNU General Public License as +## published by the Free Software Foundation; either version 2 of the +## License, or (at your option) any later version. +## +## Invenio is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Invenio; if not, write to the Free Software Foundation, Inc., +## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. +#} +{%- extends "accounts/login_base.html" -%} \ No newline at end of file diff --git a/invenio/modules/accounts/templates/accounts/login_base.html b/invenio/modules/accounts/templates/accounts/login_base.html index 3dac9cb82..e67ef26a3 100644 --- a/invenio/modules/accounts/templates/accounts/login_base.html +++ b/invenio/modules/accounts/templates/accounts/login_base.html @@ -1,255 +1,277 @@ {# ## This file is part of Invenio. ## Copyright (C) 2012 CERN. ## ## Invenio is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License as ## published by the Free Software Foundation; either version 2 of the ## License, or (at your option) any later version. ## ## Invenio is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with Invenio; if not, write to the Free Software Foundation, Inc., ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. #} -{% from "_formhelpers.html" import render_field with context %} -{% extends "page.html" %} -{% set title = None %} -{% set activated_providers = config.CFG_OPENID_PROVIDERS * config.CFG_OPENID_AUTHENTICATION +{%- from "_formhelpers.html" import render_field with context %} +{%- extends "page.html" %} +{%- set title = None %} +{%- set activated_providers = config.CFG_OPENID_PROVIDERS * config.CFG_OPENID_AUTHENTICATION + config.CFG_OAUTH1_PROVIDERS * config.CFG_OAUTH1_AUTHENTICATION + config.CFG_OAUTH2_PROVIDERS * config.CFG_OAUTH2_AUTHENTICATION %} {%- css url_for('webaccount.static', filename='css/accounts/login.css'), '10-login' -%} -{% block body %} - -<div class="row"> -{% if config.CFG_EXTERNAL_AUTH_USING_SSO %} - <div class="col-md-8 col-md-offset-2"> - <p class="lead text-center"> - {{ _("You can login using %(x_url_open)sSingle-Sign-On%(x_url_close)s")|format( - x_url_open='<a href="'+url_for('sso_login', _external=True, _scheme='https', referer=request.values.get('referer'))+'">', - x_url_close='</a>')|safe }} - </p> - <hr/> - </div> -{% endif %} - - <div class="col-md-8 col-md-offset-2"> - <p class="lead text-center">{{ _("If you already have an account, please login using the form below.") }}</p> - <p class="text-center">{{ _("If you don't own an account yet, please %(x_url_open)sregister")|format( - x_url_open='<a href="'+url_for('webaccount.register')+'">')|safe }} - {{ _("%(x_url_close)s an internal account.")|format(x_url_close='</a>')|safe }}</p> - - <hr/> - </div> -</div> - -<div class="row"> - <div class="col-md-4 col-md-offset-{{ '2' if activated_providers else '4' }}"> - <legend>{{ _('Please Sign In') }}</legend> - <form class="form-signin" action="{{ url_for('webaccount.login') }}" method="POST"> - <div class="form-group"> - {{ form.referer }} - {{ form.login_method }} - {{ form.nickname(placeholder=_('Username or email'), class_="form-control", type="text") }} - {{ form.password(placeholder=_('Password'), class_="form-control", type="password") }} - </div> - <label class="checkbox"> - {{ form.remember(class_="checkbox") }} {{ form.remember.label.text }} - </label> - {{ form.submit(class_="btn btn-info btn-block") }} - </form> - <p class="text-right"> - <a href="{{ url_for('webaccount.lost') }}"> - {{ _('Lost your password?') }} - </a> - </p> - </div> - -{% macro external_login_button(provider, referer='', icon_size=48, +{%- macro external_login_button(provider, referer='', icon_size=48, classes="", label="%(provider)s username") %} +{%- block external_login_button scoped -%} {% if provider in config.CFG_OPENID_PROVIDERS %} {% set type = 'openid' %} {% elif provider in config.CFG_OAUTH2_PROVIDERS %} {% set type = 'oauth2' %} {% elif provider in config.CFG_OAUTH1_PROVIDERS %} {% set type = 'oauth1' %} {% else %} {% set type = 'login' %} {% endif %} {% set handler = url_for('youraccount.' + type, provider=provider) %} {% if referer %} {% if not url_for('webaccount.login') in referer %} {% set handler = url_for('youraccount.' + type, provider=provider, referer=referer) %} {% endif %} {% endif %} <li class="{{ classes }}" id="{{ provider }}_login_button"> <a class="thumbnail" id="{{ provider }}_login" rel="tooltip" title="{{ provider }}" data-placement="top" href="{{ handler|safe }}"> <img class="external_provider {{ classes }}" src="{{ url_for('static', filename="/img/%s_icon_%s.png"|format(provider, icon_size)) }}" /> </a> </li> - +{%- endblock external_login_button -%} {% endmacro %} {% macro external_login_form(provider, referer='', icon_size=48, classes="", label="%(provider)s username") %} {# Template of the login form for providers which need an username for verification. @param provider: The name of the provider @type provider: str @param referer: The referer URL - will be redirected upon after login @type referer: str @param icon_size: The size of the icon of the provider @type icon_size: int @param classes: Additional classes for the login form @type classes: str @param label: The label for text input. @param label: str @rtype: str #} + {%- block external_login_form scoped -%} {% if provider in config.CFG_OPENID_PROVIDERS %} {% set type = 'openid' %} {% elif provider in config.CFG_OAUTH2_PROVIDERS %} {% set type = 'oauth2' %} {% elif provider in config.CFG_OAUTH1_PROVIDERS %} {% set type = 'oauth1' %} {% else %} {% set type = 'login' %} {% endif %} <li class="{{ classes }} login_form" id="{{ provider }}_verify_form"> <a class="thumbnail" id="{{ provider }}_login_img" rel="tooltip" title="{{ provider }}" data-placement="top" onclick="show_username_form('#{{ provider }}_verifier')" href="#{{ provider }}_verify_form"> <img class="external_provider {{ classes }}" src="{{ url_for('static', filename="/img/%s_icon_%s.png"|format(provider, icon_size)) }}" /> </a> <div class="login_content with_label" id="{{ provider }}_verifier" hidden="hidden"> <form method="get" accept-charset="UTF-8" action="{{ url_for('youraccount.' + type)|safe }}"> <input type="hidden" name="provider" value="{{ provider }}"> <input type="hidden" name="referer" value="{{ referer }}"> <input class="input-block-level" id="{{ provider }}_username_field" style="background: url({{ url_for('static', filename="/img/%s_icon_%s.png"|format(provider, 24)) }}); background-repeat: no-repeat; background-position: 2px center; padding-left: 30px; height: 30px; box-sizing: border-box;" type="text" name="identifier" value="" placeholder="{{ label|format(provider=provider) }}"> <button class="btn btn-info btn-block" type="submit"> {{ _('Continue') }} <i class="glyphicon glyphicon-chevron-right"></i> </button> </form> </div> </li> + {%- endblock external_login_form -%} {% endmacro %} {% macro construct_button(provider, size, button_class) %} +{%- block construct_button scoped -%} {% set c = config.CFG_OPENID_CONFIGURATIONS.get(provider, {}) %} {% set identifier = c.get('identifier', '') %} {% if "{0}" in identifier %} {% set label = config.CFG_EXTERNAL_LOGIN_FORM_LABELS.get(provider, "%(provider)s username") %} {{ external_login_form(provider, form.referer.data, size, button_class, _(label)) }} {% else %} {{ external_login_button(provider, form.referer.data, size, button_class) }} {% endif %} - +{%- endblock construct_button -%} {% endmacro %} -{% if activated_providers %} -<style> -.auth_providers.thumbnails { - margin-left: 0px; -} +{% block body %} +{%- block form_header scoped -%} +<div class="row"> +{% if config.CFG_EXTERNAL_AUTH_USING_SSO %}{% block form_header_sso scoped %} + <div class="col-md-8 col-md-offset-2"> + <p class="lead text-center"> + {{ _("You can login using %(x_url_open)sSingle-Sign-On%(x_url_close)s")|format( + x_url_open='<a href="'+url_for('sso_login', _external=True, _scheme='https', referer=request.values.get('referer'))+'">', + x_url_close='</a>')|safe }} + </p> + <hr/> + </div> +{% endblock form_header_sso %}{% endif %} + + {%- block form_header_message scoped -%} + <div class="col-md-8 col-md-offset-2"> + <p class="lead text-center">{{ _("If you already have an account, please login using the form below.") }}</p> + <p class="text-center">{{ _("If you don't own an account yet, please %(x_url_open)sregister")|format( + x_url_open='<a href="'+url_for('webaccount.register')+'">')|safe }} + {{ _("%(x_url_close)s an internal account.")|format(x_url_close='</a>')|safe }}</p> + + <hr/> + </div> + {%- endblock form_header_message -%} +</div> +{%- endblock form_header -%} +{%- block form_body scoped -%} +<div class="row"> + {%- block form_auth_internal scoped -%} + <div class="col-md-4 col-md-offset-{{ '2' if activated_providers else '4' }}"> + {%- block form_auth_internal_form scoped -%} + <legend>{{ _('Please Sign In') }}</legend> + <form class="form-signin" action="{{ url_for('webaccount.login') }}" method="POST"> + {{ form.referer }} + {{ form.login_method }} + <div class="form-group{% if form.nickname.errors%} has-error{% endif %}"> + {{ form.nickname(placeholder=_('Username or email'), class_="form-control", type="text") }} + {%- if form.nickname.errors %}{% for error in form.nickname.errors %} + <span class="help-block">{{ error }}</span> + {%- endfor %}{% endif %} + </div> + <div class="form-group{% if form.password.errors%} has-error{% endif %}"> + {{ form.password(placeholder=_('Password'), class_="form-control", type="password") }} + {%- if form.password.errors %}{% for error in form.password.errors %} + <span class="help-block">{{ error }}</span> + {%- endfor %}{% endif %} + + <label class="checkbox"> + {{ form.remember(class_="checkbox") }} {{ form.remember.label.text }} + </label> + {{ form.submit(class_="btn btn-info btn-block") }} + </form> + <p class="text-center"><small> + <a href="{{ url_for('webaccount.lost') }}"> + {{ _('Lost your password?') }} + </a> + </small></p> + {%- endblock form_auth_internal_form -%} + </div> + {%- endblock form_auth_internal -%} + {%- block form_auth_external scoped -%} + {%- if activated_providers %} + <style> + .auth_providers.thumbnails { + margin-left: 0px; + } -.auth_providers.thumbnails>li { - margin: 0px; - margin-right: 1px; - float: left!important; -} + .auth_providers.thumbnails>li { + margin: 0px; + margin-right: 1px; + float: left!important; + } -.auth_providers .thumbnail { - padding: 0px; - border: none; -} -</style> + .auth_providers .thumbnail { + padding: 0px; + border: none; + } + </style> <div class="col-md-1 hidden-xs" style="height: 200px; padding: 0px; display: block; float: left; width: 1px; border-right: 1px solid #ccc;"> </div> <div class="col-md-4"> <legend style="font-size: 90%;">{{ _('or Select Your Authentication Provider:') }}</legend> <ul class="auth_providers thumbnails"> {% for provider in config.CFG_EXTERNAL_LOGIN_LARGE %} {% if provider in activated_providers %} {{ construct_button(provider, 48, "large") }} {% endif %} {% endfor %} {% set providers = config.CFG_EXTERNAL_LOGIN_BUTTON_ORDER %} {% if (activated_providers|length - CFG_EXTERNAL_LOGIN_LARGE|length) != providers|length %} {# Not all the providers ordered. Add the unsorted ones to the end. #} {% for provider in activated_providers|sort %} {% if not provider in providers %} {% do providers.append(provider) %} {% endif %} {% endfor %} {% endif %} {% for provider in providers %} {% if not provider in config.CFG_EXTERNAL_LOGIN_LARGE %} {{ construct_button(provider, 24, "") }} {% endif %} {% endfor %} </ul> - - <div id="form_field"> - -{% endif %} + </div> + <div id="#form_field"></div> + {% endif %} + {%- endblock form_auth_external -%} </div> +{%- endblock form_body -%} +{%- block form_footer scoped -%}{%- endblock form_footer -%} {% endblock %} {% block javascript %} {{ super() }} <script type="text/javascript"> - function show_username_form(element) { $('#form_field').html($(element).html()) return false } (function($) { $('[rel=tooltip]').tooltip(); $('#nickname').popover({ title: '<strong>{{ _('Note') }}</strong>', content: '{{ _('You can use your nickname or your email address to login.') }}', trigger: 'focus', html: true, + container: 'body', + placement: '{% block nickname_popover_placement %}right{% endblock%}' + }); })(jQuery); - </script> {% endblock %} diff --git a/invenio/modules/accounts/templates/accounts/logout.html b/invenio/modules/accounts/templates/accounts/logout.html new file mode 100644 index 000000000..3d2630ee9 --- /dev/null +++ b/invenio/modules/accounts/templates/accounts/logout.html @@ -0,0 +1,19 @@ +{# +## This file is part of Invenio. +## Copyright (C) 2014 CERN. +## +## Invenio is free software; you can redistribute it and/or +## modify it under the terms of the GNU General Public License as +## published by the Free Software Foundation; either version 2 of the +## License, or (at your option) any later version. +## +## Invenio is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Invenio; if not, write to the Free Software Foundation, Inc., +## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. +#} +{%- extends "accounts/logout_base.html" -%} \ No newline at end of file diff --git a/invenio/modules/accounts/templates/accounts/logout_base.html b/invenio/modules/accounts/templates/accounts/logout_base.html index e8aa17caa..d23c99f52 100644 --- a/invenio/modules/accounts/templates/accounts/logout_base.html +++ b/invenio/modules/accounts/templates/accounts/logout_base.html @@ -1,36 +1,38 @@ {# ## This file is part of Invenio. ## Copyright (C) 2012 CERN. ## ## Invenio is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License as ## published by the Free Software Foundation; either version 2 of the ## License, or (at your option) any later version. ## ## Invenio is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with Invenio; if not, write to the Free Software Foundation, Inc., ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. #} {% extends "page.html" %} {% set title = _("Logout") %} {% block body %} -{{ _("You are no longer recognized by our system.") }} +<p>{{ _("You have now been signed out.") }}</p> {% if using_sso and logout_sso: %} +<p> {{ (_("""You are still recognized by the centralized %(x_fmt_open)sSSO%(x_fmt_close)s system. You can %(x_url_open)slogout from SSO%(x_url_close)s, too.""") % {'x_fmt_open' : '<strong>', 'x_fmt_close' : '</strong>', 'x_url_open' : '<a href="%s">' % (logout_sso, ), 'x_url_close' : '</a>'})|safe }} <br /> +</p> {% endif %} -{{ (_("If you wish you can %(x_url_open)slogin here%(x_url_close)s.") % +{{ (_("If you wish you can %(x_url_open)ssign in again%(x_url_close)s.") % {'x_url_open': '<a href="%s">' % (url_for('.login'),), 'x_url_close': '</a>'})|safe}} {% endblock %} diff --git a/invenio/modules/accounts/templates/accounts/lost.html b/invenio/modules/accounts/templates/accounts/lost.html new file mode 100644 index 000000000..bf5d6c244 --- /dev/null +++ b/invenio/modules/accounts/templates/accounts/lost.html @@ -0,0 +1,19 @@ +{# +## This file is part of Invenio. +## Copyright (C) 2014 CERN. +## +## Invenio is free software; you can redistribute it and/or +## modify it under the terms of the GNU General Public License as +## published by the Free Software Foundation; either version 2 of the +## License, or (at your option) any later version. +## +## Invenio is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Invenio; if not, write to the Free Software Foundation, Inc., +## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. +#} +{%- extends "accounts/lost_base.html" -%} \ No newline at end of file diff --git a/invenio/modules/accounts/templates/accounts/register.html b/invenio/modules/accounts/templates/accounts/register.html new file mode 100644 index 000000000..9ab6238de --- /dev/null +++ b/invenio/modules/accounts/templates/accounts/register.html @@ -0,0 +1,19 @@ +{# +## This file is part of Invenio. +## Copyright (C) 2014 CERN. +## +## Invenio is free software; you can redistribute it and/or +## modify it under the terms of the GNU General Public License as +## published by the Free Software Foundation; either version 2 of the +## License, or (at your option) any later version. +## +## Invenio is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Invenio; if not, write to the Free Software Foundation, Inc., +## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. +#} +{%- extends "accounts/register_base.html" -%} \ No newline at end of file diff --git a/invenio/modules/accounts/templates/accounts/register_base.html b/invenio/modules/accounts/templates/accounts/register_base.html index 89a3b2af0..0feaab08e 100644 --- a/invenio/modules/accounts/templates/accounts/register_base.html +++ b/invenio/modules/accounts/templates/accounts/register_base.html @@ -1,59 +1,71 @@ {# ## This file is part of Invenio. ## Copyright (C) 2012, 2013 CERN. ## ## Invenio is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License as ## published by the Free Software Foundation; either version 2 of the ## License, or (at your option) any later version. ## ## Invenio is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with Invenio; if not, write to the Free Software Foundation, Inc., ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. #} {% from "_formhelpers.html" import render_field with context %} {% extends "page.html" %} {% block title %}{% endblock %} {% block body %} <div class="container"> <div class="row"> <div class="col-md-offset-3 col-md-6 well"> - <form class="form-horizontal" method="POST" action="{{ url_for('.register',) }}"> + {%- block form scoped -%} + <form class="form-horizontal" role="form" method="POST" action="{{ url_for('.register',) }}"> {%- if state == 'success' %} + {%- block form_success scoped -%} <legend>{{title}}<span class="pull-right"><i class="glyphicon glyphicon-ok"></i></span></legend> {%- for m in messages %} <p>{{m}}</p> {%- endfor %} + {%- endblock form_success -%} {%- else %} + {%- block form_inner scoped -%} <fieldset> + {%- block form_title scoped -%} <legend>{{title}}<span class="pull-right"> {%- if state -%} <i class="glyphicon glyphicon-warning-sign"></i> {%- else -%} <i class="glyphicon glyphicon-edit"></i> {%- endif -%} </span></legend> + {%- endblock form_title -%} + {%- block form_message scoped -%} {% if messages and state != 'success' %} <div class="alert alert-{{state}}"> {%- for m in messages %} <p>{{m}}</p> {%- endfor %} </div> {% endif %} + {%- endblock form_message -%} + {%- block form_fields scoped -%} {% for field in form if field.name != 'submit' %} - {{render_field(field, show_description=True, label_size=3, field_size=9)}} + {%- block form_field scoped -%}{{render_field(field, show_description=True, label_size=4, field_size=5)}}{%- endblock form_field -%} {% endfor %} + {%- endblock form_fields -%} </fieldset> - {{form.submit(value="Sign up", class="btn btn-warning btn-large pull-right")}} + {{form.submit(value="Sign up", class="btn btn-warning btn-lg pull-right")}} + {%- endblock form_inner -%} {% endif %} </form> + {%- endblock form -%} </div> </div> </div> {% endblock %} diff --git a/invenio/modules/accounts/templates/accounts/widget.html b/invenio/modules/accounts/templates/accounts/widget.html new file mode 100644 index 000000000..e0db12ea8 --- /dev/null +++ b/invenio/modules/accounts/templates/accounts/widget.html @@ -0,0 +1,19 @@ +{# +## This file is part of Invenio. +## Copyright (C) 2014 CERN. +## +## Invenio is free software; you can redistribute it and/or +## modify it under the terms of the GNU General Public License as +## published by the Free Software Foundation; either version 2 of the +## License, or (at your option) any later version. +## +## Invenio is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Invenio; if not, write to the Free Software Foundation, Inc., +## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. +#} +{%- extends "accounts/widget_base.html" -%} \ No newline at end of file diff --git a/invenio/modules/accounts/views.py b/invenio/modules/accounts/views.py index b6dfa969e..2bc70194d 100644 --- a/invenio/modules/accounts/views.py +++ b/invenio/modules/accounts/views.py @@ -1,317 +1,329 @@ # -*- coding: utf-8 -*- ## ## This file is part of Invenio. ## Copyright (C) 2012, 2013 CERN. ## ## Invenio is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License as ## published by the Free Software Foundation; either version 2 of the ## License, or (at your option) any later version. ## ## Invenio is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ## General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with Invenio; if not, write to the Free Software Foundation, Inc., ## 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. """WebAccount Flask Blueprint""" from werkzeug import CombinedMultiDict, ImmutableMultiDict from flask import render_template, request, flash, redirect, url_for, \ g, abort, current_app, Blueprint from flask.ext.login import current_user, login_required #from invenio import websession_config from invenio.legacy import webuser from .forms import LoginForm, RegisterForm, LostPasswordForm from .models import User from .validators import wash_login_method from invenio.base.decorators import wash_arguments from invenio.base.globals import cfg from invenio.base.i18n import _ from flask.ext.breadcrumbs import register_breadcrumb from invenio.ext.login import login_user, logout_user, authenticate, \ reset_password, login_redirect from flask.ext.menu import register_menu from invenio.ext.sqlalchemy import db from invenio.ext.sslify import ssl_required from invenio.modules.access.mailcookie import mail_cookie_check_mail_activation from invenio.utils.datastructures import LazyDict, flatten_multidict from invenio.utils.url import rewrite_to_secure_url #CFG_HAS_HTTPS_SUPPORT = CFG_SITE_SECURE_URL.startswith("https://") #CFG_FULL_HTTPS = CFG_SITE_URL.lower().startswith("https://") blueprint = Blueprint('webaccount', __name__, url_prefix="/youraccount", template_folder='templates', static_folder='static') @blueprint.route('/login', methods=['GET', 'POST']) @wash_arguments({'nickname': (unicode, None), 'password': (unicode, None), 'login_method': (wash_login_method, 'Local'), 'action': (unicode, ''), 'remember_me': (bool, False), 'referer': (unicode, None)}) @register_breadcrumb(blueprint, '.login', _('Login')) @ssl_required def login(nickname=None, password=None, login_method=None, action='', remember_me=False, referer=None): if cfg.get('CFG_ACCESS_CONTROL_LEVEL_SITE') > 0: return abort(401) # page is not authorized if action: from invenio.modules.access.mailcookie import \ InvenioWebAccessMailCookieError, \ mail_cookie_check_authorize_action try: action, arguments = mail_cookie_check_authorize_action(action) except InvenioWebAccessMailCookieError: pass form = LoginForm(CombinedMultiDict( [ImmutableMultiDict({'referer': referer, 'login_method': 'Local'} if referer else {'login_method': 'Local'}), - request.values]), csrf_enabled=False) - try: - if login_method == 'Local' and \ - authenticate(nickname, password, login_method=login_method): + request.values]), csrf_enabled=False) - flash(_("You are logged in as %(nick)s.", nick=nickname), "info") - return login_redirect(referer) - except Exception as e: - current_app.logger.error('Exception during login process: %s', str(e)) - flash(_("Problem with login."), "error") + if request.method == "POST": + try: + if login_method == 'Local' and form.validate_on_submit() and \ + authenticate(nickname, password, login_method=login_method): + flash( + _("You are logged in as %(nick)s.", nick=nickname), + "success" + ) + return login_redirect(referer) + else: + flash(_("Invalid credentials."), "error") + except Exception as e: + current_app.logger.error( + 'Exception during login process: %s', str(e) + ) + flash(_("Problem with login."), "error") return render_template('accounts/login.html', form=form) @blueprint.route('/register', methods=['GET', 'POST']) @register_breadcrumb(blueprint, '.register', _('Register')) @ssl_required def register(): req = request.get_legacy_request() # FIXME if cfg.get('CFG_ACCESS_CONTROL_LEVEL_SITE') > 0: return webuser.page_not_authorized(req, "../youraccount/register?ln=%s" % g.ln, navmenuid='youraccount') form = RegisterForm(request.values, csrf_enabled=False) #uid = current_user.get_id() title = _("Register") messages = [] state = "" if form.validate_on_submit(): ruid = webuser.registerUser(req, form.email.data.encode('utf8'), form.password.data.encode('utf8'), form.nickname.data.encode('utf8'), ln=g.ln) if ruid == 0: title = _("Account created") messages.append(_("Your account has been successfully created.")) state = "success" if cfg.get('CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_NEW_ACCOUNT') == 1: messages.append(_("In order to confirm its validity, an email message containing an account activation key has been sent to the given email address.")) messages.append(_("Please follow instructions presented there in order to complete the account registration process.")) if cfg.get('CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS') >= 1: messages.append(_("A second email will be sent when the account has been activated and can be used.")) elif cfg.get('CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_NEW_ACCOUNT') != 1: user = User.query.filter(User.email == form.email.data.lower()).one() login_user(user.get_id()) messages.append(_("You can now access your account.")) else: title = _("Registration failure") state = "danger" if ruid == 5: messages.append(_("Users cannot register themselves, only admin can register them.")) elif ruid == 6 or ruid == 1: # Note, code 1 is used both for invalid email, and email sending # problems, however the email address is validated by the form, # so we only have to report a problem sending the email here messages.append(_("The site is having troubles in sending you an email for confirming your email address.")) messages.append(_("The error has been logged and will be taken in consideration as soon as possible.")) else: # Errors [-2, (1), 2, 3, 4] taken care of by form validation messages.append(_("Internal error %(ruid)s", ruid=ruid)) elif request.method == 'POST': title = _("Registration failure") state = "warning" return render_template('accounts/register.html', form=form, title=title, messages=messages, state=state) @blueprint.route('/logout', methods=['GET', 'POST']) @register_breadcrumb(blueprint, '.logout', _('Logout')) @login_required def logout(): logout_user() from invenio.modules.access.local_config import \ CFG_EXTERNAL_AUTH_USING_SSO, \ CFG_EXTERNAL_AUTH_LOGOUT_SSO if CFG_EXTERNAL_AUTH_USING_SSO: return redirect(CFG_EXTERNAL_AUTH_LOGOUT_SSO) return render_template('accounts/logout.html', using_sso=CFG_EXTERNAL_AUTH_USING_SSO, logout_sso=CFG_EXTERNAL_AUTH_LOGOUT_SSO) def load_user_settings(): """ Handy function to populate LazyDic with user settings. """ from invenio.modules.dashboard.settings import Settings from invenio.base.utils import autodiscover_user_settings modules = autodiscover_user_settings() user_settings = {} for module in modules: candidates = getattr(module, 'settings') if candidates is not None: if type(candidates) is not list: candidates = [candidates] for candidate in candidates: if issubclass(candidate, Settings): if candidate.__name__ in user_settings: raise Exception(candidate.__name__, 'duplicate user settings') user_settings[candidate.__name__] = candidate return user_settings _USER_SETTINGS = LazyDict(load_user_settings) @blueprint.route('/', methods=['GET', 'POST']) @blueprint.route('/display', methods=['GET', 'POST']) @login_required @register_menu(blueprint, 'personalize', _('Personalize')) @register_breadcrumb(blueprint, '.', _('Your account')) def index(): # load plugins plugins = filter(lambda x: x.is_authorized and x.widget, map(lambda x: x(), _USER_SETTINGS.values())) closed_plugins = [] plugin_sort = (lambda w, x: x.index(w.name) if w.name in x else len(x)) dashboard_settings = current_user.get('dashboard_settings', {}) if current_user.is_super_admin: # Check for a new release of Invenio from invenio.ext.script import check_for_software_updates check_for_software_updates(flash_message=True) if dashboard_settings: order_left = dashboard_settings.get('orderLeft', []) or [] order_middle = dashboard_settings.get('orderMiddle', []) or [] order_right = dashboard_settings.get('orderRight', []) or [] extract_plugins = lambda x: [p for p in plugins if p.name in x if p] plugins_left = sorted(extract_plugins(order_left), key=lambda w: plugin_sort(w, order_left)) plugins_middle = sorted(extract_plugins(order_middle), key=lambda w: plugin_sort(w, order_middle)) plugins_right = sorted(extract_plugins(order_right), key=lambda w: plugin_sort(w, order_right)) closed_plugins = [p for p in plugins if not p in plugins_left and not p in plugins_middle and not p in plugins_right] plugins = [plugins_left, plugins_middle, plugins_right] else: plugins = sorted(plugins, key=lambda w: plugin_sort(w, plugins)) plugins = [plugins[i:i+3] for i in range(0, len(plugins), 3)] return render_template('accounts/index.html', plugins=plugins, closed_plugins=closed_plugins) @blueprint.route('/edit/<name>', methods=['GET', 'POST']) @register_breadcrumb(blueprint, '.edit', _('Edit')) @login_required def edit(name): if name not in _USER_SETTINGS: flash(_('Invalid plugin name'), 'error') return redirect(url_for('.index')) plugin = _USER_SETTINGS[name]() form = None if request.method == 'POST': if plugin.form_builder: form = plugin.form_builder(request.form) if not form or form.validate(): if form: # use the form to interpret data settings_data = form.data else: # no form provided, save the POST request values settings_data = flatten_multidict(request.values) plugin.store(settings_data) plugin.save() flash(_('Data has been saved.'), 'success') return redirect(url_for('.index')) flash(_('Please, corrent errors.'), 'error') # get post data or load data from settings if not form and plugin.form_builder: form = plugin.build_form() return render_template(getattr(plugin, 'edit_template', '') or 'accounts/edit.html', plugin=plugin, form=form) @blueprint.route('/view', methods=['GET']) @login_required @wash_arguments({'name': (unicode, "")}) def view(name): if name not in _USER_SETTINGS: return "1", 406 widget = _USER_SETTINGS[name]() if widget.is_authorized and widget.widget: return render_template('accounts/widget.html', widget=widget) else: return "2", 406 @blueprint.route('/lost', methods=['GET', 'POST']) @register_breadcrumb(blueprint, '.edit', _('Edit')) @ssl_required def lost(): form = LostPasswordForm(request.values) if form.validate_on_submit(): if reset_password(request.values['email'], g.ln): flash(_('A password reset link has been sent to %(whom)s', whom=request.values['email']), 'success') else: pass logout_user() # makes no sense to have the user logged-in here return render_template('accounts/lost.html', form=form) @blueprint.route('/access', methods=['GET', 'POST']) @ssl_required def access(): try: mail = mail_cookie_check_mail_activation(request.values['mailcookie']) User.query.filter(User.email == mail).one().note = 1 try: db.session.commit() except: db.session.rollback() flash(_('Authorization failled.'), 'error') - flash(_('Your email has been validated.'), 'success') + flash( + _('Your email address has been validated, and you can now proceed ' + 'to sign-in.'), + 'success' + ) except: flash(_('The authorization token is invalid.'), 'error') return redirect('/')