def createProtoUser(self, email): """ Create a new protoUser with the given information. :returns: The user document that was created. """ from girderformindlogger.models.group import Group from girderformindlogger.models.setting import Setting encryptedEmail = hashlib.sha224(email.encode('utf-8')).hexdigest() protoUser = self.findOne(query={"email": encryptedEmail}, force=True) if protoUser: protoUser['groupInvites'] = [{ "groupId": gi.get('_id'), "level": 0 } for gi in list(Group().find(query={"queue": encryptedEmail}))] self.save(protoUser) return (protoUser) protoUser = { 'email': encryptedEmail, 'created': datetime.datetime.utcnow(), 'groupInvites': [{ "groupId": gi.get('_id'), "level": 0 } for gi in list(Group().find(query={"queue": encryptedEmail}))], 'email_encrypted': True } protoUser = self.save(protoUser) self._sendCreateAccountEmail(protoUser, email) return (protoUser)
def removeApplet(user, appletObject): """ remove an applet from a user without deleting their data inputs ------ user: admin user object appletObject: appletObject """ currentUser = authenticate(user) groupId = appletObject['roles']['user']['groups'][0]['id'] Group().removeUser(Group().load(id=groupId, force=True), user=currentUser)
def deleteApplet(user, appletObject): """ remove an applet from a user and also delete the user's data. inputs ------ user: admin user object appletObject: appletObject """ currentUser = authenticate(user) groupId = appletObject['roles']['user']['groups'][0]['id'] Group().removeUser(Group().load(id=groupId, force=True), user=currentUser, delete=True)
def makeAReviewer(user, appletObject, userB): """ give a user reviewer priveleges inputs ------ user: admin user object appletObject: appletObject userB: user to make a reviewer """ currentUser = authenticate(user) reviewerGroupId = appletObject['roles']['reviewer']['groups'][0]['id'] group = Group().load(id=ObjectId(reviewerGroupId), force=True) return Group().addUser(group, currentUser, level=AccessType.READ)
def acceptAppletInvite(user, appletObject, role): """ accept an applet invite inputs ------ user: admin user object appletObject: appletObject """ groupId = checkForInvite(user, appletObject) resp = Group().joinGroup(Group().load(groupId, force=True), user) assert role in resp[ 'lowerName'], "group name does not include \"{}\"".format(role) return 1
def userCreated(event): """ Check auto join rules when a new user is created. If a match is found, add the user to the group with the specified access level. """ user = event.info email = user.get('email').lower() rules = Setting().get(PluginSettings.AUTOJOIN) for rule in rules: if rule['pattern'].lower() not in email: continue group = Group().load(rule['groupId'], force=True) if group: Group().addUser(group, user, rule['level'])
def getCollectionCreationPolicyAccess(self): cpp = Setting().get(SettingKey.COLLECTION_CREATE_POLICY) acList = { 'users': [{ 'id': x } for x in cpp.get('users', [])], 'groups': [{ 'id': x } for x in cpp.get('groups', [])] } for user in acList['users'][:]: userDoc = User().load(user['id'], force=True, fields=['firstName', 'login', 'email']) if userDoc is None: acList['users'].remove(user) else: user['login'] = userDoc['login'] user['name'] = userDoc['firstName'] user['email'] = userDoc['email'] for grp in acList['groups'][:]: grpDoc = Group().load(grp['id'], force=True, fields=['name', 'description']) if grpDoc is None: acList['groups'].remove(grp) else: grp['name'] = grpDoc['name'] grp['description'] = grpDoc['description'] return acList
def inviteUserToApplet(user, appletObject, userB): """ invite a user to an applet inputs ------ user: a user object appletObject: userB: a user object of a user you want to invite. If they aren't defined yet, it should be a dict(email="emailaddress") """ groupId = appletObject['roles']['user']['groups'][0]['id'] currentUser = authenticate(user) group = Group().load(id=ObjectId(groupId), force=True) invitation = Invitation().createInvitation(appletObject, currentUser, role="user", profile=Profile().createProfile( appletObject, userB), idCode=None) return Group().inviteUser(group, userB, level=AccessType.READ)
def _validateCollectionCreatePolicy(doc): from girderformindlogger.models.group import Group from girderformindlogger.models.user import User value = doc['value'] if not isinstance(value, dict): raise ValidationException( 'Collection creation policy must be a JSON object.', 'value') for i, groupId in enumerate(value.get('groups', ())): Group().load(groupId, force=True, exc=True) value['groups'][i] = ObjectId(value['groups'][i]) for i, userId in enumerate(value.get('users', ())): User().load(userId, force=True, exc=True) value['users'][i] = ObjectId(value['users'][i]) value['open'] = value.get('open', False)
def __init__(self): super(Group, self).__init__() self.resourceName = 'group' self._model = GroupModel() self.route('DELETE', (':id',), self.deleteGroup) self.route('DELETE', (':id', 'member'), self.removeFromGroup) self.route('DELETE', (':id', 'moderator'), self.demote) self.route('DELETE', (':id', 'admin'), self.demote) self.route('GET', (), self.find) self.route('GET', ('open',), self.getOpenGroups) self.route('GET', (':id',), self.getGroup) self.route('GET', (':id', 'access'), self.getGroupAccess) self.route('GET', (':id', 'invitation'), self.getGroupInvitations) self.route('GET', (':id', 'member'), self.listMembers) self.route('POST', (), self.createGroup) self.route('POST', (':id', 'invitation'), self.inviteToGroup) self.route('POST', (':id', 'member'), self.joinGroup) self.route('POST', (':id', 'moderator'), self.promoteToModerator) self.route('POST', (':id', 'admin'), self.promoteToAdmin) self.route('PUT', (':id',), self.updateGroup) self.route('PUT', (':id', 'access'), self.updateGroupAccess)
def remove(self, user, progress=None, **kwargs): """ Delete a user, and all references to it in the database. :param user: The user document to delete. :type user: dict :param progress: A progress context to record progress on. :type progress: girderformindlogger.utility.progress.ProgressContext or None. """ from girderformindlogger.models.folder import Folder from girderformindlogger.models.group import Group from girderformindlogger.models.token import Token # Delete all authentication tokens owned by this user Token().removeWithQuery({'userId': user['_id']}) # Delete all pending group invites for this user Group().update({'requests': user['_id']}, {'$pull': { 'requests': user['_id'] }}) # Delete all of the folders under this user folderModel = Folder() folders = folderModel.find({ 'parentId': user['_id'], 'parentCollection': 'user' }) for folder in folders: folderModel.remove(folder, progress=progress, **kwargs) # Finally, delete the user document itself AccessControlledModel.remove(self, user) if progress: progress.update(increment=1, message='Deleted user ' + user['login'])
class Group(Resource): """API Endpoint for groups.""" def __init__(self): super(Group, self).__init__() self.resourceName = 'group' self._model = GroupModel() self.route('DELETE', (':id',), self.deleteGroup) self.route('DELETE', (':id', 'member'), self.removeFromGroup) self.route('DELETE', (':id', 'moderator'), self.demote) self.route('DELETE', (':id', 'admin'), self.demote) self.route('GET', (), self.find) self.route('GET', ('open',), self.getOpenGroups) self.route('GET', (':id',), self.getGroup) self.route('GET', (':id', 'access'), self.getGroupAccess) self.route('GET', (':id', 'invitation'), self.getGroupInvitations) self.route('GET', (':id', 'member'), self.listMembers) self.route('POST', (), self.createGroup) self.route('POST', (':id', 'invitation'), self.inviteToGroup) self.route('POST', (':id', 'member'), self.joinGroup) self.route('POST', (':id', 'moderator'), self.promoteToModerator) self.route('POST', (':id', 'admin'), self.promoteToAdmin) self.route('PUT', (':id',), self.updateGroup) self.route('PUT', (':id', 'access'), self.updateGroupAccess) @access.public @filtermodel(model=GroupModel) @autoDescribeRoute( Description('Search for groups or list all groups.') .param('text', 'Pass this to perform a full-text search for groups.', required=False) .param('exact', 'If true, only return exact name matches. This is ' 'case sensitive.', required=False, dataType='boolean', default=False) .pagingParams(defaultSort='name') .errorResponse() ) def find(self, text, exact, limit, offset, sort): user = self.getCurrentUser() if text is not None: if exact: groupList = self._model.find( {'name': text}, offset=offset, limit=limit, sort=sort) else: groupList = self._model.textSearch( text, user=user, offset=offset, limit=limit, sort=sort) else: groupList = self._model.list( user=user, offset=offset, limit=limit, sort=sort) return groupList @access.public @filtermodel(model=GroupModel) @autoDescribeRoute( Description('List all groups with open registration.') .pagingParams(defaultSort='name') .errorResponse() ) def getOpenGroups(self, limit, offset, sort): groupList = self._model.find( query={'openRegistration': True}, limit=limit, offset=offset, sort=sort ) return groupList @access.user @filtermodel(model=GroupModel) @autoDescribeRoute( Description('Create a new group.') .responseClass('Group') .notes('Must be logged in.') .param('name', 'Unique name for the group.', strip=True) .param('description', 'Description of the group.', required=False, default='', strip=True) .param( 'openRegistration', 'Whether users can join without being invited.', required=False, dataType='boolean', default=False ) .param('public', 'Whether the group should be publicly visible.', required=False, dataType='boolean', default=False) .errorResponse() .errorResponse('Write access was denied on the parent', 403) ) def createGroup(self, name, description, openRegistration, public): return(self._model.createGroup( name=name, creator=self.getCurrentUser(), description=description, openRegistration=openRegistration, public=public )) @access.public @filtermodel(model=GroupModel) @autoDescribeRoute( Description('Get a group by ID.') .responseClass('Group') .modelParam('id', model=GroupModel, level=AccessType.READ) .errorResponse('ID was invalid.') .errorResponse('Read access was denied for the group.', 403) ) def getGroup(self, group): # Add in the current setting for adding to groups group['_addToGroupPolicy'] = Setting().get(SettingKey.ADD_TO_GROUP_POLICY) return group @access.public @filtermodel(model=GroupModel, addFields={'access', 'requests'}) @autoDescribeRoute( Description('Get the access control list for a group.') .responseClass('Group') .modelParam('id', model=GroupModel, level=AccessType.READ) .errorResponse('ID was invalid.') .errorResponse('Read access was denied for the group.', 403) ) def getGroupAccess(self, group): groupModel = self._model group['access'] = groupModel.getFullAccessList(group) group['requests'] = list(groupModel.getFullRequestList(group)) return group @access.user @filtermodel(model=GroupModel, addFields={'access'}) @autoDescribeRoute( Description('Update the access control list for a group.') .modelParam('id', model=GroupModel, level=AccessType.WRITE) .jsonParam('access', 'The JSON-encoded access control list.', requireObject=True) .errorResponse('ID was invalid.') .errorResponse('Admin access was denied for the user.', 403) ) def updateGroupAccess(self, group, access): return self._model.setAccessList( group, access, save=True) @access.public @filtermodel(model=User) @autoDescribeRoute( Description('Show outstanding invitations for a group.') .responseClass('Group') .modelParam('id', model=GroupModel, level=AccessType.READ) .pagingParams(defaultSort='firstName') # 🚧 replace with customID once customID defined .errorResponse() .errorResponse('Read access was denied for the group.', 403) ) def getGroupInvitations(self, group, limit, offset, sort): return self._model.getInvites(group, limit, offset, sort) @access.user @filtermodel(model=GroupModel) @autoDescribeRoute( Description('Update a group by ID.') .modelParam('id', model=GroupModel, level=AccessType.WRITE) .param('name', 'The name to set on the group.', required=False, strip=True) .param('description', 'Description for the group.', required=False, strip=True) .param( 'openRegistration', 'Whether users can join without being invited.', required=False, dataType='boolean' ) .param('public', 'Whether the group should be publicly visible', dataType='boolean', required=False) .param('addAllowed', 'Can admins or moderators directly add members ' 'to this group? Only system administrators are allowed to ' 'set this field', required=False, enum=['default', 'no', 'yesmod', 'yesadmin']) .errorResponse() .errorResponse('Write access was denied for the group.', 403) ) def updateGroup( self, group, name, description, openRegistration, public, addAllowed ): if public is not None: self._model.setPublic(group, public) if openRegistration is not None: group['openRegistration'] = openRegistration if name is not None: group['name'] = name if description is not None: group['description'] = description if addAllowed is not None: self.requireAdmin(self.getCurrentUser()) group['addAllowed'] = addAllowed return(self._model.updateGroup(group)) @access.user @filtermodel(model=GroupModel, addFields={'access', 'requests'}) @autoDescribeRoute( Description('Request to join a group, or accept an invitation to join.') .responseClass('Group') .modelParam('id', model=GroupModel, force=True) .errorResponse('ID was invalid.') .errorResponse('You were not invited to this group, or do not have ' 'read access to it.', 403) # TODO: Update permissions error handling ) def joinGroup(self, group): groupModel = self._model group = groupModel.joinGroup(group, self.getCurrentUser()) group['access'] = groupModel.getFullAccessList(group) group['requests'] = list(groupModel.getFullRequestList(group)) return({'_id': group['_id'], 'name': group['name']}) @access.public @filtermodel(model=User) @autoDescribeRoute( Description('List members of a group.') .modelParam('id', model=GroupModel, level=AccessType.READ) .pagingParams(defaultSort='firstName') # 🚧 replace with customID once customID defined .errorResponse('ID was invalid.') .errorResponse('Read access was denied for the group.', 403) ) def listMembers(self, group, limit, offset, sort): return self._model.listMembers(group, offset=offset, limit=limit, sort=sort) @access.user @filtermodel(model=GroupModel, addFields={'access', 'requests'}) @autoDescribeRoute( Description( "Invite a user to join a group, or accept a user's request to join." ) .responseClass('Group') .notes('The "force" option to this endpoint is only available to ' 'administrators and can be used to bypass the invitation process' ' and instead add the user directly to the group.') .modelParam('id', model=GroupModel, level=AccessType.WRITE) .modelParam( 'userId', 'The ID of the user to invite or accept. Alternatively, provide ' '`email`.', model=User, destName='userToInvite', level=AccessType.READ, paramType='form', required=False ) .param( 'email', 'Email address of user to invite. Alternatively, provide `userId`.', required=False ) .param( 'level', 'The access level the user will be given when they accept the ' 'invitation.', required=False, dataType='integer', default=AccessType.READ ) .param( 'quiet', 'If you do not want this action to send an email to ' 'the target user, set this to true.', dataType='boolean', required=False, default=False ) .param( 'force', 'Add user directly rather than sending an invitation ' '(admin-only option).', dataType='boolean', required=False, default=False ) .errorResponse() .errorResponse('Write access was denied for the group.', 403) ) def inviteToGroup( self, group, userToInvite=None, email=None, level=AccessType.READ, quiet=False, force=False ): if (( userToInvite is None and email is None ) or ( userToInvite is not None and email is not None )): raise ValidationException( "`POST /group/{id}/invitation` requires exactly one of `userID`" "and `email`." ) groupModel = self._model user = self.getCurrentUser() if email is not None: userToInvite = User().findOne(query={"email": email}, force=True) if userToInvite is None: try: group["queue"] = list(set([email, *group.get("queue", [])])) except: group["queue"] = list(set([email])) groupModel.updateGroup(group) userToInvite = ProtoUser().createProtoUser(email=email) # TODO: send email to invite user return(group) if force: if not user['admin']: mustBeAdmin = True addPolicy = Setting().get(SettingKey.ADD_TO_GROUP_POLICY) addGroup = group.get('addAllowed', 'default') if addGroup not in ['no', 'yesadmin', 'yesmod']: addGroup = addPolicy if (groupModel.hasAccess( group, user, AccessType.ADMIN) and ('mod' in addPolicy or 'admin' in addPolicy) and addGroup.startswith('yes')): mustBeAdmin = False elif (groupModel.hasAccess( group, user, AccessType.WRITE) and 'mod' in addPolicy and addGroup == 'yesmod'): mustBeAdmin = False if mustBeAdmin: self.requireAdmin(user) groupModel.addUser(group, userToInvite, level=level) else: # Can only invite into access levels that you yourself have groupModel.requireAccess(group, user, level) groupModel.inviteUser(group, userToInvite, level) if not quiet: html = mail_utils.renderTemplate('groupInvite.mako', { 'userToInvite': userToInvite, 'user': user, 'group': group }) mail_utils.sendMail( "%s: You've been invited to a group" % Setting().get(SettingKey.BRAND_NAME), html, [userToInvite['email']] ) group['access'] = groupModel.getFullAccessList(group) group['requests'] = list(groupModel.getFullRequestList(group)) return(group) @access.user @filtermodel(model=GroupModel, addFields={'access'}) @autoDescribeRoute( Description('Promote a member to be a moderator of the group.') .responseClass('Group') .modelParam('id', model=GroupModel, level=AccessType.ADMIN) .modelParam('userId', 'The ID of the user to promote.', model=User, level=AccessType.READ, paramType='formData') .errorResponse('ID was invalid.') .errorResponse("You don't have permission to promote users.", 403) ) def promoteToModerator(self, group, user): return self._promote(group, user, AccessType.WRITE) @access.user @filtermodel(model=GroupModel, addFields={'access'}) @autoDescribeRoute( Description('Promote a member to be an administrator of the group.') .responseClass('Group') .modelParam('id', model=GroupModel, level=AccessType.ADMIN) .modelParam('userId', 'The ID of the user to promote.', model=User, level=AccessType.READ, paramType='formData') .errorResponse('ID was invalid.') .errorResponse("You don't have permission to promote users.", 403) ) def promoteToAdmin(self, group, user): return self._promote(group, user, AccessType.ADMIN) def _promote(self, group, user, level): """ Promote a user to moderator or administrator. :param group: The group to promote within. :param user: The user to promote. :param level: Either WRITE or ADMIN, for moderator or administrator. :type level: AccessType :returns: The updated group document. """ if not group['_id'] in user.get('groups', []): raise AccessException('That user is not a group member.') group = self._model.setUserAccess(group, user, level=level, save=True) group['access'] = self._model.getFullAccessList(group) return group @access.user @filtermodel(model=GroupModel, addFields={'access', 'requests'}) @autoDescribeRoute( Description('Demote a user to a normal group member.') .responseClass('Group') .modelParam('id', model=GroupModel, level=AccessType.ADMIN) .modelParam('userId', 'The ID of the user to demote.', model=User, level=AccessType.READ, paramType='formData') .errorResponse() .errorResponse("You don't have permission to demote users.", 403) ) def demote(self, group, user): groupModel = self._model group = groupModel.setUserAccess(group, user, level=AccessType.READ, save=True) group['access'] = groupModel.getFullAccessList(group) group['requests'] = list(groupModel.getFullRequestList(group)) return group @access.user @filtermodel(model=GroupModel, addFields={'access', 'requests'}) @autoDescribeRoute( Description('Remove a user from a group, or uninvite them.') .responseClass('Group') .notes('If the specified user is not yet a member of the group, this ' 'will delete any outstanding invitation or membership request for ' 'the user. Passing no userId parameter will assume that the ' 'current user is removing themself.') .modelParam('id', model=GroupModel, force=True) .modelParam('userId', 'The ID of the user to remove. If not passed, will ' 'remove yourself from the group.', required=False, model=User, force=True, destName='userToRemove', paramType='formData') .param( 'delete', 'Delete existing user data associated with this group membership?', dataType='boolean', required=False, default=False ) .errorResponse() .errorResponse("You don't have permission to remove that user.", 403) ) def removeFromGroup(self, group, userToRemove, delete): user = self.getCurrentUser() if not (bool( group.get('_id') in [ *user.get('groups', []), *user.get('formerGroups', []), *[ g.get('groupId') for g in [ *user.get('groupInvites', []), *user.get('declinedInvites', []) ] ] ] )): raise AccessException(message="You haven't been invited to that group.") else: groupModel = self._model if userToRemove is None: # Assume user is removing themself from the group userToRemove = user # # If removing someone else, you must have at least as high an # # access level as they do, and you must have at least write access # # to remove any user other than yourself. # if user['_id'] != userToRemove['_id']: # if groupModel.hasAccess(group, userToRemove, AccessType.ADMIN): # groupModel.requireAccess(group, user, AccessType.ADMIN) # else: # groupModel.requireAccess(group, user, AccessType.WRITE) group = groupModel.removeUser(group, userToRemove, delete) group['access'] = groupModel.getFullAccessList(group) group['requests'] = list(groupModel.getFullRequestList(group)) return(group) @access.user @autoDescribeRoute( Description('Delete a group by ID.') .modelParam('id', model=GroupModel, level=AccessType.ADMIN) .errorResponse('ID was invalid.') .errorResponse('Admin access was denied for the group.', 403) ) def deleteGroup(self, group): self._model.remove(group) return {'message': 'Deleted the group %s.' % group['name']}
def createProfile(self, applet, user, role="user"): """ Create a new profile to store information specific to a given (applet ∩ user) :param applet: The applet for which this profile exists :type applet: dict :param user: The user for which this profile exists :type user: dict :returns: The profile document that was created. """ from girderformindlogger.models.applet import Applet from girderformindlogger.models.group import Group if not isinstance(applet, dict): applet = Applet().load(applet, force=True) user = self._canonicalUser(applet["_id"], user) returnFields = ["_id", "appletId", "coordinatorDefined", "userDefined"] existing = self.findOne( { 'appletId': applet['_id'], 'userId': user['_id'], 'profile': True }, fields=[*returnFields, "deactivated"]) if applet['_id'] not in [ a.get('_id') for a in Applet().getAppletsForUser(role, user) ]: appletGroups = Applet().getAppletGroups(applet) roles = ['user', 'editor', 'reviewer', 'coordinator', 'manager' ] if role == 'manager' else [role] if 'user' not in roles: roles.append('user') for role in roles: groups = appletGroups.get(role) if bool(groups): group = Group().load(ObjectId(list(groups.keys())[0]), force=True) if group['_id'] not in user.get('groups', []): Group().inviteUser(group, user, level=AccessType.READ) Group().joinGroup(group, user) else: raise ValidationException( "User does not have role \"{}\" in this \"{}\" applet " "({})".format(role, Applet().preferredName(applet), str(applet['_id']))) if existing and not existing.get('deactivated', False): if "deactivated" in existing: existing.pop("deactivated") return existing now = datetime.datetime.utcnow() managers = list( self.find(query={ 'appletId': applet['_id'], 'roles': 'manager' }, fields=['_id'])) profile = { k: v for k, v in { 'appletId': ObjectId(applet['_id']), 'userId': ObjectId(user['_id']), 'profile': True, 'badge': 0, 'created': now, 'updated': now, 'deviceId': user['deviceId'], 'timezone': user['timezone'], 'individual_events': 0, 'completed_activities': [{ 'activity_id': activity_id, 'completed_time': None } for activity_id in applet.get('meta', {}).get( 'protocol', {}).get('activities', [])], 'accountId': applet.get('accountId', None), 'size': 0, 'coordinatorDefined': {}, 'userDefined': { 'displayName': user.get('displayName', user.get('firstName')), 'email': user.get('email' ) if not user.get('email_encrypted', None) else '' }, 'reviewers': [manager['_id'] for manager in managers] }.items() if v is not None } if existing: profile['_id'] = existing['_id'] self.setPublic(profile, False, save=False) # Save the profile. self.save(profile, validate=False) return ({k: v for k, v in profile.items() if k in returnFields})
def createUser(self, login, password, displayName="", email="", admin=False, public=False, currentUser=None, firstName="", lastName="", encryptEmail=False): """ Create a new user with the given information. :param admin: Whether user is global administrator. :type admin: bool :param public: Whether user is publicly visible. :type public: bool :returns: The user document that was created. """ from girderformindlogger.models.group import Group from girderformindlogger.models.setting import Setting requireApproval = Setting().get( SettingKey.REGISTRATION_POLICY) == 'approve' email = "" if not email else email login = login.lower().strip() email = email.lower().strip() if self.findOne({ 'email': email, 'email_encrypted': { '$ne': True } }) or self.findOne({ 'email': self.hash(email), 'email_encrypted': True }): raise ValidationException( 'That email is already registered in the system.', ) if admin: requireApproval = False encryptEmail = False user = { 'login': login, 'email': email, 'displayName': displayName if len(displayName) else firstName if firstName is not None else "", 'firstName': firstName, 'lastName': lastName, 'created': datetime.datetime.utcnow(), 'emailVerified': False, 'status': 'pending' if requireApproval else 'enabled', 'admin': admin, 'size': 0, 'deviceId': '', 'timezone': 0, 'groups': [], 'groupInvites': [{ "groupId": gi.get('_id'), "level": 0 } for gi in list(Group().find( query={"queue": email}))] if len(email) else [], 'email_encrypted': encryptEmail } if encryptEmail: if len(email) == 0 or not mail_utils.validateEmailAddress(email): raise ValidationException('Invalid email address.', 'email') user['email'] = self.hash(user['email']) self.setPassword(user, password, save=False) self.setPublic(user, public, save=False) if currentUser: self.setUserAccess(user, user=currentUser, level=AccessType.WRITE, save=False) user['creatorId'] = currentUser['_id'] user = self.save(user) if currentUser: User().setUserAccess(doc=currentUser, user=user, level=AccessType.READ, save=True) else: user['creatorId'] = user['_id'] user = self.save(user) verifyEmail = Setting().get( SettingKey.EMAIL_VERIFICATION) != 'disabled' if verifyEmail: self._sendVerificationEmail(user, email) if requireApproval: self._sendApprovalEmail(user) Group().update(query={"queue": user['email']}, update={"$pull": { "queue": user['email'] }}, multi=True) user = self._getGroupInvitesFromProtoUser(user) self._deleteProtoUser(user) return (user)
def createProfile(self, applet, user, role="user"): """ Create a new profile to store information specific to a given (applet ∩ user) :param applet: The applet for which this profile exists :type applet: dict :param user: The user for which this profile exists :type user: dict :returns: The profile document that was created. """ from girderformindlogger.models.applet import Applet from girderformindlogger.models.group import Group if not isinstance(applet, dict): applet = Applet().load(applet, force=True) user = self._canonicalUser(applet["_id"], user) returnFields = ["_id", "appletId", "coordinatorDefined", "userDefined"] existing = self.findOne( { 'appletId': applet['_id'], 'userId': user['_id'], 'profile': True }, fields=returnFields) if existing: return existing if applet['_id'] not in [ a.get('_id') for a in Applet().getAppletsForUser(role, user) ]: groups = Applet().getAppletGroups(applet).get(role) if bool(groups): group = Group().load(ObjectId(list(groups.keys())[0]), force=True) Group().inviteUser(group, user, level=AccessType.READ) Group().joinGroup(group, user) else: raise ValidationException( "User does not have role \"{}\" in this \"{}\" applet " "({})".format(role, Applet().preferredName(applet), str(applet['_id']))) now = datetime.datetime.utcnow() profile = { k: v for k, v in { 'appletId': ObjectId(applet['_id']), 'userId': ObjectId(user['_id']), 'profile': True, 'created': now, 'updated': now, 'size': 0, 'coordinatorDefined': {}, 'userDefined': { 'displayName': user.get('displayName', user.get( 'firstName')), 'email': user.get('email') } }.items() if v is not None } self.setPublic(profile, False, save=False) # Save the profile. self.save(profile, validate=False) return ({k: v for k, v in profile.items() if k in returnFields})
def testAutoJoinBehavior(self): admin, user = self.users # create some groups g1 = Group().createGroup('g1', admin) g2 = Group().createGroup('g2', admin) g3 = Group().createGroup('g3', admin) # set auto join rules rules = [ { 'pattern': '@test.com', 'groupId': str(g1['_id']), 'level': AccessType.ADMIN }, { 'pattern': '@example.com', 'groupId': str(g2['_id']), 'level': AccessType.READ }, { 'pattern': '@example.com', 'groupId': str(g3['_id']), 'level': AccessType.WRITE }, ] params = {'list': json.dumps([{'key': 'autojoin', 'value': rules}])} resp = self.request('/system/setting', user=admin, method='PUT', params=params) self.assertStatusOk(resp) # create users user1 = User().createUser('user1', 'password', 'John', 'Doe', '*****@*****.**') user2 = User().createUser('user2', 'password', 'John', 'Doe', '*****@*****.**') user3 = User().createUser('user3', 'password', 'John', 'Doe', '*****@*****.**') # check correct groups were joined self.assertEqual(user1['groups'], [g2['_id'], g3['_id']]) self.assertEqual(user2['groups'], [g1['_id']]) self.assertEqual(user3['groups'], []) # check correct access levels g1 = Group().load(g1['_id'], force=True) g3 = Group().load(g3['_id'], force=True) self.assertIn( { 'id': user2['_id'], 'level': AccessType.ADMIN, 'flags': [] }, g1['access']['users']) self.assertIn( { 'id': user1['_id'], 'level': AccessType.WRITE, 'flags': [] }, g3['access']['users'])