def test_users_delete(self): """Test to delete a user""" with app.app_context(): User.create('todelete', '*****@*****.**', 'password') db.session.commit() status, data = self.delete('{}/{}'.format(USERS_URL, 'todelete')) self.assertEqual(status, 204)
def create_user(username, email_addr, password, **kwargs): try: User.create(username, email_addr, password) except ValueError as e: print(e, file=sys.stderr) sys.exit(1) db.session.commit() print('User {} created'.format(username))
def post(self): """ Get a JWT / refresh token pair """ args = token_create_parser.parse_args() claimed_user = User.from_db_basic(args.username, args.password) if not claimed_user: api.abort(401, "Invalid username/password.") #if claimed_user.tokens: # if claimed_user.tokens[1].has_expired() is False: # api.abort(403, "{} already has an access token. Refresh the token instead.".format(args.username)) access_token, refresh_token = TokenModel.create_pair(claimed_user) db.session.commit() tokens = { "access_token": { "value": access_token.value }, "refresh_token": { "value": refresh_token.value, "expiration_time": datetime.timestamp(refresh_token.expiration_date) } } return tokens, 200
def patch(self, username): """ Modify a specific user """ user = User.from_db(username) if not user: api.abort(404, 'No such user') args = user_modify_parser.parse_args() try: user.modify(args.changes) except json.decoder.JSONDecodeError: api.abort(400, "Badly formatted JSON") except TypeError: api.abort( 400, "A JSON list following the JSON patch format is expected") except (jsonpatch.InvalidJsonPatch, JsonPointerException) as e: api.abort( 400, "Invalid JSON patch format. More information: {}".format(e)) except jsonpatch.JsonPatchConflict as e: api.abort( 409, "Conflict in the set of changes. More information: {}".format( e)) except ValueError as e: api.abort( 400, "Invalid value(s) in the set of changes. More information: {}". format(e)) db.session.commit() return user, 200
def get(self, username): args = get_stats_parser.parse_args() user = User.from_db(username) if not user: api.abort(404, 'No such user') if not get_current_user().has_right( 'stats.get') and get_current_user().name != username: api.abort( 403, 'You don\'t have the proper right or try to access the stats of someone else' ) try: start = datetime.fromtimestamp(int( args.start)) if args.start else datetime.fromtimestamp(0) end = datetime.fromtimestamp(int( args.end)) if args.end else datetime.fromtimestamp(2147483647) except ValueError: api.abort(400, "Invalid value, a timestamp in seconds is expected") from kovaak_stats.models.stat import Stat if args.scenarii: stats = Stat.query.filter_by(user_id=user.id).filter( Stat.scenario.in_(args.scenarii), Stat.creation_date >= start, Stat.creation_date <= end).order_by(Stat.execution_date).all() else: stats = Stat.query.filter_by(user_id=user.id).filter( Stat.creation_date >= start, Stat.creation_date <= end).order_by(Stat.execution_date).all() return format_users_stats(stats), 200
def get(self, username): """ Get a user's rights """ user = User.from_db(username) if not user: api.abort(404, 'No such user') return user, 200
def get(self, username): """ Get a specific user """ user = User.from_db(username) if not user: api.abort(404, 'No such user') return user, 200
def request_loader(request): auth = request.headers.get('Authorization') if not auth: return None method, token = auth.split(' ') try: if method == 'Basic': return User.from_basic_auth(token) elif method == 'Bearer': return User.from_bearer_auth(token) else: abort(400) except AuthenticationError: abort(401) return None
def delete(self, username): """ Delete a specific user """ user = User.from_db(username) if not user: api.abort(404, 'No such user') user.delete() db.session.commit() return '', 204
def post(self): """ Get a google token pair """ args = google_tokens_parser.parse_args() client_id = current_app.config.get('GOOGLE_CLIENT_ID') client_secret = current_app.config.get('GOOGLE_CLIENT_SECRET') auth_code = args.auth try: credentials = client.credentials_from_code(client_id, client_secret, scope='', code=auth_code) except client.FlowExchangeError as e: api.abort(400, e) r = requests.get('{}?access_token={}'.format(fetch_info_url, credentials.access_token)) content = json.loads(r.content.decode('utf-8')) user = User.from_db_by_email(content['email']) if not user: try: user = User.create_google(content['email']) except ValueError as e: api.abort( 400, 'Cannot create the user. More information: {}'.format(e)) TokenModel.create_pair(user, raw_access={ 'type': 'access-google', 'value': credentials.access_token, 'expiration_date': credentials.token_expiry }, raw_refresh={ 'type': 'refresh-google', 'value': credentials.refresh_token }) db.session.commit() return { 'name': user.name, 'access_token': credentials.access_token, 'rights': user.rights }, 200
def tearDown(self): # Delete our test user with self.app.app_context(): if os.path.isfile('./tests/app.conf'): self.app.config.from_pyfile('../tests/app.conf') user = User.from_db(self.app.config.get('TEST_USER')) if user: user.delete() db.session.remove() db.drop_all()
def post(self, username): args = password_recovery_parser.parse_args() user = User.from_db(username) if not user: api.abort(404, 'No such user') from kovaak_stats.models.recovery_code import RecoveryCode provided_code = RecoveryCode.from_db(args.recovery_code, user.id) if not provided_code or provided_code.has_expired(): api.abort(403, "The recovery code is incorrect or has expired") user.hashed_pw = hash_pw(args.new_password).decode('utf-8') db.session.commit() return '', 204
def post(self): """ Create a new user """ args = user_create_parser.parse_args() try: user = User.create(args.username, args.email_addr, args.password) except ValueError as e: api.abort(400, 'Cannot create the user. More information: {}'.format(e)) db.session.commit() return user, 200
def test_users_full_password_change_with_code_renewing(self): """Test to change the password of the test user after the 1st code has expired""" with app.app_context(): self.get('{}/{}/{}'.format(USERS_URL, self.app.config.get('TEST_USER'), 'recover')) user = User.from_db(self.app.config.get('TEST_USER')) delta = datetime.timedelta( minutes=self.app.config.get('RECOVERY_CODE_DURATION')) user.recovery_code.expiration_date = user.recovery_code.expiration_date - delta db.session.commit() self.get('{}/{}/{}'.format(USERS_URL, self.app.config.get('TEST_USER'), 'recover')) user = User.from_db(self.app.config.get('TEST_USER')) code = user.recovery_code.value status, data = self.post( '{}/{}/{}'.format(USERS_URL, self.app.config.get('TEST_USER'), 'recover'), { 'recovery_code': code, 'new_password': '******' }) self.assertEqual(status, 204)
def test_users_full_password_change(self): """Test to change the password of the test user""" with self.app.app_context(): status, data = self.get('{}/{}/{}'.format( USERS_URL, self.app.config.get('TEST_USER'), 'recover')) user = User.from_db(self.app.config.get('TEST_USER')) code = user.recovery_code.value self.assertEqual(status, 204) status, data = self.post( '{}/{}/{}'.format(USERS_URL, self.app.config.get('TEST_USER'), 'recover'), { 'recovery_code': code, 'new_password': '******' }) self.assertEqual(status, 204)
def post(self, username): """ Add one or multiple rights to a user """ args = right_add_parser.parse_args() user = User.from_db(username) if not user: api.abort(404, 'No such user') try: for right_name in args.rights: user.add_right_from_string(right_name) except ValueError as e: api.abort(400, e) db.session.commit() return '', 204
def delete(self, username, right_name): """ Delete a right from a user """ user = User.from_db(username) if not user: api.abort(404, 'No such user') from kovaak_stats.models.right import Right if not Right.exists(right_name): api.abort(404, 'No such right') try: user.del_right_from_string(right_name) except ValueError as e: api.abort(400, e) db.session.commit() return '', 204
def get(self, username): user = User.from_db(username) if not user: api.abort(404, 'No such user') code = user.gen_recovery_code() if not code: api.abort(409, 'A code has already been sent in the last 10 minutes') if send_email( '*****@*****.**', user.email_addr, 'Recovery code kovaak stats viewer', 'The code to change your kovaak stats viewer password is {}'. format(code)) is False: user.recovery_code.delete() db.session.commit() api.abort(400, 'Couldn\'t send an email with the code') return '', 204
def test_users_change_password_expired_code(self): """Test to change the password of the test user but provide an expired code""" with self.app.app_context(): self.get('{}/{}/{}'.format(USERS_URL, self.app.config.get('TEST_USER'), 'recover')) user = User.from_db(self.app.config.get('TEST_USER')) code = user.recovery_code.value delta = datetime.timedelta( minutes=self.app.config.get('RECOVERY_CODE_DURATION')) user.recovery_code.expiration_date = user.recovery_code.expiration_date - delta db.session.commit() status, data = self.post( '{}/{}/{}'.format(USERS_URL, self.app.config.get('TEST_USER'), 'recover'), { 'recovery_code': code, 'new_password': '******' }) self.assertEqual(status, 403)
def create(cls, token_type, username=None, raw_token=None): if token_type not in TOKEN_TYPES: return None token = cls() if raw_token: if 'expiration_date' in raw_token: token = cls(value=raw_token['value'], type=token_type, expiration_date=raw_token['expiration_date']) else: token = cls(value=raw_token['value'], type=token_type) db.session.add(token) return token if token_type == 'refresh': token.value = secrets.token_urlsafe(40) exp = datetime.datetime.now() + datetime.timedelta( days=current_app.config.get('REFRESH_TOKEN_DURATION')) token.expiration_date = exp token.type = token_type elif token_type == 'jwt': from kovaak_stats.models.user import User user = User.from_db(username) rightlist = list(map(lambda x: x.name, user.rights)) payload = { 'sub': username, 'rights': rightlist, 'iat': datetime.datetime.now(), 'exp': datetime.datetime.now() + datetime.timedelta( minutes=int(current_app.config.get('JWT_DURATION'))) } token.value = jwt.encode( payload, current_app.config.get('JWT_SECRET')).decode('unicode_escape') exp = datetime.datetime.now() + datetime.timedelta( minutes=current_app.config.get('JWT_DURATION')) token.expiration_date = exp token.type = token_type db.session.add(token) return token
def setUp(self): self.app = app with self.app.app_context(): db.drop_all() db.create_all() if os.path.isfile('./tests/app.conf'): self.app.config.from_pyfile('../tests/app.conf') # Create our test user user = User.create(self.app.config.get('TEST_USER'), self.app.config.get('TEST_USERS_EMAIL'), self.app.config.get('TEST_USERS_PASSWORD')) for right_name in rights: user.rights.append(Right.create(right_name)) db.session.add(user) self._basic = b64encode('{0}:{1}'.format( self.app.config.get('TEST_USER'), self.app.config.get('TEST_USERS_PASSWORD')).encode( 'utf8')).decode('utf8') g.current_user = None db.session.commit()
def test_auth_refresh_with_expired_token(self): """Test to refresh an access token with an expired refresh token""" with self.app.app_context(): status, data = self.post( '{}/{}'.format(AUTH_URL, 'token-pair'), { 'username': self.app.config.get('TEST_USER'), 'password': self.app.config.get('TEST_USERS_PASSWORD') }) access_token = data['access_token']['value'] refresh_token = data['refresh_token']['value'] user = User.from_db(self.app.config.get('TEST_USER')) delta = datetime.timedelta( days=self.app.config.get('REFRESH_TOKEN_DURATION')) user.tokens[ 1].expiration_date = user.tokens[1].expiration_date - delta db.session.commit() status, data = self.post( '{}/{}/{}'.format(AUTH_URL, access_token, 'refresh'), {'refresh_token': refresh_token}) self.assertEqual(status, 403)
def post(self, username): args = upload_parser.parse_args() user = User.from_db(username) if not user: api.abort(404, 'No such user') if not get_current_user().has_right( 'stats.upload') and get_current_user().name != username: api.abort( 403, 'You don\'t have the proper right or try to upload some stats to someone else\'s account' ) from kovaak_stats.models.stat import Stat for file in args.files: try: Stat.create(file, user) except ValueError as e: if args.silent_fail is None: api.abort(400, e) except IndexError as e: if args.silent_fail is None: api.abort(400, 'Wrong file format') db.session.commit() return '', 204
def test_auth_create_pair_create_after_expired(self): """Test to create a second token pair after the first one has expired""" with self.app.app_context(): status, data = self.post( '{}/{}'.format(AUTH_URL, 'token-pair'), { 'username': self.app.config.get('TEST_USER'), 'password': self.app.config.get('TEST_USERS_PASSWORD') }) self.assertEqual(status, 200) user = User.from_db(self.app.config.get('TEST_USER')) delta = datetime.timedelta( days=self.app.config.get('REFRESH_TOKEN_DURATION')) user.tokens[ 1].expiration_date = user.tokens[1].expiration_date - delta db.session.commit() status, data = self.post( '{}/{}'.format(AUTH_URL, 'token-pair'), { 'username': self.app.config.get('TEST_USER'), 'password': self.app.config.get('TEST_USERS_PASSWORD') }) self.assertEqual(status, 200)
def check_user(username): user = User.from_db(username) if not user: print('User {} doesn\'t exist'.format(username), file=sys.stderr) sys.exit(1) return user
def load_user(user_id): return User.from_db(user_id)
def specific_user_del(user, **kwargs): User.delete(user) db.session.commit() print('User {} has been deleted'.format(user.name))