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.")
Exemple #2
0
    def delete_team(cls, user_data):
        user = Authenticator.authenticate_team(user_data,
                                               TeamRoles.is_team_moderator)
        team = TeamDatabaseClient.get_team_by_id(user.team_id)

        try:
            TeamDatabaseClient.delete_team(team)
            DatabaseClient.commit()
            cls.logger().info(f"Team #{user.team_id} deleted.")
            return SuccessfulTeamMessageResponse(
                "Team removed!", TeamResponseStatus.REMOVED.value)
        except IntegrityError:
            DatabaseClient.rollback()
            cls.logger().error(
                f"User #{user.id} couldn't remove team #{user.team_id}.")
            return UnsuccessfulTeamMessageResponse("Couldn't remove team.")
Exemple #3
0
    def tito_welcome(cls, user_id, team_id):
        bot = BotDatabaseClient.get_bot_by_id(cls.TITO_ID)
        team = TeamDatabaseClient.get_team_by_id(team_id)

        if bot is not None and team.welcome_message is not None:
            body = {
                "params": cls.TITO_WELCOME_PARAMS,
                "message": team.welcome_message,
                "user_id": user_id,
                "team_id": team_id
            }
            headers = {"X-Auth-Token": bot.token}
            requests.post(url=bot.callback, json=body, headers=headers)
            cls.logger().info(f"Tito notified to welcome user #{user_id} to team #{team_id}")
        elif team.welcome_message is not None:
            cls.logger().info(f"There's no message for Tito to welcome user #{user_id}.")
    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)
Exemple #6
0
    def update_information(cls, update_data):
        user = Authenticator.authenticate_team(update_data.authentication,
                                               TeamRoles.is_team_moderator)
        team = TeamDatabaseClient.get_team_by_id(
            update_data.authentication.team_id)

        team.name = \
            update_data.updated_team["team_name"] if "team_name" in update_data.updated_team else team.name
        team.picture = \
            update_data.updated_team["picture"] if "picture" in update_data.updated_team else team.picture
        team.location = \
            update_data.updated_team["location"] if "location" in update_data.updated_team else team.location
        team.description = \
            update_data.updated_team["description"] if "description" in update_data.updated_team else team.description
        team.welcome_message = \
            update_data.updated_team[
                "welcome_message"] if "welcome_message" in update_data.updated_team else team.welcome_message

        try:
            team = TeamDatabaseClient.update_team(team)
            DatabaseClient.commit()
            cls.logger().info(
                f"Team {team.id} information updated by user #{user.id}, who's team {user.team_role}."
            )
            return SuccessfulTeamResponse(team,
                                          TeamResponseStatus.UPDATED.value)
        except IntegrityError:
            DatabaseClient.rollback()
            team_name = update_data.updated_team.get("team_name")
            if TeamDatabaseClient.get_team_by_name(team_name) is not None:
                cls.logger().info(
                    f"Trying to update team {user.team_id}'s name with {team_name}, that currently exists."
                )
                return BadRequestTeamMessageResponse(
                    f"Name {team_name} is already in use!",
                    TeamResponseStatus.ALREADY_REGISTERED.value)
            else:
                cls.logger().error(
                    f"Couldn't update team {user.team_id} information.")
                return UnsuccessfulTeamMessageResponse(
                    "Couldn't update team 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."
            )
    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.")
Exemple #9
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)