Commits

Tarashish Mishra  committed 57fa668

user authentication from gae api

  • Participants
  • Parent commits 4e7d736
  • Branches gae

Comments (0)

Files changed (5)

File MoinMoin/auth/gae.py

+# Copyright: 2012 MoinMoin:TarashishMishra
+# License: GNU GPL v2 (or any later version), see LICENSE.txt for details.
+
+"""
+    MoinMoin - Authentication on GAE
+
+    Users could log in into moin using their google account
+
+"""
+
+
+from MoinMoin import log
+logging = log.getLogger(__name__)
+
+from MoinMoin import user
+from MoinMoin.auth import BaseAuth, MultistageRedirectLogin, ContinueLogin
+from MoinMoin.constants.keys import *
+
+from werkzeug import redirect, abort
+from flask import url_for
+
+from google.appengine.api import users
+
+
+class GAEAuthMoin(BaseAuth):
+    """ authenticate on gae using google account """
+    name = 'gae'
+    login_inputs = ['special_no_input']
+    logout_possible = True
+
+    def login(self, user_obj=None, **kw):
+        u = None
+        # always revalidate auth
+        if user_obj and user_obj.auth_method == self.name:
+            user_obj = None
+        # something else authenticated before us
+        if user_obj:
+            return ContinueLogin(user_obj)
+        # get the current user from gae
+        gae_user = users.get_current_user()
+        if not gae_user:
+            # Redirect the user to the google account login, telling it to redirect back to
+            # moin's .show_root url, simulating a login there.
+            return_to = url_for(".show_root", login_submit=1)
+            return MultistageRedirectLogin(users.create_login_url(return_to))
+
+        gae_user_id = unicode(gae_user.user_id())
+        email = unicode(gae_user.email())
+        nickname = unicode(gae_user.nickname())
+        logging.debug("Current gae_user: name: {0!r}, email: {1!r}, gae_user_id: {2!r}".format(nickname, email, gae_user_id))
+        # try to get existing user with the same gae_user_id
+        users_list = user.search_users(gae_user_id=gae_user_id)
+        if users_list:
+            u = user.User(uid=users_list[0].meta[ITEMID], trusted=self.trusted, auth_method=self.name)
+            changed = False
+        else:
+            # if no user with same gae_user_id found try to get existing user with the same email
+            users_list = user.search_users(email=email)
+            if users_list:
+                u = user.User(uid=users_list[0].meta[ITEMID], trusted=self.trusted, auth_method=self.name)
+                # set gae_user_id when user is found by email
+                u.profile[GAE_USER_ID] = gae_user_id
+                changed = True
+            else:
+                # if there is no existing user with same gae_user_id or email create one
+                u = user.User(trusted=self.trusted, auth_method=self.name)
+                u.profile[GAE_USER_ID] = gae_user_id
+                u.profile[EMAIL] = email
+                u.profile[NAME] = nickname
+                changed = True
+        if u:
+            u.create_or_update(changed=changed)
+            user_obj = u
+
+        return ContinueLogin(user_obj)
+
+    def logout(self, user_obj, **kw):
+        # TODO: currently, logging out of moin logs you out of all applications that use your
+        # google account. We should fix that.
+        user_obj.logout_session()
+        abort(redirect(users.create_logout_url(url_for('.show_root'))))

File MoinMoin/constants/keys.py

 EDIT_ROWS = "edit_rows"
 RESULTS_PER_PAGE = "results_per_page"
 DISABLED = "disabled"
+GAE_USER_ID = "gae_user_id"
 
 USEROBJ_ATTRS = [
     # User objects proxy these attributes of the UserProfile objects:

File MoinMoin/templates/layout.html

                     <a href="{{ url_for('frontend.usersettings') }}" class="moin-usersettings" rel="nofollow">{{ _('Settings') }}</a>
                 {%- endif %}
             {%- endif %}
-            {% if user.auth_method in cfg.auth_can_logout %}
-                <span class="sep"> | </span>
-                <a href="{{ url_for('frontend.logout', logout_submit=1) }}" class="moin-logout" rel="nofollow">
-                    {{ _('Logout') }}
-                </a>
+            {% set logout_url = theme_supp.logout_url() %}
+            {% if logout_url %}
+                    <span class="sep"> | </span>
+                    <a href="{{ logout_url }}" class="moin-logout" rel="nofollow">
+                        {{ _('Logout') }}
+                    </a>
             {% endif %}
+                
         {% else %}
             {% set login_url = theme_supp.login_url() %}
             {% if login_url %}

File MoinMoin/themes/__init__.py

         """
         url = None
         if self.cfg.auth_login_inputs == ['special_no_input']:
-            url = url_for('frontend.login', login=1)
+            url = url_for('frontend.login', login=1, login_submit=1)
         if self.cfg.auth_have_login:
             url = url or url_for('frontend.login')
         return url
 
+    def logout_url(self):
+        """
+        Return URL usable for user logout
+
+        :rtype: unicode (or None, if no logout url is supported)
+        :returns: url for user logout
+        """
+        url = None
+        if flaskg.user and flaskg.user.auth_method in self.cfg.auth_can_logout:
+            url = url_for('frontend.logout', logout_submit=1)
+        return url
+
 
 def get_editor_info(meta, external=False):
     addr = meta.get(ADDRESS)

File wikiconfig_gae.py

 from MoinMoin.config.default import DefaultConfig
 from MoinMoin.storage import create_simple_mapping
 from MoinMoin.util.interwiki import InterWikiMap
+from MoinMoin.auth.gae import GAEAuthMoin
 
 
 class Config(DefaultConfig):
         mod = getattr(pkg, mod_name)
         xs = XStatic(mod, root_url='/static', provider='local', protocol='http')
         serve_files.update([(xs.name, xs.base_dir)])
-
+    auth = [GAEAuthMoin(), ]
 
 MOINCFG = Config # Flask only likes uppercase stuff
 # Flask settings - see the flask documentation about their meaning