def authenticate(self, environ, identity): """ authenticated user to the identity. If a auth cookie is given it is appended to the indentiy. :param environ: The WSGI environment. :param identity: The repoze.who's identity dictionary. """ if 'login' not in identity or 'password' not in identity: return None login = identity['login'] password = identity['password'] try: if not self.conn: self.conn = Connection(self.base_url, server_cert=self.server_cert, client_cert=self.client_cert, client_key=self.client_key) params = {'login': login, 'password': password} headers = { "Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain" } if environ.get('HTTP_ACCEPT_LANGUAGE', None): headers['Accept-Language'] = environ.get( 'HTTP_ACCEPT_LANGUAGE', None) path = "/userservice/auth" response = self.conn.post(path, params=params, headers=headers) if response.status_code != 200: return "::ERROR:: Connection response: %s (%s) %r" % ( response.reason, path, response.status_code) res = response.json() authUser = res.get('result', {}).get('value', False) if authUser != False: cookie = response.get_cookie('userauthcookie') if cookie: return "%s;%s" % (login, cookie) else: return login else: return "::ERROR:: Authentication attempt failed!" except Exception as exx: log.error("[authenticate] %r" % exx) return "::ERROR:: Connection failed!"
def add_metadata(self, environ, identity): """ Add metadata about the authenticated user to the identity. It modifies the C{identity} dictionary to add the metadata. :param environ: The WSGI environment. :param identity: The repoze.who's identity dictionary. """ params = {} headers = { "Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain" } # this part is used implicit: # on logout, there is no login and thus just return a None path = environ.get('PATH_INFO', '/logout') if '/logout' in path: return None # due to the requirement to transfer info back from repoze # authentication, we have to deal with the ::ERROR:: user if (identity and "::ERROR::" in identity.get('repoze.who.user', '::ERROR::')): return None try: if not self.conn: self.conn = Connection(self.base_url, server_cert=self.server_cert, client_cert=self.client_cert, client_key=self.client_key) if environ.get('HTTP_ACCEPT_LANGUAGE', None): headers['Accept-Language'] = environ.get( 'HTTP_ACCEPT_LANGUAGE', None) if not self.conn.is_user_session_set: # for the authetication we take the 'repoze.who.userid' as it # is the one which is returned from the authenticate call # extended by the realm and joined with the auth_cookie if ';' in identity['repoze.who.userid']: user, session = identity['repoze.who.userid'].split(';', 1) self.conn.set_user_session(session, user) else: user = identity['repoze.who.userid'] self.conn.set_user_session(None, user) path = "/userservice/userinfo" response = self.conn.post(path, params=params, headers=headers) if response.status_code == 200: res = response.json() user_data = res.get('result', {}).get('value', []) if type(user_data) in [dict]: identity.update(user_data) # implicit return of enriched identity return identity except Exception as exx: log.error("[add_metadata] %r" % exx) return "::ERROR:: Connection failed!"
def call_linotp(self, url, params=None, return_json=True): """ make a http request to the linotp server :param url: the path of the linotp resource :param params: dict with request parameters :param return_json: bool, response should already be a json loaded obj :return: return the response of the request as dict or as plain text """ if not self.conn: self.conn = Connection(self.base_url, server_cert=self.server_cert, client_cert=self.client_cert, client_key=self.client_key) if params is None: params = {} headers = { "Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain", } # for locale support, we copy the incomming languege settings if self.browser_language: headers['Accept-Language'] = self.browser_language if not self.conn.is_user_session_set: # if we are requesting for a user, provide the user auth cookie if 'user' in params: if hasattr(self, 'auth_cookie') and self.auth_cookie: self.conn.set_user_session(self.auth_cookie, params['user']) path = url if 'session' in params: # If a session is contained in params it is the local selfservice # session (between the browser and this server) not the session # between selfservice and LinOTP. Therefore we delete it. The # selfservice->LinOTP session has already been set with # 'self.conn.set_user_session' del params['session'] net_response = self.conn.post(path, params=params, headers=headers) if net_response.status_code != 200: error = "%s%s: %s - %s" % (self.config.get( 'linotp_url', ''), path, net_response.status_code, net_response.reason) log.error(error) if net_response.reason == "Logout from LinOTP selfservice": raise SessionExpiratioException( error, url=self.config.get('linotp_url', ''), path=path, status_code=net_response.status_code, reason=net_response.reason) raise InvalidLinOTPResponse(error, url=self.config.get('linotp_url', ''), path=path, status_code=net_response.status_code, reason=net_response.reason) return net_response.json() if return_json else net_response.text()