From ac0bc6a1e1930e1fb898ce664e6ea8eb5efadbc7 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Wed, 3 Jul 2013 08:09:48 -0500 Subject: fixing the config section we pull things out of for basic_auth --- mediagoblin/plugins/basic_auth/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'mediagoblin/plugins') diff --git a/mediagoblin/plugins/basic_auth/__init__.py b/mediagoblin/plugins/basic_auth/__init__.py index a2efae92..0d3c6886 100644 --- a/mediagoblin/plugins/basic_auth/__init__.py +++ b/mediagoblin/plugins/basic_auth/__init__.py @@ -21,7 +21,7 @@ from sqlalchemy import or_ def setup_plugin(): - config = pluginapi.get_config('mediagoblin.pluginapi.basic_auth') + config = pluginapi.get_config('mediagoblin.plugins.basic_auth') def get_user(**kwargs): -- cgit v1.2.3 From 5adb906a0a4da32f22d4ebd868bfa92929c22011 Mon Sep 17 00:00:00 2001 From: Rodney Ewing Date: Wed, 26 Jun 2013 11:20:50 -0700 Subject: merge --squash openid branch to take care of a false merge commit in the basic_auth branch that openid is forked from Commits squashed together (in reverse chronological order): - do the label thing only for boolean fields - made edit_account to autofocus on the first field - added feature to render_divs where if field.label == '' then it will render form.description the same a render_label - added allow_registration check - refactored create_user - removed verification_key from create_user - removed get_user from openid - cleanup after removing openid from template_env.globals - fix for werkzueg 0.9.1 - cleanup after merge - more tests - restored openid extra_validation just for safety - tests for openid - deleted openid extra_validation - passed next parameter in session for openid - fixed a bug that was deleting the messages - implemented openid store using sqlalchemy - ask openid provider for 'nickname' to prefill username in registration form - refactored delete openid url to work with generic urls such as google and to not allow a user to delete a url if it is there only one and they don't have a pw - refactored login to register user workflow, which fixed a problem where the 'or register with a password link' wasn't showing up when the finish_login view called the register view because there wasn't any redirect. - added the ability to remove openid's - added the ability to add openids to an existing account - refactored start_login and finish_login views - modified edit_account.html to use render_divs - modified gmg/edit/views to behave appropriatly if no password authentication is enabled. moved the update email stuff to it's own funtion to make edit_account view cleaner. edit_account now modifies the form depending on the plugins. - minor typos - added retrieving email from openid provider - moved allow_registration check to a decorator - moved check if auth is enabled to a decorator - changed openid user registration to go through login first - cleanup after merge - modified verification emails to use itsdangerous tokens - added error handling on bad token, fixed route, and added tests - added support for user to change email address - added link to login view openid/password in login template - updated openid get_user function - modified get_user function to take kwargs instead of username - no need for user might be email kwarg in check_login_simple - added gen_password_hash and check_password functions to auth/__init__ - added focus to form input - made imports fully qualified - modified basic_auth.check_login to check that the user has a pw_hash first - changed occurances of form.data['whatever'] to form.whatever.data - convert tabs to spaces in register template, remove unsed templates, and fixed trans tags in templates - in process of openid login. it works, but needs major imporvements - make password field required in basic_auth form - check if password field present in basic_auth create_user - modified openid create_user function - modified models based on Elronds suggestions - changed register form action to a variable to be passed in by the view using the template - openid plugin v0, still need to authenticate via openid. - added a register_user function to be able to use in a plugin's register view, and modified auth/views.register to redirect to openid/register if appropriate. - Modified basic_auth plugin to work with modified auth plugin hooks. Added context variables. Removed basic_auth/tools which was previously renamed to basic_auth/lib. - modified auth/__init__ hooks to work better with multiple plugins. Removed auth/lib.py. And added a basic_extra_verification function that all plugins will use. - added models and migrations for openid plugin --- mediagoblin/plugins/basic_auth/__init__.py | 11 +- mediagoblin/plugins/openid/__init__.py | 122 +++++++ mediagoblin/plugins/openid/forms.py | 41 +++ mediagoblin/plugins/openid/lib.py | 28 ++ mediagoblin/plugins/openid/models.py | 65 ++++ mediagoblin/plugins/openid/store.py | 128 +++++++ .../templates/mediagoblin/plugins/openid/add.html | 44 +++ .../mediagoblin/plugins/openid/delete.html | 43 +++ .../mediagoblin/plugins/openid/login.html | 65 ++++ .../mediagoblin/plugins/openid/request_form.html | 24 ++ mediagoblin/plugins/openid/views.py | 405 +++++++++++++++++++++ 11 files changed, 970 insertions(+), 6 deletions(-) create mode 100644 mediagoblin/plugins/openid/__init__.py create mode 100644 mediagoblin/plugins/openid/forms.py create mode 100644 mediagoblin/plugins/openid/lib.py create mode 100644 mediagoblin/plugins/openid/models.py create mode 100644 mediagoblin/plugins/openid/store.py create mode 100644 mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/add.html create mode 100644 mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/delete.html create mode 100644 mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/login.html create mode 100644 mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/request_form.html create mode 100644 mediagoblin/plugins/openid/views.py (limited to 'mediagoblin/plugins') diff --git a/mediagoblin/plugins/basic_auth/__init__.py b/mediagoblin/plugins/basic_auth/__init__.py index 0d3c6886..2e7e8f8c 100644 --- a/mediagoblin/plugins/basic_auth/__init__.py +++ b/mediagoblin/plugins/basic_auth/__init__.py @@ -15,6 +15,7 @@ # along with this program. If not, see . from mediagoblin.plugins.basic_auth import forms as auth_forms from mediagoblin.plugins.basic_auth import tools as auth_tools +from mediagoblin.auth.tools import create_basic_user from mediagoblin.db.models import User from mediagoblin.tools import pluginapi from sqlalchemy import or_ @@ -38,9 +39,7 @@ def get_user(**kwargs): def create_user(registration_form): user = get_user(username=registration_form.username.data) if not user and 'password' in registration_form: - user = User() - user.username = registration_form.username.data - user.email = registration_form.email.data + user = create_basic_user(registration_form) user.pw_hash = gen_password_hash( registration_form.password.data) user.save() @@ -89,7 +88,7 @@ hooks = { 'auth_fake_login_attempt': auth_tools.fake_login_attempt, 'template_global_context': append_to_global_context, ('mediagoblin.plugins.openid.register', - 'mediagoblin/auth/register.html'): add_to_form_context, - ('mediagoblin.plugins.openid.login', - 'mediagoblin/auth/login.html'): add_to_form_context, + 'mediagoblin/auth/register.html'): add_to_form_context, + ('mediagoblin.plugins.openid.finish_login', + 'mediagoblin/auth/register.html'): add_to_form_context, } diff --git a/mediagoblin/plugins/openid/__init__.py b/mediagoblin/plugins/openid/__init__.py new file mode 100644 index 00000000..9803ada6 --- /dev/null +++ b/mediagoblin/plugins/openid/__init__.py @@ -0,0 +1,122 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +import os +import uuid + +from sqlalchemy import or_ + +from mediagoblin.auth.tools import create_basic_user +from mediagoblin.db.models import User +from mediagoblin.plugins.openid.models import OpenIDUserURL +from mediagoblin.tools import pluginapi +from mediagoblin.tools.translate import lazy_pass_to_ugettext as _ + +PLUGIN_DIR = os.path.dirname(__file__) + + +def setup_plugin(): + config = pluginapi.get_config('mediagoblin.plugins.openid') + + routes = [ + ('mediagoblin.plugins.openid.register', + '/auth/openid/register/', + 'mediagoblin.plugins.openid.views:register'), + ('mediagoblin.plugins.openid.login', + '/auth/openid/login/', + 'mediagoblin.plugins.openid.views:login'), + ('mediagoblin.plugins.openid.finish_login', + '/auth/openid/login/finish/', + 'mediagoblin.plugins.openid.views:finish_login'), + ('mediagoblin.plugins.openid.edit', + '/edit/openid/', + 'mediagoblin.plugins.openid.views:start_edit'), + ('mediagoblin.plugins.openid.finish_edit', + '/edit/openid/finish/', + 'mediagoblin.plugins.openid.views:finish_edit'), + ('mediagoblin.plugins.openid.delete', + '/edit/openid/delete/', + 'mediagoblin.plugins.openid.views:delete_openid'), + ('mediagoblin.plugins.openid.finish_delete', + '/edit/openid/delete/finish/', + 'mediagoblin.plugins.openid.views:finish_delete')] + + pluginapi.register_routes(routes) + pluginapi.register_template_path(os.path.join(PLUGIN_DIR, 'templates')) + + +def create_user(register_form): + if 'openid' in register_form: + username = register_form.username.data + user = User.query.filter( + or_( + User.username == username, + User.email == username, + )).first() + + if not user: + user = create_basic_user(register_form) + + new_entry = OpenIDUserURL() + new_entry.openid_url = register_form.openid.data + new_entry.user_id = user.id + new_entry.save() + + return user + + +def extra_validation(register_form): + openid = register_form.openid.data if 'openid' in \ + register_form else None + if openid: + openid_url_exists = OpenIDUserURL.query.filter_by( + openid_url=openid + ).count() + + extra_validation_passes = True + + if openid_url_exists: + register_form.openid.errors.append( + _('Sorry, an account is already registered to that OpenID.')) + extra_validation_passes = False + + return extra_validation_passes + + +def no_pass_redirect(): + return 'openid' + + +def add_to_form_context(context): + context['openid_link'] = True + return context + + +def Auth(): + return True + +hooks = { + 'setup': setup_plugin, + 'authentication': Auth, + 'auth_extra_validation': extra_validation, + 'auth_create_user': create_user, + 'auth_no_pass_redirect': no_pass_redirect, + ('mediagoblin.auth.register', + 'mediagoblin/auth/register.html'): add_to_form_context, + ('mediagoblin.auth.login', + 'mediagoblin/auth/login.html'): add_to_form_context, + ('mediagoblin.edit.account', + 'mediagoblin/edit/edit_account.html'): add_to_form_context, +} diff --git a/mediagoblin/plugins/openid/forms.py b/mediagoblin/plugins/openid/forms.py new file mode 100644 index 00000000..f26024bd --- /dev/null +++ b/mediagoblin/plugins/openid/forms.py @@ -0,0 +1,41 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +import wtforms + +from mediagoblin.tools.translate import lazy_pass_to_ugettext as _ +from mediagoblin.auth.tools import normalize_user_or_email_field + + +class RegistrationForm(wtforms.Form): + openid = wtforms.HiddenField( + '', + [wtforms.validators.Required()]) + username = wtforms.TextField( + _('Username'), + [wtforms.validators.Required(), + normalize_user_or_email_field(allow_email=False)]) + email = wtforms.TextField( + _('Email address'), + [wtforms.validators.Required(), + normalize_user_or_email_field(allow_user=False)]) + + +class LoginForm(wtforms.Form): + openid = wtforms.TextField( + _('OpenID'), + [wtforms.validators.Required(), + # Can openid's only be urls? + wtforms.validators.URL(message='Please enter a valid url.')]) diff --git a/mediagoblin/plugins/openid/lib.py b/mediagoblin/plugins/openid/lib.py new file mode 100644 index 00000000..bbe33d44 --- /dev/null +++ b/mediagoblin/plugins/openid/lib.py @@ -0,0 +1,28 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +import mediagoblin.plugins.openid.forms as auth_forms + + +def get_register_form(request): + # This function will check to see if persona plugin is enabled. If so, + # this function will call hook_transform? and return a modified form + # containing both openid & persona info. + return auth_forms.RegistrationForm(request.form) + + +def get_login_form(request): + # See register_form comment above + return auth_forms.LoginForm(request.form) diff --git a/mediagoblin/plugins/openid/models.py b/mediagoblin/plugins/openid/models.py new file mode 100644 index 00000000..6773f0ad --- /dev/null +++ b/mediagoblin/plugins/openid/models.py @@ -0,0 +1,65 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +from sqlalchemy import Column, Integer, Unicode, ForeignKey +from sqlalchemy.orm import relationship, backref + +from mediagoblin.db.models import User +from mediagoblin.db.base import Base + + +class OpenIDUserURL(Base): + __tablename__ = "openid__user_urls" + + id = Column(Integer, primary_key=True) + openid_url = Column(Unicode, nullable=False) + user_id = Column(Integer, ForeignKey(User.id), nullable=False) + + # OpenID's are owned by their user, so do the full thing. + user = relationship(User, backref=backref('openid_urls', + cascade='all, delete-orphan')) + + +# OpenID Store Models +class Nonce(Base): + __tablename__ = "openid__nonce" + + server_url = Column(Unicode, primary_key=True) + timestamp = Column(Integer, primary_key=True) + salt = Column(Unicode, primary_key=True) + + def __unicode__(self): + return u'Nonce: %r, %r' % (self.server_url, self.salt) + + +class Association(Base): + __tablename__ = "openid__association" + + server_url = Column(Unicode, primary_key=True) + handle = Column(Unicode, primary_key=True) + secret = Column(Unicode) + issued = Column(Integer) + lifetime = Column(Integer) + assoc_type = Column(Unicode) + + def __unicode__(self): + return u'Association: %r, %r' % (self.server_url, self.handle) + + +MODELS = [ + OpenIDUserURL, + Nonce, + Association +] diff --git a/mediagoblin/plugins/openid/store.py b/mediagoblin/plugins/openid/store.py new file mode 100644 index 00000000..b54cf5c8 --- /dev/null +++ b/mediagoblin/plugins/openid/store.py @@ -0,0 +1,128 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +import base64 +import time + +from openid.association import Association as OIDAssociation +from openid.store.interface import OpenIDStore +from openid.store import nonce + +from mediagoblin.plugins.openid.models import Association, Nonce + + +class SQLAlchemyOpenIDStore(OpenIDStore): + def __init__(self): + self.max_nonce_age = 6 * 60 * 60 + + def storeAssociation(self, server_url, association): + assoc = Association.query.filter_by( + server_url=server_url, handle=association.handle + ).first() + + if not assoc: + assoc = Association() + assoc.server_url = unicode(server_url) + assoc.handle = association.handle + + # django uses base64 encoding, python-openid uses a blob field for + # secret + assoc.secret = unicode(base64.encodestring(association.secret)) + assoc.issued = association.issued + assoc.lifetime = association.lifetime + assoc.assoc_type = association.assoc_type + assoc.save() + + def getAssociation(self, server_url, handle=None): + assocs = [] + if handle is not None: + assocs = Association.query.filter_by( + server_url=server_url, handle=handle + ) + else: + assocs = Association.query.filter_by( + server_url=server_url + ) + + if assocs.count() == 0: + return None + else: + associations = [] + for assoc in assocs: + association = OIDAssociation( + assoc.handle, base64.decodestring(assoc.secret), + assoc.issued, assoc.lifetime, assoc.assoc_type + ) + if association.getExpiresIn() == 0: + assoc.delete() + else: + associations.append((association.issued, association)) + + if not associations: + return None + associations.sort() + return associations[-1][1] + + def removeAssociation(self, server_url, handle): + assocs = Association.query.filter_by( + server_url=server_url, handle=handle + ).first() + + assoc_exists = True if assocs else False + for assoc in assocs: + assoc.delete() + return assoc_exists + + def useNonce(self, server_url, timestamp, salt): + if abs(timestamp - time.time()) > nonce.SKEW: + return False + + ononce = Nonce.query.filter_by( + server_url=server_url, + timestamp=timestamp, + salt=salt + ).first() + + if ononce: + return False + else: + ononce = Nonce() + ononce.server_url = server_url + ononce.timestamp = timestamp + ononce.salt = salt + ononce.save() + return True + + # Need to test these cleanups, not sure if the expired Association query + # will work + def cleanupNonces(self, _now=None): + if _now is None: + _now = int(time.time()) + expired = Nonce.query.filter( + Nonce.timestamp < (_now - nonce.SKEW) + ) + count = expired.count() + for each in expired: + each.delete() + return count + + def cleanupAssociations(self): + now = int(time.time()) + expired = Association.query.filter( + 'issued + lifetime' < now) + count = expired.count() + for each in expired: + each.delete() + return count diff --git a/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/add.html b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/add.html new file mode 100644 index 00000000..8d308c81 --- /dev/null +++ b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/add.html @@ -0,0 +1,44 @@ +{# +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +#} +{% extends "mediagoblin/base.html" %} + +{% import "/mediagoblin/utils/wtforms.html" as wtforms_util %} + +{% block title -%} + {% trans %}Add an OpenID{% endtrans %} — {{ super() }} +{%- endblock %} + +{% block mediagoblin_content %} +
+ {{ csrf_token }} +
+

{% trans %}Add an OpenID{% endtrans %}

+

+ + {% trans %}Delete an OpenID{% endtrans %} + +

+ {{ wtforms_util.render_divs(form, True) }} +
+ +
+
+
+{% endblock %} + diff --git a/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/delete.html b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/delete.html new file mode 100644 index 00000000..84301b9e --- /dev/null +++ b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/delete.html @@ -0,0 +1,43 @@ +{# +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +#} +{% extends "mediagoblin/base.html" %} + +{% import "/mediagoblin/utils/wtforms.html" as wtforms_util %} + +{% block title -%} + {% trans %}Delete an OpenID{% endtrans %} — {{ super() }} +{%- endblock %} + +{% block mediagoblin_content %} +
+ {{ csrf_token }} +
+

{% trans %}Delete an OpenID{% endtrans %}

+

+ + {% trans %}Add an OpenID{% endtrans %} + +

+ {{ wtforms_util.render_divs(form, True) }} +
+ +
+
+
+{% endblock %} diff --git a/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/login.html b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/login.html new file mode 100644 index 00000000..33df7200 --- /dev/null +++ b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/login.html @@ -0,0 +1,65 @@ +{# +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +#} +{% extends "mediagoblin/base.html" %} + +{% import "/mediagoblin/utils/wtforms.html" as wtforms_util %} + +{% block mediagoblin_head %} + +{% endblock %} + +{% block title -%} + {% trans %}Log in{% endtrans %} — {{ super() }} +{%- endblock %} + +{% block mediagoblin_content %} +
+ {{ csrf_token }} +
+

{% trans %}Log in{% endtrans %}

+ {% if login_failed %} +
+ {% trans %}Logging in failed!{% endtrans %} +
+ {% endif %} + {% if allow_registration %} +

+ {% trans %}Log in to create an account!{% endtrans %} +

+ {% endif %} + {% if pass_auth is defined %} +

+ + {%- trans %}Or login with a password!{% endtrans %} + +

+ {% endif %} + {{ wtforms_util.render_divs(login_form, True) }} +
+ +
+ {% if next %} + + {% endif %} +
+
+{% endblock %} + diff --git a/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/request_form.html b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/request_form.html new file mode 100644 index 00000000..aa50eb1c --- /dev/null +++ b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/request_form.html @@ -0,0 +1,24 @@ +{# +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +#} +{% extends "mediagoblin/base.html" %} + +{% block mediagoblin_content %} +
+ {{ html|safe }} + +{% endblock %} diff --git a/mediagoblin/plugins/openid/views.py b/mediagoblin/plugins/openid/views.py new file mode 100644 index 00000000..7ed6e6bd --- /dev/null +++ b/mediagoblin/plugins/openid/views.py @@ -0,0 +1,405 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +from openid.consumer import consumer +from openid.consumer.discover import DiscoveryFailure +from openid.extensions.sreg import SRegRequest, SRegResponse + +from mediagoblin import mg_globals, messages +from mediagoblin.db.models import User +from mediagoblin.decorators import (auth_enabled, allow_registration, + require_active_login) +from mediagoblin.tools.response import redirect, render_to_response +from mediagoblin.tools.translate import pass_to_ugettext as _ +from mediagoblin.plugins.openid import lib as auth_lib +from mediagoblin.plugins.openid import forms as auth_forms +from mediagoblin.plugins.openid.models import OpenIDUserURL +from mediagoblin.plugins.openid.store import SQLAlchemyOpenIDStore +from mediagoblin.auth.tools import register_user + + +def _start_verification(request, form, return_to, sreg=True): + """ + Start OpenID Verification. + + Returns False if verification fails, otherwise, will return either a + redirect or render_to_response object + """ + openid_url = form.openid.data + c = consumer.Consumer(request.session, SQLAlchemyOpenIDStore()) + + # Try to discover provider + try: + auth_request = c.begin(openid_url) + except DiscoveryFailure: + # Discovery failed, return to login page + form.openid.errors.append( + _('Sorry, the OpenID server could not be found')) + + return False + + host = 'http://' + request.host + + if sreg: + # Ask provider for email and nickname + auth_request.addExtension(SRegRequest(required=['email', 'nickname'])) + + # Do we even need this? + if auth_request is None: + form.openid.errors.append( + _('No OpenID service was found for %s' % openid_url)) + + elif auth_request.shouldSendRedirect(): + # Begin the authentication process as a HTTP redirect + redirect_url = auth_request.redirectURL( + host, return_to) + + return redirect( + request, location=redirect_url) + + else: + # Send request as POST + form_html = auth_request.htmlMarkup( + host, host + return_to, + # Is this necessary? + form_tag_attrs={'id': 'openid_message'}) + + # Beware: this renders a template whose content is a form + # and some javascript to submit it upon page load. Non-JS + # users will have to click the form submit button to + # initiate OpenID authentication. + return render_to_response( + request, + 'mediagoblin/plugins/openid/request_form.html', + {'html': form_html}) + + return False + + +def _finish_verification(request): + """ + Complete OpenID Verification Process. + + If the verification failed, will return false, otherwise, will return + the response + """ + c = consumer.Consumer(request.session, SQLAlchemyOpenIDStore()) + + # Check the response from the provider + response = c.complete(request.args, request.base_url) + if response.status == consumer.FAILURE: + messages.add_message( + request, + messages.WARNING, + _('Verification of %s failed: %s' % + (response.getDisplayIdentifier(), response.message))) + + elif response.status == consumer.SUCCESS: + # Verification was successfull + return response + + elif response.status == consumer.CANCEL: + # Verification canceled + messages.add_message( + request, + messages.WARNING, + _('Verification cancelled')) + + return False + + +def _response_email(response): + """ Gets the email from the OpenID providers response""" + sreg_response = SRegResponse.fromSuccessResponse(response) + if sreg_response and 'email' in sreg_response: + return sreg_response.data['email'] + return None + + +def _response_nickname(response): + """ Gets the nickname from the OpenID providers response""" + sreg_response = SRegResponse.fromSuccessResponse(response) + if sreg_response and 'nickname' in sreg_response: + return sreg_response.data['nickname'] + return None + + +@auth_enabled +def login(request): + """OpenID Login View""" + login_form = auth_lib.get_login_form(request) + allow_registration = mg_globals.app_config["allow_registration"] + + # Can't store next in request.GET because of redirects to OpenID provider + # Store it in the session + next = request.GET.get('next') + request.session['next'] = next + + login_failed = False + + if request.method == 'POST' and login_form.validate(): + return_to = request.urlgen( + 'mediagoblin.plugins.openid.finish_login') + + success = _start_verification(request, login_form, return_to) + + if success: + return success + + login_failed = True + + return render_to_response( + request, + 'mediagoblin/plugins/openid/login.html', + {'login_form': login_form, + 'next': request.session.get('next'), + 'login_failed': login_failed, + 'post_url': request.urlgen('mediagoblin.plugins.openid.login'), + 'allow_registration': allow_registration}) + + +@auth_enabled +def finish_login(request): + """Complete OpenID Login Process""" + response = _finish_verification(request) + + if not response: + # Verification failed, redirect to login page. + return redirect(request, 'mediagoblin.plugins.openid.login') + + # Verification was successfull + query = OpenIDUserURL.query.filter_by( + openid_url=response.identity_url, + ).first() + user = query.user if query else None + + if user: + # Set up login in session + request.session['user_id'] = unicode(user.id) + request.session.save() + + if request.session.get('next'): + return redirect(request, location=request.session.pop('next')) + else: + return redirect(request, "index") + else: + # No user, need to register + if not mg_globals.app.auth: + messages.add_message( + request, + messages.WARNING, + _('Sorry, authentication is disabled on this instance.')) + return redirect(request, 'index') + + # Get email and nickname from response + email = _response_email(response) + username = _response_nickname(response) + + register_form = auth_forms.RegistrationForm(request.form, + openid=response.identity_url, + email=email, + username=username) + return render_to_response( + request, + 'mediagoblin/auth/register.html', + {'register_form': register_form, + 'post_url': request.urlgen('mediagoblin.plugins.openid.register')}) + + +@allow_registration +@auth_enabled +def register(request): + """OpenID Registration View""" + if request.method == 'GET': + # Need to connect to openid provider before registering a user to + # get the users openid url. If method is 'GET', then this page was + # acessed without logging in first. + return redirect(request, 'mediagoblin.plugins.openid.login') + + register_form = auth_forms.RegistrationForm(request.form) + + if register_form.validate(): + user = register_user(request, register_form) + + if user: + # redirect the user to their homepage... there will be a + # message waiting for them to verify their email + return redirect( + request, 'mediagoblin.user_pages.user_home', + user=user.username) + + return render_to_response( + request, + 'mediagoblin/auth/register.html', + {'register_form': register_form, + 'post_url': request.urlgen('mediagoblin.plugins.openid.register')}) + + +@require_active_login +def start_edit(request): + """Starts the process of adding an openid url to a users account""" + form = auth_forms.LoginForm(request.form) + + if request.method == 'POST' and form.validate(): + query = OpenIDUserURL.query.filter_by( + openid_url=form.openid.data + ).first() + user = query.user if query else None + + if not user: + return_to = request.urlgen('mediagoblin.plugins.openid.finish_edit') + success = _start_verification(request, form, return_to, False) + + if success: + return success + else: + form.openid.errors.append( + _('Sorry, an account is already registered to that OpenID.')) + + return render_to_response( + request, + 'mediagoblin/plugins/openid/add.html', + {'form': form, + 'post_url': request.urlgen('mediagoblin.plugins.openid.edit')}) + + +@require_active_login +def finish_edit(request): + """Finishes the process of adding an openid url to a user""" + response = _finish_verification(request) + + if not response: + # Verification failed, redirect to add openid page. + return redirect(request, 'mediagoblin.plugins.openid.edit') + + # Verification was successfull + query = OpenIDUserURL.query.filter_by( + openid_url=response.identity_url, + ).first() + user_exists = query.user if query else None + + if user_exists: + # user exists with that openid url, redirect back to edit page + messages.add_message( + request, + messages.WARNING, + _('Sorry, an account is already registered to that OpenID.')) + return redirect(request, 'mediagoblin.plugins.openid.edit') + + else: + # Save openid to user + user = User.query.filter_by( + id=request.session['user_id'] + ).first() + + new_entry = OpenIDUserURL() + new_entry.openid_url = response.identity_url + new_entry.user_id = user.id + new_entry.save() + + messages.add_message( + request, + messages.SUCCESS, + _('Your OpenID url was saved successfully.')) + + return redirect(request, 'mediagoblin.edit.account') + + +@require_active_login +def delete_openid(request): + """View to remove an openid from a users account""" + form = auth_forms.LoginForm(request.form) + + if request.method == 'POST' and form.validate(): + # Check if a user has this openid + query = OpenIDUserURL.query.filter_by( + openid_url=form.openid.data + ) + user = query.first().user if query.first() else None + + if user and user.id == int(request.session['user_id']): + count = len(user.openid_urls) + if not count > 1 and not user.pw_hash: + # Make sure the user has a pw or another OpenID + messages.add_message( + request, + messages.WARNING, + _("You can't delete your only OpenID URL unless you" + " have a password set")) + elif user: + # There is a user, but not the same user who is logged in + form.openid.errors.append( + _('That OpenID is not registered to this account.')) + + if not form.errors and not request.session['messages']: + # Okay to continue with deleting openid + return_to = request.urlgen( + 'mediagoblin.plugins.openid.finish_delete') + success = _start_verification(request, form, return_to, False) + + if success: + return success + + return render_to_response( + request, + 'mediagoblin/plugins/openid/delete.html', + {'form': form, + 'post_url': request.urlgen('mediagoblin.plugins.openid.delete')}) + + +@require_active_login +def finish_delete(request): + """Finishes the deletion of an OpenID from an user's account""" + response = _finish_verification(request) + + if not response: + # Verification failed, redirect to delete openid page. + return redirect(request, 'mediagoblin.plugins.openid.delete') + + query = OpenIDUserURL.query.filter_by( + openid_url=response.identity_url + ) + user = query.first().user if query.first() else None + + # Need to check this again because of generic openid urls such as google's + if user and user.id == int(request.session['user_id']): + count = len(user.openid_urls) + if count > 1 or user.pw_hash: + # User has more then one openid or also has a password. + query.first().delete() + + messages.add_message( + request, + messages.SUCCESS, + _('OpenID was successfully removed.')) + + return redirect(request, 'mediagoblin.edit.account') + + elif not count > 1: + messages.add_message( + request, + messages.WARNING, + _("You can't delete your only OpenID URL unless you have a " + "password set")) + + return redirect(request, 'mediagoblin.plugins.openid.delete') + + else: + messages.add_message( + request, + messages.WARNING, + _('That OpenID is not registered to this account.')) + + return redirect(request, 'mediagoblin.plugins.openid.delete') -- cgit v1.2.3 From b01bff8b3c973887fd7063723ee1fb89d6f40a60 Mon Sep 17 00:00:00 2001 From: Rodney Ewing Date: Wed, 26 Jun 2013 12:20:51 -0700 Subject: removed openid/lib, since the get forms functions were not needed for persona plugin --- mediagoblin/plugins/openid/lib.py | 28 ---------------------------- mediagoblin/plugins/openid/views.py | 3 +-- 2 files changed, 1 insertion(+), 30 deletions(-) delete mode 100644 mediagoblin/plugins/openid/lib.py (limited to 'mediagoblin/plugins') diff --git a/mediagoblin/plugins/openid/lib.py b/mediagoblin/plugins/openid/lib.py deleted file mode 100644 index bbe33d44..00000000 --- a/mediagoblin/plugins/openid/lib.py +++ /dev/null @@ -1,28 +0,0 @@ -# GNU MediaGoblin -- federated, autonomous media hosting -# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program 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 Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -import mediagoblin.plugins.openid.forms as auth_forms - - -def get_register_form(request): - # This function will check to see if persona plugin is enabled. If so, - # this function will call hook_transform? and return a modified form - # containing both openid & persona info. - return auth_forms.RegistrationForm(request.form) - - -def get_login_form(request): - # See register_form comment above - return auth_forms.LoginForm(request.form) diff --git a/mediagoblin/plugins/openid/views.py b/mediagoblin/plugins/openid/views.py index 7ed6e6bd..b95144d0 100644 --- a/mediagoblin/plugins/openid/views.py +++ b/mediagoblin/plugins/openid/views.py @@ -23,7 +23,6 @@ from mediagoblin.decorators import (auth_enabled, allow_registration, require_active_login) from mediagoblin.tools.response import redirect, render_to_response from mediagoblin.tools.translate import pass_to_ugettext as _ -from mediagoblin.plugins.openid import lib as auth_lib from mediagoblin.plugins.openid import forms as auth_forms from mediagoblin.plugins.openid.models import OpenIDUserURL from mediagoblin.plugins.openid.store import SQLAlchemyOpenIDStore @@ -139,7 +138,7 @@ def _response_nickname(response): @auth_enabled def login(request): """OpenID Login View""" - login_form = auth_lib.get_login_form(request) + login_form = auth_forms.LoginForm(request) allow_registration = mg_globals.app_config["allow_registration"] # Can't store next in request.GET because of redirects to OpenID provider -- cgit v1.2.3 From 664ce3bfaea6778c3fbca613ab66da881559f4c3 Mon Sep 17 00:00:00 2001 From: Rodney Ewing Date: Wed, 26 Jun 2013 12:43:12 -0700 Subject: fixed openid store cleanupAssociations --- mediagoblin/plugins/openid/store.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'mediagoblin/plugins') diff --git a/mediagoblin/plugins/openid/store.py b/mediagoblin/plugins/openid/store.py index b54cf5c8..8f9a7012 100644 --- a/mediagoblin/plugins/openid/store.py +++ b/mediagoblin/plugins/openid/store.py @@ -105,8 +105,6 @@ class SQLAlchemyOpenIDStore(OpenIDStore): ononce.save() return True - # Need to test these cleanups, not sure if the expired Association query - # will work def cleanupNonces(self, _now=None): if _now is None: _now = int(time.time()) @@ -120,9 +118,10 @@ class SQLAlchemyOpenIDStore(OpenIDStore): def cleanupAssociations(self): now = int(time.time()) - expired = Association.query.filter( - 'issued + lifetime' < now) - count = expired.count() - for each in expired: - each.delete() + assoc = Association.query.all() + count = 0 + for each in assoc: + if (each.lifetime + each.issued) <= now: + each.delete() + count = count + 1 return count -- cgit v1.2.3 From ef146456b1a2648b9f137593f0a551d16a69965a Mon Sep 17 00:00:00 2001 From: Rodney Ewing Date: Wed, 26 Jun 2013 12:44:37 -0700 Subject: typo --- .../openid/templates/mediagoblin/plugins/openid/request_form.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'mediagoblin/plugins') diff --git a/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/request_form.html b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/request_form.html index aa50eb1c..68d028d0 100644 --- a/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/request_form.html +++ b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/request_form.html @@ -20,5 +20,5 @@ {% block mediagoblin_content %}
{{ html|safe }} - +
{% endblock %} -- cgit v1.2.3 From d66f79031e07447ab22cb19a610f388ff85ce249 Mon Sep 17 00:00:00 2001 From: Rodney Ewing Date: Wed, 26 Jun 2013 12:53:02 -0700 Subject: forgot to pass request.form into LoginForm class --- mediagoblin/plugins/openid/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'mediagoblin/plugins') diff --git a/mediagoblin/plugins/openid/views.py b/mediagoblin/plugins/openid/views.py index b95144d0..9566e38e 100644 --- a/mediagoblin/plugins/openid/views.py +++ b/mediagoblin/plugins/openid/views.py @@ -138,7 +138,7 @@ def _response_nickname(response): @auth_enabled def login(request): """OpenID Login View""" - login_form = auth_forms.LoginForm(request) + login_form = auth_forms.LoginForm(request.form) allow_registration = mg_globals.app_config["allow_registration"] # Can't store next in request.GET because of redirects to OpenID provider -- cgit v1.2.3 From fea0b3b289154c96017021d25b0ed455d6f7f7b4 Mon Sep 17 00:00:00 2001 From: Rodney Ewing Date: Wed, 3 Jul 2013 07:16:31 -0700 Subject: use template hooks instead of hardcoding in templates --- mediagoblin/plugins/basic_auth/__init__.py | 9 -------- mediagoblin/plugins/openid/__init__.py | 9 ++++---- .../mediagoblin/plugins/openid/edit_link.html | 25 ++++++++++++++++++++ .../mediagoblin/plugins/openid/login_link.html | 25 ++++++++++++++++++++ .../mediagoblin/plugins/openid/register_link.html | 27 ++++++++++++++++++++++ 5 files changed, 82 insertions(+), 13 deletions(-) create mode 100644 mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/edit_link.html create mode 100644 mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/login_link.html create mode 100644 mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/register_link.html (limited to 'mediagoblin/plugins') diff --git a/mediagoblin/plugins/basic_auth/__init__.py b/mediagoblin/plugins/basic_auth/__init__.py index 2e7e8f8c..c16d8855 100644 --- a/mediagoblin/plugins/basic_auth/__init__.py +++ b/mediagoblin/plugins/basic_auth/__init__.py @@ -71,11 +71,6 @@ def append_to_global_context(context): return context -def add_to_form_context(context): - context['pass_auth_link'] = True - return context - - hooks = { 'setup': setup_plugin, 'authentication': auth, @@ -87,8 +82,4 @@ hooks = { 'auth_check_password': check_password, 'auth_fake_login_attempt': auth_tools.fake_login_attempt, 'template_global_context': append_to_global_context, - ('mediagoblin.plugins.openid.register', - 'mediagoblin/auth/register.html'): add_to_form_context, - ('mediagoblin.plugins.openid.finish_login', - 'mediagoblin/auth/register.html'): add_to_form_context, } diff --git a/mediagoblin/plugins/openid/__init__.py b/mediagoblin/plugins/openid/__init__.py index 9803ada6..1ee60fbf 100644 --- a/mediagoblin/plugins/openid/__init__.py +++ b/mediagoblin/plugins/openid/__init__.py @@ -56,6 +56,11 @@ def setup_plugin(): pluginapi.register_routes(routes) pluginapi.register_template_path(os.path.join(PLUGIN_DIR, 'templates')) + pluginapi.register_template_hooks( + {'openid_register_link': 'mediagoblin/plugins/openid/register_link.html', + 'openid_login_link': 'mediagoblin/plugins/openid/login_link.html', + 'openid_edit_link': 'mediagoblin/plugins/openid/edit_link.html'}) + def create_user(register_form): if 'openid' in register_form: @@ -115,8 +120,4 @@ hooks = { 'auth_no_pass_redirect': no_pass_redirect, ('mediagoblin.auth.register', 'mediagoblin/auth/register.html'): add_to_form_context, - ('mediagoblin.auth.login', - 'mediagoblin/auth/login.html'): add_to_form_context, - ('mediagoblin.edit.account', - 'mediagoblin/edit/edit_account.html'): add_to_form_context, } diff --git a/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/edit_link.html b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/edit_link.html new file mode 100644 index 00000000..2e63e1f8 --- /dev/null +++ b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/edit_link.html @@ -0,0 +1,25 @@ +{# +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +#} + +{% block openid_edit_link %} +

+ + {% trans %}Edit your OpenID's{% endtrans %} + +

+{% endblock %} diff --git a/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/login_link.html b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/login_link.html new file mode 100644 index 00000000..e5e77d01 --- /dev/null +++ b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/login_link.html @@ -0,0 +1,25 @@ +{# +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +#} + +{% block openid_login_link %} +

+ + {%- trans %}Or login with OpenID!{% endtrans %} + +

+{% endblock %} diff --git a/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/register_link.html b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/register_link.html new file mode 100644 index 00000000..9bccb4d8 --- /dev/null +++ b/mediagoblin/plugins/openid/templates/mediagoblin/plugins/openid/register_link.html @@ -0,0 +1,27 @@ +{# +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +#} + +{% block openid_register_link %} + {% if openid_link is defined %} +

+ + {%- trans %}Or register with OpenID!{% endtrans %} + +

+ {% endif %} +{% endblock %} -- cgit v1.2.3 From c92b3c63b13ad44e8485a577f5fb768c9bdc1f94 Mon Sep 17 00:00:00 2001 From: Rodney Ewing Date: Wed, 3 Jul 2013 08:09:06 -0700 Subject: changed hook name to reuse with persona --- mediagoblin/plugins/openid/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'mediagoblin/plugins') diff --git a/mediagoblin/plugins/openid/__init__.py b/mediagoblin/plugins/openid/__init__.py index 1ee60fbf..ee88808c 100644 --- a/mediagoblin/plugins/openid/__init__.py +++ b/mediagoblin/plugins/openid/__init__.py @@ -57,9 +57,9 @@ def setup_plugin(): pluginapi.register_template_path(os.path.join(PLUGIN_DIR, 'templates')) pluginapi.register_template_hooks( - {'openid_register_link': 'mediagoblin/plugins/openid/register_link.html', - 'openid_login_link': 'mediagoblin/plugins/openid/login_link.html', - 'openid_edit_link': 'mediagoblin/plugins/openid/edit_link.html'}) + {'register_link': 'mediagoblin/plugins/openid/register_link.html', + 'login_link': 'mediagoblin/plugins/openid/login_link.html', + 'edit_link': 'mediagoblin/plugins/openid/edit_link.html'}) def create_user(register_form): -- cgit v1.2.3