def add_score(self, request): """ Scores increasing handler. --- Increments (or decrements) the score of a user Parameters: - request: The HTTP request received in the REST endpoint. Returns: A tuple with the following values: - (200, 'OK') when the score was successfully updated. - (401, 'Unauthorized') when the user cannot update the scores. """ token = request.form['token'] games_won_delta = int( request.form['games_won']) if 'games_won' in request.form else None games_lost_delta = int(request.form['games_lost'] ) if 'games_lost' in request.form else None score_delta = int( request.form['score']) if 'score' in request.form else None db_session = SchemaManager.session() user_sessions_rs = UserSessions(db_session) if (not user_sessions_rs.token_is_valid(token)): return (401, 'Unauthorized') user_session = user_sessions_rs.get_session(token) user_scores_rs = UserScores(db_session) user_scores_rs.add_user_score(user_session.username, games_won_delta, games_lost_delta, score_delta) return (200, 'OK')
def create_user(self, request): """ User creation handler. --- Performs the user creation operation, generating a new user in the database. Parameters: - request: The HTTP request received in the REST endpoint. Returns: A tuple with the following values: - (200, 'OK') on a successful creation. - (500, 'Server error') on a failed creation. """ username = request.form['username'] password = request.form['password'] db_session = SchemaManager.session() users_rs = Users(db_session) try: new_user = users_rs.create(username, password) if (new_user is None): raise except: return (500, 'Server error') return (200, 'OK')
class UserScore(Manager.declarative_base()): """ Entity class mapped to a persisted user score. --- This class is responsible of mapping a single user scores database record to the application model. """ __tablename__ = 'user_scores' username = Column(String(32), ForeignKey('users.username'), primary_key=True) games_won = Column(Integer, default=0, nullable=False) games_lost = Column(Integer, default=0, nullable=False) score = Column(Integer, default=0, nullable=False) def __init__(self, username, games_won=None, games_lost=None, score=None): """ Constructor method. --- Parameters: - username: The user username. Must be unique in the database. A string of 32 characters at most. - games_won: The number of games this user has won. Optional. Defaults to 0 - games_lost: The number of games this user has lost. Optional. Defaults to 0 - score: The score of this user. Optional. Defaults to 0 """ self.username = username if (games_won is not None): self.games_won = games_won if (games_lost is not None): self.games_lost = games_lost if (score is not None): self.score = score
def user_info(self, request): """ User info handler. --- Retrieves information about the current user or the user with a given username. Parameters: - request: The HTTP request received in the REST endpoint. Returns: A tuple with the following values: - (200, 'OK') returns a valid user info object. - (401, 'Unauthorized') when the provided token is not valid. - (404, 'Not Found') when the provided username does not exist. """ username_validated = False db_session = SchemaManager.session() username = request.form.get('username') if username is None: username = request.args.get('username') if username is None: token = request.form.get('token') if token is None: token = request.args.get('token') user_sessions_rs = UserSessions(db_session) session = user_sessions_rs.get_session(token) if (session is None): return (401, 'Unauthorized') username = session.username username_validated = True users_rs = Users(db_session) if not username_validated and not users_rs.username_exists(username): return (404, 'Not Found') user_scores_rs = UserScores(db_session) user_score_record = user_scores_rs.get_user_score(username) return (200, json.dumps({ 'username': username, 'games_won': user_score_record.games_won, 'games_lost': user_score_record.games_lost, 'score': user_score_record.score }))
def add_score(self, request): """ Scores increasing handler. --- Increments (or decrements) the score of a user Parameters: - request: The HTTP request received in the REST endpoint. Returns: A tuple with the following values: - (200, 'OK') when the score was successfully updated. - (400, 'Missing {parameter}') when at least one of the required parameters is not given. - (401, 'Unauthorized') when the user cannot update the scores. - (404, 'Not Found') when the username doesn't correspond to any existing users. """ username = request.form.get('username') if username is None: return (400, 'Missing username') secret_code = request.form.get('secret_code') if secret_code is None: return (400, 'Missing secret_code') won = request.form.get('won') if won is None: return (400, 'Missing won') won = won == str(True) if not secret_code == '_super_secret_code_that_cant_be_intercepted_with_wireshark_or_reading_the_source_code_': return (401, 'Unauthorized') score_delta = request.form.get('score') try: score_delta = int(score_delta) except ValueError as ex: return (400, 'Invalid score') db_session = SchemaManager.session() users_rs = Users(db_session) if (not users_rs.username_exists(username)): return (404, 'Not Found') UserScores(db_session).add_user_score(username, 1 if won else None, None if won else 1, score_delta) return (200, 'OK')
def check_token(self, request): """ Token checking handler. --- Checks the validity of an authentication token. Parameters: - request: The HTTP request received in the REST endpoint. Returns: A tuple with the following values: - (200, 'OK') when the provided token is valid. - (401, 'Unauthorized') for an incorrect token. """ token = request.form['token'] db_session = SchemaManager.session() user_sessions_rs = UserSessions(db_session) if (not user_sessions_rs.token_is_valid(token)): return (401, 'Unauthorized') return (200, 'OK')
class UserSession(Manager.declarative_base()): """ Entity class mapped to a persisted user session. --- This class is responsible of mapping a single user session database record to the application model. """ __tablename__ = 'user_sessions' token = Column(String(36), primary_key=True) username = Column(String(32), ForeignKey('users.username'), nullable=False) def __init__(self, username, token): """ Constructor method. --- Parameters: - username: The user username. A string of 32 characters at most. - token: The user token. Must be unique in the table. A string of 36 characters at most. """ self.username = username self.token = token
class User(Manager.declarative_base()): """ Entity class mapped to a persisted user. --- This class is responsible of mapping a single user database record to the application model. """ __tablename__ = 'users' username = Column(String(32), primary_key=True) password = Column(String(64), nullable=False) def __init__(self, username, password): """ Constructor method. --- Parameters: - username: The user username. Must be unique in the database. A string of 32 characters at most. - password: The user password. This string will be stored as-is (it is expected to be already hashed or encrypted). A string of 64 characters at most. """ self.username = username self.password = password
def list_scores(self, request): """ Scores listing handler. --- Retrieves a list of scores. Parameters: - request: The HTTP request received in the REST endpoint. Returns: A tuple with the following values: - (200, list of score records) when the list was successfully retrieved. """ db_session = SchemaManager.session() user_scores_rs = UserScores(db_session) user_score_records = user_scores_rs.get_all_user_scores() out = [] for user_score_record in user_score_records: out.append({ 'username': user_score_record.username, 'games_won': user_score_record.games_won, 'games_lost': user_score_record.games_lost, 'score': user_score_record.score }) return (200, json.dumps(out))
def login_user(self, request): """ User login handler. --- Performs the user login operation, generating a new token to be used in future operations. Parameters: - request: The HTTP request received in the REST endpoint. Returns: A tuple with the following values: - (200, authentication token) on a successful login. - (401, 'Unauthorized') on a failed login. """ username = request.form['username'] password = request.form['password'] db_session = SchemaManager.session() users_rs = Users(db_session) if (not users_rs.user_is_valid(username, password)): return (401, 'Unauthorized') user_sessions_rs = UserSessions(db_session) user_session = user_sessions_rs.create(username) return (200, user_session.token)
def __init__(self): SchemaManager.create_schema()