views.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. # GNU MediaGoblin -- federated, autonomous media hosting
  2. # Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
  3. #
  4. # This program is free software: you can redistribute it and/or modify
  5. # it under the terms of the GNU Affero General Public License as published by
  6. # the Free Software Foundation, either version 3 of the License, or
  7. # (at your option) any later version.
  8. #
  9. # This program is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. # GNU Affero General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU Affero General Public License
  15. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. import json
  17. import logging
  18. import requests
  19. import six
  20. from werkzeug.exceptions import BadRequest
  21. from mediagoblin import messages, mg_globals
  22. from mediagoblin.auth.tools import register_user
  23. from mediagoblin.decorators import (auth_enabled, allow_registration,
  24. require_active_login)
  25. from mediagoblin.tools.response import render_to_response, redirect
  26. from mediagoblin.tools.translate import pass_to_ugettext as _
  27. from mediagoblin.plugins.persona import forms
  28. from mediagoblin.plugins.persona.models import PersonaUserEmails
  29. _log = logging.getLogger(__name__)
  30. def _get_response(request):
  31. if 'assertion' not in request.form:
  32. _log.debug('assertion not in request.form')
  33. raise BadRequest()
  34. data = {'assertion': request.form['assertion'],
  35. 'audience': request.urlgen('index', qualified=True)}
  36. resp = requests.post('https://verifier.login.persona.org/verify',
  37. data=data, verify=True)
  38. if resp.ok:
  39. verification_data = json.loads(resp.content)
  40. if verification_data['status'] == 'okay':
  41. return verification_data['email']
  42. return None
  43. @auth_enabled
  44. def login(request):
  45. if request.method == 'GET':
  46. return redirect(request, 'mediagoblin.auth.login')
  47. email = _get_response(request)
  48. if email:
  49. query = PersonaUserEmails.query.filter_by(
  50. persona_email=email
  51. ).first()
  52. user = query.user if query else None
  53. if user:
  54. request.session['user_id'] = six.text_type(user.id)
  55. request.session['persona_login_email'] = email
  56. request.session.save()
  57. return redirect(request, "index")
  58. else:
  59. if not mg_globals.app.auth:
  60. messages.add_message(
  61. request,
  62. messages.WARNING,
  63. _('Sorry, authentication is disabled on this instance.'))
  64. return redirect(request, 'index')
  65. register_form = forms.RegistrationForm(email=email,
  66. persona_email=email)
  67. return render_to_response(
  68. request,
  69. 'mediagoblin/auth/register.html',
  70. {'register_form': register_form,
  71. 'post_url': request.urlgen(
  72. 'mediagoblin.plugins.persona.register')})
  73. return redirect(request, 'mediagoblin.auth.login')
  74. @allow_registration
  75. @auth_enabled
  76. def register(request):
  77. if request.method == 'GET':
  78. # Need to connect to persona before registering a user. If method is
  79. # 'GET', then this page was acessed without logging in first.
  80. return redirect(request, 'mediagoblin.auth.login')
  81. register_form = forms.RegistrationForm(request.form)
  82. if register_form.validate():
  83. user = register_user(request, register_form)
  84. if user:
  85. # redirect the user to their homepage... there will be a
  86. # message waiting for them to verify their email
  87. return redirect(
  88. request, 'mediagoblin.user_pages.user_home',
  89. user=user.username)
  90. return render_to_response(
  91. request,
  92. 'mediagoblin/auth/register.html',
  93. {'register_form': register_form,
  94. 'post_url': request.urlgen('mediagoblin.plugins.persona.register')})
  95. @require_active_login
  96. def edit(request):
  97. form = forms.EditForm(request.form)
  98. if request.method == 'POST' and form.validate():
  99. query = PersonaUserEmails.query.filter_by(
  100. persona_email=form.email.data)
  101. user = query.first().user if query.first() else None
  102. if user and user.id == int(request.user.id):
  103. count = len(user.persona_emails)
  104. if count > 1 or user.pw_hash:
  105. # User has more then one Persona email or also has a password.
  106. query.first().delete()
  107. messages.add_message(
  108. request,
  109. messages.SUCCESS,
  110. _('The Persona email address was successfully removed.'))
  111. return redirect(request, 'mediagoblin.edit.account')
  112. elif not count > 1:
  113. form.email.errors.append(
  114. _("You can't delete your only Persona email address unless"
  115. " you have a password set."))
  116. else:
  117. form.email.errors.append(
  118. _('That Persona email address is not registered to this'
  119. ' account.'))
  120. return render_to_response(
  121. request,
  122. 'mediagoblin/plugins/persona/edit.html',
  123. {'form': form,
  124. 'edit_persona': True})
  125. @require_active_login
  126. def add(request):
  127. if request.method == 'GET':
  128. return redirect(request, 'mediagoblin.plugins.persona.edit')
  129. email = _get_response(request)
  130. if email:
  131. query = PersonaUserEmails.query.filter_by(
  132. persona_email=email
  133. ).first()
  134. user_exists = query.user if query else None
  135. if user_exists:
  136. messages.add_message(
  137. request,
  138. messages.WARNING,
  139. _('Sorry, an account is already registered with that Persona'
  140. ' email address.'))
  141. return redirect(request, 'mediagoblin.plugins.persona.edit')
  142. else:
  143. # Save the Persona Email to the user
  144. new_entry = PersonaUserEmails()
  145. new_entry.persona_email = email
  146. new_entry.user_id = request.user.id
  147. new_entry.save()
  148. request.session['persona_login_email'] = email
  149. messages.add_message(
  150. request,
  151. messages.SUCCESS,
  152. _('Your Persona email address was saved successfully.'))
  153. return redirect(request, 'mediagoblin.edit.account')