Initial cleanup of the codebase
Change-Id: Idbc92ea3c2d7ee4d4807d1d83ceee9a299b9a9f7
diff --git a/app/providers/__init__.py b/app/providers/__init__.py
new file mode 100644
index 0000000..1efe8f3
--- /dev/null
+++ b/app/providers/__init__.py
@@ -0,0 +1,250 @@
+from flask import flash
+from requests.auth import HTTPBasicAuth
+
+import APIFactory
+import config
+
+
+__author__ = 'hanl'
+
+
+
+# instance reference for authentication provider
+# must be set before usage!
+provider = None
+message_handler = None
+
+
+def load_provider(provider_name, handler):
+ '''
+ :param provider_name:
+ :return:
+ '''
+ global message_handler
+ message_handler = handler
+
+ split = provider_name.split('.')
+ # get last element, so you have the class name
+ _class = split[len(split) - 1]
+ provider_name = provider_name.replace("." + _class, "")
+ module = __import__(provider_name)
+ obj = getattr(module, _class, None)
+ instance = obj()
+ if instance is None:
+ raise KeyError("the provider class %s is undefined!" % str(_class))
+ print "successfully loaded provider '%s'" % str(_class)
+ global provider
+ provider = instance
+ return instance
+
+
+class User(object):
+ '''
+ the user object
+ '''
+
+ def __init__(self, username, password=None, email=None, firstName=None, lastName=None, address=None,
+ institution=None,
+ phone=None, country=None, id_token=None):
+ print "the username %s" % str(username)
+ if not username:
+ raise ValueError("the username must be set")
+ self.username = username
+ self.password = password
+ self.email = email
+ self.firstName = firstName
+ self.lastName = lastName
+ self.address = address
+ self.institution = institution
+ self.phone = phone
+ self.country = country
+ self.id_token = id_token
+
+ def is_authenticated(self):
+ return True
+
+ def has_details(self):
+ if self.firstName and self.lastName and self.email:
+ return True
+ return False
+
+ def is_anonymous(self):
+ return False
+
+ def get_id(self):
+ '''
+ :return: id reference to retrieve user object from middleware
+ '''
+ return unicode(self.username)
+
+ def is_active(self):
+ return True
+
+ def get_full_name(self):
+ if self.firstName and self.lastName:
+ return u' '.join([self.firstName, self.lastName])
+ return None
+
+
+class Provider(object):
+ global message_handler
+
+ def __init__(self):
+ self.handler = message_handler
+
+ def authenticate(self, username=None, password=None):
+ pass
+
+ def get_user(self, username=None, session=None, full=False):
+ if not username or not session:
+ return ValueError("username and session must be provided!")
+
+ def login(self, session=None, user=None):
+ pass
+
+
+ def logout(self, session=None):
+ pass
+
+ def is_authenticated(self):
+ pass
+
+
+class CustomProvider(Provider):
+ def authenticate(self, username=None, password=None):
+ pass
+
+ def get_user(self, username=None, session=None, full=False):
+ """
+ Returns the user model instance associated with the given request session.
+ If no user is retrieved an instance of `AnonymousUser` is returned.
+ """
+ # call super method
+ super(CustomProvider, self).get_user(username, session, full)
+ if full:
+ id_token = session['api_token']
+ code = APIFactory.decrypt_openid(token=id_token)
+ user = User(username=username, email=code['email'], firstName=code['firstName'],
+ lastName=code['lastName'], address=code['address'], institution=code['institution'],
+ phone=code['phone'])
+ return user
+ else:
+ return User(username=username)
+
+ def login(self, session=None, user=None):
+ '''
+ :param login_func: client specific login function
+ :param user: user object to register user for
+ :return: boolean if login successful
+ '''
+ super(CustomProvider, self).login(session, user)
+
+ response = APIFactory.get("auth/requestToken", auth=HTTPBasicAuth(username=user.username,
+ password=user.password))
+ user.password = None
+
+ if response is None:
+ return False
+ elif self.handler.isError(response):
+ self.handler.notifyNext(response.json(), flash)
+ return False
+ print "the response %i:%s" % (response.status_code, str(response.content))
+ session['api_token'] = response.content.replace('api_token ', '')
+ return True
+
+ def logout(self, session=None):
+ if 'api_token' not in session:
+ return False
+ session.pop('api_token', None)
+ return True
+
+ def is_authenticated(self):
+ '''
+ check that oauth id_token and access_token are not expired!
+ :return:
+ '''
+ pass
+
+
+class OAuth2Provider(Provider):
+ def authenticate(self, username=None, password=None):
+ pass
+
+ def get_user(self, username=None, session=None, full=False):
+ """
+ Returns the user model instance associated with the given request session.
+ If no user is retrieved an instance of `AnonymousUser` is returned.
+ """
+ # call super method
+ super(OAuth2Provider, self).get_user(username, session, full)
+
+ if full and "openid" in config.OPENID_CONNECT_SCOPES and "profile" in config.OPENID_CONNECT_SCOPES:
+ id_token = session['id_token']
+ code = APIFactory.decrypt_openid(secret=config.OAUTH2_CLIENT_SECRET, token=id_token)
+ user = User(username=username, email=code['email'], firstName=code['firstName'],
+ lastName=code['lastName'], address=code['address'], institution=code['institution'],
+ phone=code['phone'])
+ return user
+ elif full:
+ response = APIFactory.get("user/info", auth=APIFactory.Oauth2Auth(session['access_token']))
+ if response is None:
+ return None
+ elif self.handler.isError(response):
+ self.handler.notifyNext(response.json(), flash)
+ return None
+ else:
+ code = response.json()
+ user = User(username=username, email=code['email'], firstName=code['firstName'],
+ lastName=code['lastName'], address=code['address'], institution=code['institution'],
+ phone=code['phone'])
+ return user
+ else:
+ # for the most tasks its only about to have a user object, not the actual data!
+ return User(username=username)
+
+ def login(self, session=None, user=None):
+ '''
+ :param login_func: client specific login function
+ :param user: user object to register user for
+ :return: boolean if login successful
+ '''
+ super(OAuth2Provider, self).login(session, user)
+
+ params = {"username": user.username, "password": user.password,
+ "grant_type": "password", "client_id": config.OAUTH2_CLIENT_ID,
+ "client_secret": config.OAUTH2_CLIENT_SECRET, "scope": config.OPENID_CONNECT_SCOPES}
+ response = APIFactory.post(path='oauth2/token', params=params)
+ user.password = None
+
+ if response is None:
+ return False
+ elif self.handler.isError(response):
+ self.handler.notifyNext(response.json(), flash)
+ return False
+ print "the response %i:%s" % (response.status_code, str(response.content))
+
+ session['access_token'] = response.json()['access_token']
+ if "openid" in config.OPENID_CONNECT_SCOPES:
+ session['id_token'] = response.json()['id_token']
+ else:
+ session['id_token'] = "some random string" # todo ???
+ return True
+
+
+ def logout(self, session=None):
+ if 'access_token' not in session:
+ return False
+
+ session.pop('access_token', None)
+ if 'id_token' in session:
+ session.pop('id_token', None)
+ return True
+
+
+ def is_authenticated(self):
+ '''
+ check that oauth id_token and access_token are not expired!
+ add function to auth decorator
+ :return:
+ '''
+ pass