def view_helper(self, user_id: str, args: Namespace) -> ResponseTuple: """ View user info from database. If no parameters are provided, returns information of ``user_id``. If ``args.username`` is provided, returns the specific user matching the Slack ID provided, otherwise returns all users that match all traits of other provided parameters (e.g. ``github`` and ``email``) :param user_id: Slack ID of user who is calling command :param args: List of user parameters defining the query :return: error message if user not found in database, else information about the user, or users. """ try: if args.username: user = self.facade.retrieve(User, args.username) # If no query parameters are provided, get the sender elif not args.github and not args.email: user = self.facade.retrieve(User, user_id) else: query = [] if args.github: query.append(('github', args.github)) if args.email: query.append(('email', escape_email(args.email))) users = self.facade.query(User, query) if len(users) == 0: raise LookupError elif len(users) > 1: return { 'text': 'Warning - multiple users found!', 'attachments': [u.get_attachment() for u in users] }, 200 else: user = users[0] if args.inspect: return { 'attachments': [user.get_attachment(), self.viewinspect_helper(user)] }, 200 else: return {'attachments': [user.get_attachment()]}, 200 except LookupError: return self.lookup_error, 200
def user_edit(self, caller_id: str, member: str = None, name: str = None, email: str = None, pos: str = None, github: str = None, major: str = None, bio: str = None, permission: Permissions = None) -> bool: """ Edit a user in the database. If ``member`` is not None, and the calling user is an admin, this function edits the user with ID ``member``. Otherwise, the calling user is edited. :param caller_id: Slack ID of the user who is calling the API :param member: Slack ID of the user to edit :param name: display name to change to for the user :param email: email to change to for the user :param pos: position to change to for the user :param github: Github username to change to for the user :param major: major to change to for the user :param bio: bio to change to for the user :param permission: permission level to change to for the user :raises: LookupError if the calling user or the desired user to edit could not be found in the database :raises: PermissionError if the calling user is attempting to edit another user and they are not an admin, or are trying to edit their own permission level without being an admin :raises: GithubAPIException if setting the Github username fails to add the corresponding user to the Github organization :return: True if user was successfully edited in the database, False otherwise """ logging.info("User edit command API called") calling_user = self._db_facade.retrieve(User, caller_id) is_admin = calling_user.permissions_level == Permissions.admin edited_user = calling_user if member is not None: if is_admin: edited_user = self._db_facade.retrieve(User, member) else: msg = f"Calling user with Slack ID {caller_id} has" \ " permission level " \ f"{str(calling_user.permissions_level)}, insufficient " \ "for editing another user!" logging.error(msg) raise PermissionError(msg) else: edited_user = calling_user if permission and is_admin: edited_user.permissions_level = permission elif permission and not is_admin: msg = f"Calling user with Slack ID {caller_id} has permission" \ f" level {str(calling_user.permissions_level)}, " \ "insufficient for editing own permission level!" logging.error(msg) raise PermissionError(msg) if github: github_id = self._gh_interface.org_add_member(github) edited_user.github_username = github edited_user.github_id = github_id if name: edited_user.name = name if email: edited_user.email = escape_email(email) if pos: edited_user.position = pos if major: edited_user.major = major if bio: edited_user.biography = bio return self._db_facade.store(edited_user)
def edit_helper(self, user_id: str, param_list: Dict[str, str]) -> ResponseTuple: """ Edit user from database. If ``param_list['member'] is not None``, this function edits using the ID from ``param_list['member']`` (must be an admin to do so). Otherwise, edits the user that called the function. :param user_id: Slack ID of user who is calling the command :param param_list: List of user parameters that are to be edited :return: returns error message if not admin and command edits another user, returns edit message if user is edited """ is_admin = False edited_user = None msg = "" if param_list["member"] is not None: try: admin_user = self.facade.retrieve(User, user_id) if admin_user.permissions_level != Permissions.admin: return self.permission_error, 200 else: is_admin = True edited_id = param_list["member"] edited_user = self.facade.retrieve(User, edited_id) except LookupError: return self.lookup_error, 200 else: try: edited_user = self.facade.retrieve(User, user_id) except LookupError: return self.lookup_error, 200 if param_list["name"]: edited_user.name = param_list["name"] if param_list["email"]: edited_user.email = escape_email(param_list["email"]) if param_list["pos"]: edited_user.position = param_list["pos"] if param_list["github"]: try: github_id = self.github.org_add_member(param_list["github"]) edited_user.github_username = param_list["github"] edited_user.github_id = github_id except GithubAPIException: msg = f"\nError adding user {param_list['github']} to " \ f"GitHub organization" logging.error(msg) if param_list["major"]: edited_user.major = param_list["major"] if param_list["bio"]: edited_user.biography = param_list["bio"] if param_list["permission"] and is_admin: edited_user.permissions_level = cast(Permissions, param_list["permission"]) elif param_list["permission"] and not is_admin: msg += "\nCannot change own permission: user isn't admin." logging.warning(f"User {user_id} tried to elevate permissions" " level.") self.facade.store(edited_user) ret = {'attachments': [edited_user.get_attachment()]} if msg != "": # mypy doesn't like the fact that there could be different types # for the values of the dict ret, so we have to ignore this line # for now ret['text'] = msg # type: ignore return ret, 200
def test_escape_normal_email(self): email = '*****@*****.**' self.assertEqual(util.escape_email(email), email)
def test_escape_email(self): """Test parsing escaped emails.""" email = "<mailto:[email protected]|[email protected]>" ret = util.escape_email(email) self.assertEqual(ret, "*****@*****.**")
def test_escape_email(): """Test parsing escaped emails.""" email = "<mailto:[email protected]|[email protected]>" ret = util.escape_email(email) assert ret == "*****@*****.**"
def edit_helper(self, user_id: str, args: Namespace) -> ResponseTuple: """ Edit user from database. If ``args.username is not None``, this function edits using the ID from ``args.username`` (must be an admin to do so). Otherwise, edits the user that called the function. :param user_id: Slack ID of user who is calling the command :param args: List of user parameters that are to be edited :return: error message if not admin and command edits another user, or the edit message if user is edited """ is_admin = False edited_user = None msg = "" if args.username is not None: try: admin_user = self.facade.retrieve(User, user_id) if admin_user.permissions_level != Permissions.admin: return self.permission_error, 200 else: is_admin = True edited_id = args.username edited_user = self.facade.retrieve(User, edited_id) except LookupError: return self.lookup_error, 200 else: try: edited_user = self.facade.retrieve(User, user_id) except LookupError: return self.lookup_error, 200 if args.name: edited_user.name = args.name if args.email: edited_user.email = escape_email(args.email) if args.pos: edited_user.position = args.pos if args.github: try: github_id = self.github.org_add_member(args.github) edited_user.github_username = args.github edited_user.github_id = github_id except GithubAPIException: msg = f"\nError adding user {args.github} to " \ f"GitHub organization" logging.error(msg) if args.major: edited_user.major = args.major if args.bio: edited_user.biography = args.bio if args.permission and is_admin: edited_user.permissions_level = args.permission elif args.permission and not is_admin: msg += "\nCannot change own permission: user isn't admin." logging.warning(f"User {user_id} tried to elevate permissions" " level.") self.facade.store(edited_user) # Sync permissions only if email was updated if args.email: sync_user_email_perms(self.gcp, self.facade, edited_user) ret = {'attachments': [edited_user.get_attachment()]} if msg != "": # mypy doesn't like the fact that there could be different types # for the values of the dict ret, so we have to ignore this line # for now ret['text'] = msg # type: ignore return ret, 200