def set_user_offline(cls, user_data): user = Authenticator.authenticate(user_data) user.online = False UserDatabaseClient.update_user(user) DatabaseClient.commit() cls.logger().info(f"User #{user.id} set offline.") return SuccessfulUserResponse(user)
def _login_app_user(cls, user_data): user = UserDatabaseClient.get_user_by_email(user_data.email) if user: try: if hashing.verify(user_data.password, user.password): cls.logger().debug(f"Generating token for user {user.id}") user.token = Authenticator.generate( user.id, user_data.password) user.online = True UserDatabaseClient.update_user(user) DatabaseClient.commit() cls.logger().info(f"User #{user.id} logged in") headers = {"auth_token": user.token} return SuccessfulUserResponse(user, headers) else: cls.logger().info( f"Wrong credentials while attempting to log in user #{user_data.email}" ) return SuccessfulUserMessageResponse( "Wrong email or password.", UserResponseStatus.WRONG_CREDENTIALS.value) except ValueError: cls.logger().info( f"Wrong credentials while attempting to log in user #{user_data.email}" ) return SuccessfulUserMessageResponse( "Wrong email or password.", UserResponseStatus.WRONG_CREDENTIALS.value) else: cls.logger().info(f"User #{user_data.email} not found.") raise UserNotFoundError("User not found.", UserResponseStatus.USER_NOT_FOUND.value)
def logout_user(cls, user_data): user = Authenticator.authenticate(user_data) user.token = None user.online = False UserDatabaseClient.update_user(user) DatabaseClient.commit() cls.logger().info(f"User #{user.id} logged out.") return SuccessfulUserMessageResponse( "User logged out.", UserResponseStatus.LOGGED_OUT.value)
def create_channel(cls, creation_data): user = Authenticator.authenticate_team(creation_data.authentication) try: new_client = UserDatabaseClient.add_client() new_channel = Channel( channel_id=new_client.id, team_id=user.team_id, creator=user.id, name=creation_data.name, visibility=creation_data.visibility, description=creation_data.description, welcome_message=creation_data.welcome_message ) ChannelDatabaseClient.add_channel(new_channel) new_channel_user = ChannelUser(user_id=user.id, channel_id=new_channel.channel_id) ChannelDatabaseClient.add_channel_user(new_channel_user) new_chat = Chat(user_id=user.id, chat_id=new_channel.channel_id, team_id=new_channel.team_id) MessageDatabaseClient.add_chat(new_chat) DatabaseClient.commit() channel = ChannelDatabaseClient.get_channel_by_id(new_channel.channel_id) cls.logger().info(f"Channel #{new_channel.channel_id} created in team {new_channel.team_id}.") cls.logger().info(f"User #{user.id} assigned as channel #{new_channel.channel_id} creator.") except IntegrityError: DatabaseClient.rollback() if ChannelDatabaseClient.get_channel_by_name(creation_data.name) is not None: cls.logger().info(f"Failing to create channel {creation_data.name}. Name already in use.") return BadRequestChannelMessageResponse(f"Channel name {creation_data.name} already in use.", TeamResponseStatus.ALREADY_REGISTERED.value) else: cls.logger().error(f"Failing to create channel {creation_data.name}.") return UnsuccessfulChannelMessageResponse("Couldn't create channel.") else: return SuccessfulChannelResponse(channel, TeamResponseStatus.CREATED.value)
def notify_change_role(cls, user_team, old_role, admin_id): admin = UserDatabaseClient.get_user_by_id(admin_id) team = TeamDatabaseClient.get_team_by_id(user_team.team_id) new_role = user_team.role condition = "upgraded" if TeamRoles.is_higher_role( new_role, old_role) else "downgraded" message_body = f"You have been {condition} in team {team.name}!" data = { "notification_type": NotificationType.TEAM_ROLE_CHANGE.value, "team_name": team.name, "admin_id": admin.id } try: cls.logger().debug( f"Sending notification to topic {user_team.user_id}, with title \"{cls.APP_NAME}\" " f"and body \"{message_body}\"") response = cls.push_service.notify_topic_subscribers( topic_name=user_team.user_id, message_title=cls.APP_NAME, message_body=message_body, data_message=data) failures = response.get("failure") if failures > 0: cls.logger().error( f"There's been detected {failures} failures sending user #{user_team.user_id} new " f"role notifications to Firebase.") else: cls.logger().info( f"New role notified to user #{user_team.user_id}.") except ConnectionError: cls.logger().error("Couldn't connect to Firebase server.")
def create_bot(cls, bot_data): admin = Authenticator.authenticate_team(bot_data.authentication, UserRoles.is_admin) try: new_client = UserDatabaseClient.add_client() new_bot = Bot( bot_id=new_client.id, name=bot_data.name, callback=bot_data.callback, token=Authenticator.generate(new_client.id) ) BotDatabaseClient.add_bot(new_bot) team_bot = TeamUser( user_id=new_client.id, team_id=admin.team_id, role=TeamRoles.BOT.value ) TeamDatabaseClient.add_team_user(team_bot) DatabaseClient.commit() cls.logger().info(f"Bot #{new_bot.id} created in team {admin.team_id} with callback url {new_bot.callback} " f"by admin {admin.id}.") return SuccessfulUserMessageResponse("Bot created.", UserResponseStatus.OK.value) except IntegrityError as exc: DatabaseClient.rollback() if BotDatabaseClient.get_bot_by_name(bot_data.name) is not None: cls.logger().info(f"Failing to create bot {bot_data.name}. Name already in use.", exc) return BadRequestUserMessageResponse("Name already in use for other bot.", UserResponseStatus.ALREADY_REGISTERED.value) else: cls.logger().info(f"Failing to create bot {bot_data.name}.") return UnsuccessfulClientResponse("Couldn't create bot.")
def create_user(cls, user_data): if UserDatabaseClient.get_user_by_username( user_data.username) is not None: cls.logger().info( f"Failing to create user #{user_data.username}. Username already in use." ) return BadRequestUserMessageResponse( "Username already in use for other user.", UserResponseStatus.ALREADY_REGISTERED.value) try: new_client = UserDatabaseClient.add_client() new_user = User(user_id=new_client.id, username=user_data.username, email=user_data.email, password=hashing.hash(user_data.password), first_name=user_data.first_name, last_name=user_data.last_name, profile_pic=user_data.profile_pic, role=user_data.role or UserRoles.USER.value, token=Authenticator.generate( new_client.id, user_data.password)) UserDatabaseClient.add_user(new_user) DatabaseClient.commit() cls.logger().info(f"User #{new_client.id} created.") headers = {"auth_token": new_user.token} return SuccessfulUserResponse(new_user, headers) except IntegrityError as exc: DatabaseClient.rollback() if UserDatabaseClient.get_user_by_email( user_data.email) is not None: cls.logger().info( f"Failing to create user {user_data.username}. Email already in use.", exc) return BadRequestUserMessageResponse( "Email already in use for other user.", UserResponseStatus.ALREADY_REGISTERED.value) else: cls.logger().info( f"Failing to create user #{user_data.username}.") return UnsuccessfulClientResponse("Couldn't create user.") except: DatabaseClient.rollback() cls.logger().info(f"Failing to create user #{user_data.username}.") return UnsuccessfulClientResponse("Couldn't create user.")
def update_user(cls, update_data): user = Authenticator.authenticate(update_data) user.username = \ update_data.updated_user["username"] if "username" in update_data.updated_user else user.username user.email = \ update_data.updated_user["email"] if "email" in update_data.updated_user else user.email user.password = \ hashing.hash( update_data.updated_user["password"]) if "password" in update_data.updated_user else user.password user.first_name = \ update_data.updated_user["first_name"] if "first_name" in update_data.updated_user else user.first_name user.last_name = \ update_data.updated_user["last_name"] if "last_name" in update_data.updated_user else user.last_name user.profile_pic = \ update_data.updated_user["profile_pic"] if "profile_pic" in update_data.updated_user else user.profile_pic try: UserDatabaseClient.update_user(user) DatabaseClient.commit() cls.logger().info(f"User {user.id} information updated.") return SuccessfulUserResponse(user) except IntegrityError: DatabaseClient.rollback() new_username = update_data.updated_user.get("username") new_email = update_data.updated_user.get("email") if UserDatabaseClient.get_user_by_username( new_username) is not None: cls.logger().info( f"Name {new_email} is taken for another user.") return BadRequestUserMessageResponse( f"Name {new_username} is already in use!", UserResponseStatus.ALREADY_REGISTERED.value) elif UserDatabaseClient.get_user_by_email(new_email) is not None: cls.logger().info( f"Email {new_email} is taken for another user.") return BadRequestUserMessageResponse( f"Email {new_email} is already in use!", UserResponseStatus.ALREADY_REGISTERED.value) else: cls.logger().error( f"Couldn't update user {user.id} information.") return UnsuccessfulClientResponse( "Couldn't update user information!")
def add_user(cls, add_data): admin = Authenticator.authenticate(add_data.authentication, UserRoles.is_admin) user = UserDatabaseClient.get_user_by_id(add_data.add_user_id) if user is None: cls.logger().info(f"User {add_data.add_user_id} not found.") raise UserNotFoundError("User not found.", UserResponseStatus.USER_NOT_FOUND.value) if user.role == UserRoles.ADMIN.value: cls.logger().warning( f"Admin #{admin.id} trying to add other admin to a team.") return BadRequestTeamMessageResponse( "You cannot add an admin to a team!", TeamResponseStatus.ROLE_UNAVAILABLE.value) if TeamDatabaseClient.get_user_in_team_by_ids( user.id, add_data.authentication.team_id) is not None: cls.logger().info( f"User {add_data.add_user_id} already part of team #{add_data.authentication.team_id}." ) return BadRequestTeamMessageResponse( "This user already belongs to the team.", TeamResponseStatus.ALREADY_REGISTERED.value) previous_invitation = TeamDatabaseClient.get_team_invite( add_data.authentication.team_id, user.email) if previous_invitation is not None: cls.logger().info( f"Deleting old invitation for user {add_data.add_user_id} to team " f"#{add_data.authentication.team_id}.") TeamDatabaseClient.delete_invite(previous_invitation) DatabaseClient.commit() added_user = TeamUser(user_id=add_data.add_user_id, team_id=add_data.authentication.team_id) try: TeamDatabaseClient.add_team_user(added_user) DatabaseClient.commit() BotService.tito_welcome(added_user.user_id, added_user.team_id) cls.logger().info( f"Added user #{added_user.user_id} to team #{added_user.team_id} by admin #{admin.id}." ) return SuccessfulTeamMessageResponse( "User added.", TeamResponseStatus.ADDED.value) except IntegrityError: DatabaseClient.rollback() cls.logger().error( f"Couldn't add user #{added_user.user_id} to team #{added_user.team_id}." ) return UnsuccessfulTeamMessageResponse( "Couldn't invite user to team.")
def team_user_profile(cls, user_id, team_id, admin_search=False): profile = UserDatabaseClient.get_user_profile(user_id) cls.logger().info(f"Retrieved user #{user_id} profile.") output_profile = cls._generate_user_profile(profile) if admin_search or any( list( map(lambda team: team.get("id") == team_id, output_profile.get("teams")))): return SuccessfulFullUserResponse(output_profile)
def notify_team_invitation(cls, invitation, inviter_id): inviter_user = UserDatabaseClient.get_user_by_id(inviter_id) invited_user = UserDatabaseClient.get_user_by_email(invitation.email) team = TeamDatabaseClient.get_team_by_id(invitation.team_id) if invited_user is not None: message_body = "You have been invited to join a team!" data = { "notification_type": NotificationType.TEAM_INVITATION.value, "team_name": team.name, "inviter_id": inviter_user.id, "invitation_token": invitation.token } try: cls.logger().debug( f"Sending notification to topic {invited_user.id}, with title \"{cls.APP_NAME}\" " f"and body \"{message_body}\"") response = cls.push_service.notify_topic_subscribers( topic_name=invited_user.id, message_title=cls.APP_NAME, message_body=message_body, data_message=data) failures = response.get("failure") if failures > 0: cls.logger().error( f"There's been detected {failures} failures sending user #{invited_user.id}'s " f"team invite notification to Firebase.") else: cls.logger().info( f"Team invite notified to user #{invited_user.id}.") except ConnectionError: cls.logger().error("Couldn't connect to Firebase server.") else: cls.logger().info( f"The invited user is not already registered so it cannot receive a notification." )
def send_message(cls, inbox_data): user = Authenticator.authenticate_team(inbox_data.authentication) if user.id == inbox_data.chat_id: raise WrongActionError("You cannot send a message to yourself!", MessageResponseStatus.ERROR.value) receiver = cls._determinate_message_receiver(inbox_data.chat_id, user.team_id) if receiver is None or receiver.team_id != user.team_id: cls.logger().info(f"Trying to send a message to client #{inbox_data.chat_id} who's not part of team " f"{user.team_id}.") return BadRequestMessageSentResponse("The receiver it's not part of this team!", TeamResponseStatus.USER_NOT_MEMBER.value) new_message = Message( sender_id=user.id, receiver_id=inbox_data.chat_id, team_id=user.team_id, content=inbox_data.content, send_type=SendMessageType.DIRECT.value if receiver.is_user else SendMessageType.CHANNEL.value, message_type=inbox_data.message_type ) chat_sender, chat_receivers = cls._increase_chats_offset(user.id, inbox_data.chat_id, user.team_id, receiver.is_user) try: new_message = MessageDatabaseClient.add_message(new_message) if inbox_data.mentions is not None: MentionService.save_mentions(new_message, inbox_data.mentions) MessageDatabaseClient.add_or_update_chat(chat_sender) for chat_receiver in chat_receivers: MessageDatabaseClient.add_or_update_chat(chat_receiver) DatabaseClient.commit() NotificationService.notify_message(new_message, receiver.is_user) cls.logger().info(f"Message sent from user #{new_message.sender_id} to client #{new_message.receiver_id}.") except IntegrityError: DatabaseClient.rollback() if UserDatabaseClient.get_client_by_id(inbox_data.chat_id) is None: cls.logger().error(f"User #{new_message.sender_id} trying to sent a message to an nonexistent user.") raise UserNotFoundError("User not found.", UserResponseStatus.USER_NOT_FOUND.value) else: cls.logger().error(f"Failing to send message from user #{new_message.sender_id} to client" f" #{inbox_data.chat_id}.") return UnsuccessfulMessageSentResponse("Couldn't sent message.") except FlushError: cls.logger().error( f"Failing to send message from user #{new_message.sender_id} to client #{inbox_data.chat_id} " f"due to DB problems.") return UnsuccessfulMessageSentResponse("Couldn't sent message.") else: return SuccessfulMessageSentResponse("Message sent")
def recover_password(cls, recover_data): user = UserDatabaseClient.get_user_by_email(recover_data.email) if user is not None: old_password_recovery = UserDatabaseClient.get_password_recovery_by_id( user.id) if old_password_recovery is not None: cls.logger().debug( f"It already exists a recovery token for user {user.username}. Resending token." ) recovery_token = old_password_recovery.token else: recovery_token = Authenticator.generate_recovery_token() cls.logger().debug("Generating recovery token") password_recovery = PasswordRecovery(user_id=user.id, token=recovery_token) UserDatabaseClient.add_password_recovery(password_recovery) DatabaseClient.commit() email_data = RecoveryPasswordEmailDTO( email=user.email, username=user.username, token=recovery_token, message_template=EmailService.recovery_token_message) EmailService.send_email(email_data) cls.logger().info( f"Sending recovery token email for user {user.username}.") return SuccessfulUserMessageResponse("Recovery token sent!", UserResponseStatus.OK.value) else: cls.logger().info(f"User {recover_data.email} not found.") raise UserNotFoundError("User not found.", UserResponseStatus.USER_NOT_FOUND.value)
def authenticate(cls, authentication, role_verifying=lambda _: True): logger = logging.getLogger(cls.__name__) try: payload = jwt.decode(authentication.token.encode(), cls._secret, algorithms='HS256') user = UserDatabaseClient.get_user_by_id(payload.get("user_id")) if user is not None: if role_verifying(user.role): if user.token == authentication.token: logger.info(f"User #{user.id} authenticated.") return user else: logger.info( f"Failing to authenticate user #{payload['user_id']}." ) raise WrongTokenError( "You must be logged to perform this action.", UserResponseStatus.WRONG_TOKEN.value) else: logger.info( f"User #{user.id} does not have permissions to perform this action." ) raise NoPermissionsError( "You don't have enough permissions to perform this action.", TeamResponseStatus.NOT_ENOUGH_PERMISSIONS.value) else: bot = BotDatabaseClient.get_bot_by_id(payload.get("user_id")) if bot is not None: logger.info(f"Bot #{bot.id} authenticated.") return bot else: logger.info(f"User not found.") raise UserNotFoundError( "User not found.", UserResponseStatus.USER_NOT_FOUND.value) except DecodeError: logger.info(f"Failing to authenticate user.") raise WrongTokenError("You must be logged to perform this action.", UserResponseStatus.WRONG_TOKEN.value)
def authenticate_channel(cls, authentication, channel_role_verifying=lambda _: True): logger = logging.getLogger(cls.__name__) try: user = cls.authenticate_team( authentication, lambda user: TeamRoles.is_team_moderator(user)) user.channel_id = authentication.channel_id user.is_channel_creator = False return user except NoPermissionsError: user = cls.authenticate_team(authentication) channel_user = UserDatabaseClient.get_channel_user_by_ids( user.id, authentication.channel_id) if channel_user is not None: if channel_role_verifying(channel_user.is_channel_creator): logger.info( f"User {user.username} authenticated as channel #{authentication.channel_id} creator." ) return channel_user else: raise NoPermissionsError( "You don't have enough permissions to perform this action.", TeamResponseStatus.NOT_ENOUGH_PERMISSIONS.value) else: channel = ChannelDatabaseClient.get_channel_by_id( authentication.channel_id) if channel is None: logger.info( f"Chanel #{authentication.channel_id} not found.") raise ChannelNotFoundError( "Channel not found.", ChannelResponseStatus.CHANNEL_NOT_FOUND.value) else: logger.info( f"User {user.username} trying to access channel #{channel.channel_id}, " f"when it's not part of it.") raise NoPermissionsError( "You're not part of this channel!", TeamResponseStatus.NOT_ENOUGH_PERMISSIONS.value)
def notify_mention(cls, message, mentioned_id): is_not_bot = BotDatabaseClient.get_bot_by_id(mentioned_id) is None if is_not_bot: team = TeamDatabaseClient.get_team_by_id(message.team_id) sender = UserDatabaseClient.get_user_by_id(message.sender_id) if sender is None: sender = BotDatabaseClient.get_bot_by_id(message.sender_id) message_body = "You have been mentioned!" data = { "notification_type": NotificationType.MENTION.value, "team_name": team.name, "sender_id": sender.id } channel = ChannelDatabaseClient.get_channel_by_id(mentioned_id) if channel is not None: data["channel_name"] = channel.name try: cls.logger().debug( f"Sending notification to topic {mentioned_id}, with title \"{cls.APP_NAME}\" " f"and body \"{message_body}\"") response = cls.push_service.notify_topic_subscribers( topic_name=mentioned_id, message_title=cls.APP_NAME, message_body=message_body, data_message=data) failures = response.get("failure") if failures > 0: cls.logger().error( f"There's been detected {failures} failures sending the mentions notification for " f"receiver #{message.receiver_id} to Firebase.") else: cls.logger().info( f"New mention notified to receiver #{message.receiver_id}." ) except ConnectionError: cls.logger().error("Couldn't connect to Firebase server.")
def authenticate_team(cls, authentication, role_verifying=lambda _: True): logger = logging.getLogger(cls.__name__) user = cls.authenticate(authentication) if user.role == UserRoles.ADMIN.value: user.user_role = user.role user.team_id = authentication.team_id user.team_role = user.role return user team_user = UserDatabaseClient.get_team_user_by_ids( user.id, authentication.team_id) if team_user is not None: if role_verifying(team_user.team_role): logger.info( f"Client #{team_user.id} authenticated as team #{team_user.team_id} {team_user.team_role}." ) return team_user else: logger.info( f"User #{user.id} does not have permissions to perform this action." ) raise NoPermissionsError( "You don't have enough permissions to perform this action.", TeamResponseStatus.NOT_ENOUGH_PERMISSIONS.value) else: team = TeamDatabaseClient.get_team_by_id(authentication.team_id) if team is None: logger.info(f"Team #{authentication.team_id} not found.") raise TeamNotFoundError("Team not found.", TeamResponseStatus.NOT_FOUND.value) else: logger.info( f"Client #{user.id} trying to access team #{team.id}, when it's not part of it." ) raise NoPermissionsError( "You're not part of this team!", TeamResponseStatus.NOT_ENOUGH_PERMISSIONS.value)
def add_member(cls, invitation_data): user = Authenticator.authenticate_channel(invitation_data.authentication, TeamRoles.is_channel_creator) invited_user = UserDatabaseClient.get_user_by_id(invitation_data.user_invited_id) if invited_user is None: cls.logger().info(f"Trying to add user an nonexistent user to channel #{user.channel_id}.") return BadRequestChannelMessageResponse("Invited user not found!", UserResponseStatus.USER_NOT_FOUND.value) invited_user_in_team = TeamDatabaseClient.get_user_in_team_by_ids(invited_user.id, user.team_id) if invited_user_in_team is None: cls.logger().info(f"Trying to add user {invited_user.id} to channel #{user.channel_id}, but it's not part " f"of the team #{user.team_id}.") return BadRequestChannelMessageResponse("User not part of the team!", TeamResponseStatus.USER_NOT_MEMBER.value) try: new_channel_user = ChannelUser(user_id=invited_user.id, channel_id=user.channel_id) ChannelDatabaseClient.add_channel_user(new_channel_user) new_chat = Chat(user_id=invited_user.id, chat_id=user.channel_id, team_id=user.team_id) MessageDatabaseClient.add_chat(new_chat) DatabaseClient.commit() NotificationService.notify_channel_invitation(new_channel_user, user.id) cls.logger().info(f"User #{invited_user.id} added to channel #{user.channel_id} by {user.username}.") except IntegrityError: DatabaseClient.rollback() already_member = ChannelDatabaseClient.get_user_in_channel_by_ids(invited_user.id, user.channel_id) if already_member is not None: cls.logger().info(f"Failing to add user #{invited_user.id} to channel #{user.channel_id}. " f"The user is already part of it.") return BadRequestChannelMessageResponse(f"User already registered in channel.", TeamResponseStatus.ALREADY_REGISTERED.value) else: cls.logger().error(f"Failing to add user #{invitation_data.user_invited_id} to channel" f"{invitation_data.authentication.channel_id}.") return UnsuccessfulChannelMessageResponse("Couldn't add user to channel.") else: return SuccessfulChannelMessageResponse("User added!", ChannelResponseStatus.ADDED.value)
def notify_channel_invitation(cls, user_channel, inviter_id): inviter_user = UserDatabaseClient.get_user_by_id(inviter_id) channel = ChannelDatabaseClient.get_channel_by_id( user_channel.channel_id) team = TeamDatabaseClient.get_team_by_id(channel.team_id) message_body = f"You have been added to channel {channel.name} in team {team.name}!" data = { "notification_type": NotificationType.CHANNEL_INVITATION.value, "channel_name": channel.name, "team_name": team.name, "inviter_id": inviter_user.id } try: cls.logger().debug( f"Sending notification to topic {user_channel.user_id}, with title \"{cls.APP_NAME}\" " f"and body \"{message_body}\"") response = cls.push_service.notify_topic_subscribers( topic_name=user_channel.user_id, message_title=cls.APP_NAME, message_body=message_body, data_message=data) failures = response.get("failure") if failures > 0: cls.logger().error( f"There's been detected {failures} failures sending user #{user_channel.user_id}'s " f"channel invite notification to Firebase.") else: cls.logger().info( f"Channel invitation notified to user #{user_channel.user_id}." ) except ConnectionError: cls.logger().error("Couldn't connect to Firebase server.")
def _login_facebook_user(cls, user_data): try: facebook_user = FacebookService.get_user_from_facebook(user_data) user = UserDatabaseClient.get_user_by_facebook_id( facebook_user.facebook_id) if user is not None: cls.logger().info( f"Logging in Facebook user with Facebook ID #{facebook_user.facebook_id}." ) cls.logger().debug(f"Generating token for user {user.id}") user.token = Authenticator.generate(user.id) user.online = True UserDatabaseClient.update_user(user) DatabaseClient.commit() cls.logger().info(f"User #{user.id} logged in.") headers = {"auth_token": user.token} return SuccessfulUserResponse(user, headers) else: cls.logger().info( f"Creating new Facebook user with Facebook ID #{facebook_user.facebook_id}." ) new_client = UserDatabaseClient.add_client() new_user = User(user_id=new_client.id, facebook_id=facebook_user.facebook_id, username=facebook_user.username, email=facebook_user.email, first_name=facebook_user.first_name, last_name=facebook_user.last_name, profile_pic=facebook_user.profile_pic, role=UserRoles.USER.value, token=Authenticator.generate(new_client.id)) UserDatabaseClient.add_user(new_user) DatabaseClient.commit() cls.logger().info(f"User #{new_client.id} logged in.") headers = {"auth_token": new_user.token} return SuccessfulUserResponse(new_user, headers) except FacebookWrongTokenError: cls.logger().info( f"Failing to logging in user with Facebook token #{user_data.facebook_token}." ) return UnsuccessfulClientResponse("Couldn't perform login.")
def regenerate_token(cls, regenerate_data): user = UserDatabaseClient.get_user_by_email(regenerate_data.email) if user: password_recovery = UserDatabaseClient.get_password_recovery_by_id( user.id) if password_recovery: try: UserDatabaseClient.delete_password_recovery( password_recovery) cls.logger().debug( f"Deleting token recover entry for user {user.id}") user.token = Authenticator.generate(user.id) cls.logger().debug( f"Regenerating token for user {user.id}") user.online = True UserDatabaseClient.update_user(user) DatabaseClient.commit() cls.logger().info(f"Logging in user {user.id}") headers = {"auth_token": user.token} return SuccessfulUserResponse(user, headers) except IntegrityError: DatabaseClient.rollback() cls.logger().error( f"Couldn't regenerate token for user #{user.id}.") return UnsuccessfulClientResponse( "Couldn't regenerate token.") else: cls.logger().info( f"Attempting to recover password for user #{user.id} with no password recovery token." ) return BadRequestUserMessageResponse( "You haven't ask for password recovery!", UserResponseStatus.WRONG_CREDENTIALS.value) else: cls.logger().info(f"User {regenerate_data.email} not found.") raise UserNotFoundError("User not found.", UserResponseStatus.USER_NOT_FOUND.value)
def user_profile(cls, user_data): user = Authenticator.authenticate(user_data) profile = UserDatabaseClient.get_user_profile(user.id) cls.logger().info(f"Retrieved user #{user.id} profile.") return SuccessfulFullUserResponse(cls._generate_user_profile(profile))
def get_all_users(cls, user_data): admin = Authenticator.authenticate(user_data, UserRoles.is_admin) users = UserDatabaseClient.get_all_users() cls.logger().info(f"Admin {admin.id} retrieved {len(users)} users.") return SuccessfulUsersListResponse( list(map(lambda user: user.__dict__, users)))
def invite_user(cls, invite_data): team_mod = Authenticator.authenticate_team(invite_data.authentication, TeamRoles.is_team_moderator) invited_user = UserDatabaseClient.get_user_by_email(invite_data.email) if invited_user is not None and invited_user.role == UserRoles.ADMIN.value: cls.logger().info( f"Mod #{team_mod.id} tried to invite admin #{invited_user.id} to team #{team_mod.team_id}." ) return BadRequestTeamMessageResponse( "You cannot invite an admin to a team!", TeamResponseStatus.ROLE_UNAVAILABLE.value) already_member = TeamDatabaseClient.get_user_in_team_by_email( invite_data.email, team_mod.team_id) if already_member is not None: cls.logger().info( f"Mod #{team_mod.id} tried to invite user #{already_member.user_id} to team " f"#{team_mod.team_id}, but it already belongs to that team.") return BadRequestTeamMessageResponse( "This user already belongs to the team.", TeamResponseStatus.ALREADY_REGISTERED.value) if TeamDatabaseClient.get_team_invite(team_mod.team_id, invite_data.email) is not None: cls.logger().info( f"Mod #{team_mod.id} tried to invite an user already invited to team #{team_mod.team_id}" ) return BadRequestTeamMessageResponse( "This user was already invited to join the team.", TeamResponseStatus.ALREADY_INVITED.value) invite_token = Authenticator.generate_team_invitation() new_invite = TeamInvite(team_id=team_mod.team_id, email=invite_data.email, token=invite_token) try: TeamDatabaseClient.add_invite(new_invite) team = TeamDatabaseClient.get_team_by_id(team_mod.team_id) DatabaseClient.commit() cls.logger().info( f"New invitation for {new_invite.email} to join team #{team_mod.team_id}, by user #" f"{team_mod.id}.") email_data = TeamInvitationEmailDTO( email=invite_data.email, team_name=team.name, inviter_name=team_mod.username, token=invite_token, message_template=EmailService.team_invitation_message) EmailService.send_email(email_data) NotificationService.notify_team_invitation(new_invite, team_mod.id) cls.logger().info( f"Team #{team_mod.team_id} invitation email sent to {new_invite.email}." ) except IntegrityError: DatabaseClient.rollback() cls.logger().error( f"Couldn't invite user {new_invite.email} to team #{team_mod.team_id}." ) return UnsuccessfulTeamMessageResponse( "Couldn't invite user to team.") else: return SuccessfulTeamMessageResponse( "User invited.", TeamResponseStatus.INVITED.value)