From 43b7fcb1943d868101f3686788ba46e035e84591 Mon Sep 17 00:00:00 2001 From: Megan Henning <meganhenning@flywheel.io> Date: Mon, 11 Sep 2017 16:35:32 -0500 Subject: [PATCH] Add CAS authentication --- api/auth/authproviders.py | 56 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/api/auth/authproviders.py b/api/auth/authproviders.py index 61a4e178..25b064d7 100644 --- a/api/auth/authproviders.py +++ b/api/auth/authproviders.py @@ -4,6 +4,8 @@ import json import urllib import urlparse +from xml.etree import ElementTree + from . import APIAuthProviderException, APIUnknownUserException, APIRefreshTokenException from .. import config, util from ..dao import dbutil @@ -189,6 +191,7 @@ class GoogleOAuthProvider(AuthProvider): # If the user has no avatar set, mark their provider_avatar as their chosen avatar. config.db.users.update_one({'_id': uid, 'avatar': {'$exists': False}}, {'$set':{'avatar': provider_avatar, 'modified': timestamp}}) + class WechatOAuthProvider(AuthProvider): def __init__(self): @@ -278,6 +281,56 @@ class WechatOAuthProvider(AuthProvider): pass +class CASAuthProvider(AuthProvider): + + def __init__(self): + super(CASAuthProvider, self).__init__('cas') + + def validate_code(self, code, **kwargs): + uid = self.validate_user(code) + return { + 'access_token': code, + 'uid': uid, + 'auth_type': self.auth_type, + 'expires': datetime.datetime.utcnow() + datetime.timedelta(days=14) + } + + def validate_user(self, token): + config.log.warning('the config is {}\n\n'.format(self.config)) + r = requests.get(self.config['verify_endpoint'], params={'ticket': token, 'service': self.config['service_url']}) + if not r.ok: + raise APIAuthProviderException('User token not valid') + + username = self._parse_xml_response(r.content) + uid = username+'@'+self.config['namespace'] + + self.ensure_user_exists(uid) + self.set_user_gravatar(uid, uid) + + return uid + + def _parse_xml_response(self, response): + + # parse xml + tree = ElementTree.fromstring(response) + + # check to see if xml response labeled request as success + if tree[0].tag.endswith('authenticationSuccess'): + + # get username from response + namespace = tree.tag[0:tree.tag.index('}')+1] + username = tree[0].find('.//' + namespace + 'user').text + + else: + raise APIAuthProviderException('Auth provider ticket verification unsuccessful.') + + if not username: + raise APIAuthProviderException('Auth provider did not provide username') + + return username + + + class APIKeyAuthProvider(AuthProvider): """ Uses an API key for authentication. @@ -339,5 +392,6 @@ AuthProviders = { 'google' : GoogleOAuthProvider, 'ldap' : JWTAuthProvider, 'wechat' : WechatOAuthProvider, - 'api-key' : APIKeyAuthProvider + 'api-key' : APIKeyAuthProvider, + 'cas' : CASAuthProvider } -- GitLab