class UserService(object): def __init__(self): self.repository = Repository() """ exposed methods """ def register(self, req): req['password'] = bcrypt.hashpw(str.encode(req['password']), bcrypt.gensalt()).decode() response = Response(None, 'Operation not built yet.', None, None) result = self.repository.create_account(req) if 'error' in result: response.error = result['error'] response.message = 'Error registering customer/user.' else: if result == 'NOP': return response response.data = result['acct'] response.message = 'Successfully registered customer/user.' return response def login(self, req): valid_user_res = self.verify_user(req['username'], str.encode(req['pw'])) if valid_user_res.error or 'Operation not' in valid_user_res.message: return valid_user_res response = Response(None, 'Operation not built yet.', None, None) if not valid_user_res.data: response.message = 'Invalid user. Check username and password.' response.authorized = False return response key = 'customer_{0}'.format(valid_user_res.data['custId']) customer_info = self.repository.get_object_by_key(key) session_res = self.create_session(req['username']) if session_res.error: return session_res secret = get_secret() encoded_jwt = jwt.encode({'id': session_res.data}, secret, algorithm='HS256') response.data = { 'userInfo': { 'userId': valid_user_res.data['userId'], 'username': valid_user_res.data['username'], 'token': encoded_jwt.decode() }, 'customerInfo': customer_info } response.message = 'Successfully logged in (session created).' response.authorized = True return response def get_user_from_session(self, jwt): valid_user_res = self.verify_user(jwt['sessionRes'].data['username'], None, True) if valid_user_res.error or 'Operation not' in valid_user_res.message: return valid_user_res response = Response(None, 'Operation not built yet.', None, None) if not valid_user_res.data: response.message = 'Invalid user. Check username and password.' response.authorized = False return response response.data = { 'userInfo': { 'userId': valid_user_res.data['userId'], 'username': valid_user_res.data['username'], 'token': jwt['token'] } } response.message = 'Successfully verified and extended session.' response.authorized = True return response """ Private methods """ def create_session(self, username): response = Response(None, 'Operation not built yet.', None, None) expiry = int(get_ttl()) session = self.repository.create_session(username, expiry) if 'error' in session: response.message = 'Error creating session.' response.error = session['error'] return response if 'sessionId' in session: response.data = session['sessionId'] response.message = 'Session created.' return response def extend_session(self, token): secret = get_secret() response = Response(None, 'Operation not built yet.', None, None) decoded = None try: decoded_jwt = jwt.decode(token, secret, algorithms=['HS256']) except Exception as ex: print(ex) response.message = 'Error extending session. Invalid token.' response.error = ex return response expiry = int(get_ttl()) session = self.repository.extend_session(decoded_jwt['id'], expiry) if 'error' in session: if session['error'].CODE == 13: response.message = 'Unauthorizeed. Session expired' response.authorized = False else: response.message = "Error trying to verify session." response.error = { 'message': repr(session['error']), 'stackTrace': traceback.format_exc() } return response if session == 'NOP': return response response.data = session response.message = 'Successfully extended session.' response.authorized = True return response def verify_user(self, username, pw, jwt=None): result = self.repository.get_user_info(username) response = Response(None, 'Operation not built yet.', None, None) if 'error' in result: response.error = result['error'] response.message = 'Could not find user.' return response if result == 'NOP': return response #no password when using JWT, if user is found, consider valid if jwt: response.data = result['user_info'] response.message = 'JWT - no password verification needed.' return response if bcrypt.checkpw(pw, str.encode(result['user_info']['password'])): response.data = result['user_info'] response.message = 'Password verified.' return response def create_user(self, req): pw = bcrypt.hashpw(req['password'], bcrypt.gensalt()) self.repository.create_user(req['username'], pw.decode())