Example #1
0
    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)
Example #2
0
    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.")
Example #3
0
    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 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."
            )
Example #5
0
    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)
Example #6
0
    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)
Example #7
0
    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)