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 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.")
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)
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.")
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)