Exemple #1
0
    def joinGroup(self, group, user):
        """
        This method either accepts an invitation to join a group, or if the
        given user has not been invited to the group, this will create an
        invitation request that moderators and admins may grant or deny later.
        """
        from girderformindlogger.models.user import User

        if 'groupInvites' not in user:
            user['groupInvites'] = []

        if group.get('openRegistration', False):
            self.addUser(group, user, level=AccessType.READ)
            User().save(user, validate=False)

        else:
            for invite in user['groupInvites']:
                if invite['groupId'] == group['_id']:
                    self.addUser(group, user, level=invite['level'])
                    user['groupInvites'].remove(invite)
                    User().save(user, validate=False)
                    break
            else:
                if 'requests' not in group:
                    group['requests'] = []

                if not user['_id'] in group['requests']:
                    group['requests'].append(user['_id'])
                    group = self.save(group, validate=False)

        return (group)
Exemple #2
0
 def setUp(self):
     base.TestCase.setUp(self)
     admin = {
         'email': '*****@*****.**',
         'login': '******',
         'firstName': 'Admin',
         'lastName': 'Last',
         'password': '******',
         'admin': True
     }
     self.admin = User().createUser(**admin)
     user = {
         'email': '*****@*****.**',
         'login': '******',
         'firstName': 'First',
         'lastName': 'Last',
         'password': '******',
         'admin': False
     }
     self.user = User().createUser(**user)
     coll = {
         'name': 'Test Collection',
         'description': 'The description',
         'public': True,
         'creator': self.admin
     }
     self.collection = Collection().createCollection(**coll)
     Folder().createFolder(parent=self.collection,
                           parentType='collection',
                           name='Public',
                           public=True,
                           creator=self.admin)
Exemple #3
0
    def setUp(self):
        base.TestCase.setUp(self)

        self.admin = User().createUser(email='*****@*****.**',
                                       login='******',
                                       lastName='admin',
                                       firstName='admin',
                                       password='******',
                                       admin=True)
        self.user = User().createUser(email='*****@*****.**',
                                      login='******',
                                      lastName='u',
                                      firstName='u',
                                      password='******')

        self.f1 = Folder().createFolder(self.admin,
                                        'f1',
                                        creator=self.admin,
                                        parentType='user')
        self.f2 = Folder().createFolder(self.admin,
                                        'f2',
                                        creator=self.admin,
                                        parentType='user')
        self.virtual = Folder().createFolder(self.user,
                                             'v',
                                             creator=self.user,
                                             parentType='user')
        self.virtual['isVirtual'] = True
Exemple #4
0
    def load(self, info):
        User().ensureIndex((
            (('oauth.provider', SortDir.ASCENDING),
             ('oauth.id', SortDir.ASCENDING)), {}))
        User().reconnect()

        events.bind('no_password_login_attempt', 'oauth', checkOauthUser)

        info['apiRoot'].oauth = rest.OAuth()
def fastCrypt():
    """
    Use faster password hashing to avoid unnecessary testing bottlenecks.
    """
    from girderformindlogger.models.user import User

    # CryptContext.update could be used to mutate the existing instance, but if this fixture's scope
    # is ever made more limited (so that the teardown matters), this approach is more maintainable
    originalCryptContext = User()._cryptContext
    User()._cryptContext = originalCryptContext.copy(schemes=['plaintext'])
    yield
    User()._cryptContext = originalCryptContext
Exemple #6
0
    def _testLogin(cls, login):
        """
        When attempting to generate a username, use this to test if the given
        name is valid.
        """
        try:
            User()._validateLogin(login)
        except ValidationException:
            # Still doesn't match regex, we're hosed
            return False

        # See if this is already taken.
        user = User().findOne({'login': login})
        return not user
    def testLdapStatusCheck(self):
        admin = User().createUser(login='******',
                                  email='*****@*****.**',
                                  firstName='admin',
                                  lastName='admin',
                                  password='******',
                                  admin=True)

        params = {
            'bindName': 'cn=foo,cn=Users,dc=foo,dc=bar,dc=org',
            'password': '******',
            'uri': 'ldap://foo.bar.org:389'
        }

        with mock.patch('ldap.initialize',
                        return_value=MockLdap(bindFail=True)):
            resp = self.request('/system/ldap_server/status',
                                user=admin,
                                params=params)
            self.assertStatusOk(resp)
            self.assertFalse(resp.json['connected'])
            self.assertEqual(resp.json['error'],
                             'LDAP connection error: failed to connect')

        with mock.patch('ldap.initialize',
                        return_value=MockLdap(bindFail=False)):
            resp = self.request('/system/ldap_server/status',
                                user=admin,
                                params=params)
            self.assertStatusOk(resp)
            self.assertTrue(resp.json['connected'])
            self.assertNotIn('error', resp.json)
    def validate(self, doc):
        from girderformindlogger.models.token import Token
        from girderformindlogger.models.user import User

        if doc['tokenDuration']:
            doc['tokenDuration'] = float(doc['tokenDuration'])
        else:
            doc['tokenDuration'] = None

        doc['name'] = doc['name'].strip()
        doc['active'] = bool(doc.get('active', True))

        if doc['scope'] is not None:
            if not isinstance(doc['scope'], (list, tuple)):
                raise ValidationException('Scope must be a list, or None.')
            if not doc['scope']:
                raise ValidationException('Custom scope list must not be empty.')

            # Ensure only registered scopes are being set
            admin = User().load(doc['userId'], force=True)['admin']
            scopes = TokenScope.scopeIds(admin)
            unknownScopes = set(doc['scope']) - scopes
            if unknownScopes:
                raise ValidationException('Invalid scopes: %s.' % ','.join(unknownScopes))

        # Deactivating an already existing token
        if '_id' in doc and not doc['active']:
            Token().clearForApiKey(doc)

        return doc
    def createToken(self, key, days=None):
        """
        Create a token using an API key.

        :param key: The API key (the key itself, not the full document).
        :type key: str
        :param days: You may request a token duration up to the token duration
            of the API key itself, or pass None to use the API key duration.
        :type days: float or None
        """
        from girderformindlogger.models.setting import Setting
        from girderformindlogger.models.token import Token
        from girderformindlogger.models.user import User

        apiKey = self.findOne({
            'key': key
        })

        if apiKey is None or not apiKey['active']:
            raise ValidationException('Invalid API key.')

        cap = apiKey['tokenDuration'] or Setting().get(SettingKey.COOKIE_LIFETIME)
        days = min(float(days or cap), cap)

        user = User().load(apiKey['userId'], force=True)

        # Mark last used stamp
        apiKey['lastUse'] = datetime.datetime.utcnow()
        apiKey = self.save(apiKey)
        token = Token().createToken(user=user, days=days, scope=apiKey['scope'], apiKey=apiKey)
        return (user, token)
Exemple #10
0
    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
Exemple #11
0
    def inviteUser(self, group, user, level=AccessType.READ):
        """
        Invite a user to join the group. Inviting them automatically
        grants the user read access to the group so that they can see it.
        Once they accept the invitation, they will be given the specified level
        of access.

        If the user has requested an invitation to this group, calling this
        will accept their request and add them to the group at the access
        level specified.
        """
        from girderformindlogger.models.user import User

        if group['_id'] in user.get('groups', []):
            raise ValidationException('User is already in this group.')

        # If there is an outstanding request to join from this user, we
        # just add them to the group instead of invite them.
        if user['_id'] in group.get('requests', []):
            return self.addUser(group, user, level)

        if 'groupInvites' not in user:
            user['groupInvites'] = []

        for invite in user['groupInvites']:
            if invite['groupId'] == group['_id']:
                invite['level'] = level
                break
        else:
            user['groupInvites'].append({
                'groupId': group['_id'],
                'level': level
            })

        return User().save(user, validate=False)
Exemple #12
0
def _uploadComplete(event):
    """
    Called after an upload finishes. We check if our current token is a special
    authorized upload token, and if so, delete it.

    TODO we could alternatively keep a reference count inside each token that authorized
    more than a single upload at a time, and just decrement it here.
    """
    token = getCurrentToken()
    if token and 'authorizedUploadId' in token:
        user = User().load(token['userId'], force=True)
        item = Item().load(event.info['file']['itemId'], force=True)

        # Save the metadata on the item
        item['description'] = token['authorizedUploadDescription']
        item['authorizedUploadEmail'] = token['authorizedUploadEmail']
        Item().save(item)

        text = mail_utils.renderTemplate('authorized_upload.uploadFinished.mako', {
            'itemId': item['_id'],
            'itemName': item['name'],
            'itemDescription': item.get('description', '')
        })
        mail_utils.sendMail('Authorized upload complete', text, [user['email']])
        Token().remove(token)
    def setUp(self):
        base.TestCase.setUp(self)

        self.users = [
            User().createUser('usr%s' % num, 'passwd', 'tst', 'usr',
                              '*****@*****.**' % num) for num in [0, 1]
        ]
    def setUp(self):
        base.TestCase.setUp(self)

        self.siteAdminUser = User().createUser(email='*****@*****.**',
                                               login='******',
                                               firstName='Robert',
                                               lastName='Balboa',
                                               password='******')
        self.creatorUser = User().createUser(email='*****@*****.**',
                                             login='******',
                                             firstName='Apollo',
                                             lastName='Creed',
                                             password='******')
        creationSetting = Setting().getDefault(
            SettingKey.COLLECTION_CREATE_POLICY)
        creationSetting['open'] = True
        Setting().set(SettingKey.COLLECTION_CREATE_POLICY, creationSetting)
    def setUp(self):
        base.TestCase.setUp(self)
        self.dataDir = os.path.join(
            os.environ['GIRDER_TEST_DATA_PREFIX'], 'plugins', 'dicom_viewer')

        self.users = [User().createUser(
            'usr%s' % num, 'passwd', 'tst', 'usr', '*****@*****.**' % num)
            for num in [0, 1]]
Exemple #16
0
    def _canonicalUser(self, appletId, user):
        from girderformindlogger.models.user import User

        if isinstance(user, dict):
            userId = str(user['_id'])
            user = User().load(userId, force=True)
            profile = self.load(userId, force=True)
            return (user if user is not None else (
                User().load(str(profile['userId']), force=True) if
                (isinstance(profile, dict) and 'userId' in profile) else {}))
        if isinstance(user, str):
            try:
                return (self._canonicalUser(appletId,
                                            User().load(user, force=True)))
            except:
                return (self._canonicalUser(appletId,
                                            self.load(user, force=True)))
Exemple #17
0
    def check_auth_password(self, username, password):
        if username.lower() == 'anonymous':
            return paramiko.AUTH_SUCCESSFUL

        try:
            self.girderUser = User().authenticate(username, password, otpToken=True)
            return paramiko.AUTH_SUCCESSFUL
        except AccessException:
            return paramiko.AUTH_FAILED
Exemple #18
0
 def listMembers(self, group, offset=0, limit=0, sort=None):
     """
     List members of the group.
     """
     from girderformindlogger.models.user import User
     return User().find({'groups': group['_id']},
                        limit=limit,
                        offset=offset,
                        sort=sort)
Exemple #19
0
    def setUp(self):
        # Since our plugin updates the model singleton, don't drop models
        base.TestCase.setUp(self, dropModels=False)

        self.admin = User().createUser(email='*****@*****.**',
                                       login='******',
                                       firstName='first',
                                       lastName='last',
                                       password='******',
                                       admin=True)
Exemple #20
0
def _registerLdapUser(attrs, email, server):
    first, last = None, None
    if attrs.get('givenName'):
        first = attrs['givenName'][0].decode('utf8')
    elif attrs.get('cn'):
        first = attrs['cn'][0].decode('utf8').split()[0]

    if attrs.get('sn'):
        last = attrs['sn'][0].decode('utf8')
    elif attrs.get('cn'):
        last = attrs['cn'][0].decode('utf8').split()[-1]

    if not first or not last:
        raise Exception('No LDAP name entry found for %s.' % email)

    # Try using the search field value as the login. If it's an email address,
    # use the part before the @.
    try:
        login = attrs[server['searchField']][0].decode('utf8').split('@')[0]
        return User().createUser(login,
                                 password=None,
                                 firstName=first,
                                 lastName=last,
                                 email=email)
    except ValidationException as e:
        if e.field != 'login':
            raise

    # Fall back to deriving login from user's name
    for i in six.moves.range(_MAX_NAME_ATTEMPTS):
        login = ''.join((first, last, str(i) if i else ''))
        try:
            return User().createUser(login,
                                     password=None,
                                     firstName=first,
                                     lastName=last,
                                     email=email)
        except ValidationException as e:
            if e.field != 'login':
                raise

    raise Exception('Failed to generate login name for LDAP user %s.' % email)
Exemple #21
0
    def listKeys(self, userId, limit, offset, sort):
        user = self.getCurrentUser()

        if userId not in {None, str(user['_id'])}:
            self.requireAdmin(user)
            user = User().load(userId, force=True, exc=True)

        return list(ApiKeyModel().list(user,
                                       offset=offset,
                                       limit=limit,
                                       sort=sort))
Exemple #22
0
 def _recalculateSizes(self, progress):
     fixes = 0
     models = [Collection(), User()]
     steps = sum(model.find().count() for model in models)
     progress.update(total=steps, current=0)
     for model in models:
         for doc in model.find():
             progress.update(increment=1)
             _, f = model.updateSize(doc)
             fixes += f
     return fixes
Exemple #23
0
    def load(self, info):
        getPlugin('jobs').load(info)

        name = 'thumbnails'
        info['apiRoot'].thumbnail = rest.Thumbnail()

        for model in (Item(), Collection(), Folder(), User()):
            model.exposeFields(level=AccessType.READ, fields='_thumbnails')
            events.bind('model.%s.remove' % model.name, name, removeThumbnails)

        events.bind('model.file.remove', name, removeThumbnailLink)
        events.bind('data.process', name, _onUpload)
Exemple #24
0
    def _grantCreatorAccess(self, event):
        """
        This callback makes the group creator an administrator member of the
        group.

        This generally should not be called or overridden directly, but it may
        be unregistered from the `model.group.save.created` event.
        """
        from girderformindlogger.models.user import User
        group = event.info
        creator = User().load(group['creatorId'], force=True, exc=True)

        self.addUser(group, creator, level=AccessType.ADMIN)
Exemple #25
0
def lookUpPath(path, user=None, filter=True, force=False):
    """
    Look up a resource in the data hierarchy by path.

    :param path: path of the resource
    :param user: user with correct privileges to access path
    :param filter: Whether the returned model should be filtered.
    :type filter: bool
    :param force: if True, don't validate the access.
    :type force: bool
    """
    path = path.lstrip('/')
    pathArray = split(path)
    model = pathArray[0]

    if model == 'user':
        username = pathArray[1]
        parent = User().findOne({'login': username})

        if parent is None:
            raise ResourcePathNotFound('User not found: %s' % username)

    elif model == 'collection':
        collectionName = pathArray[1]
        parent = Collection().findOne({'name': collectionName})

        if parent is None:
            raise ResourcePathNotFound('Collection not found: %s' %
                                       collectionName)

    else:
        raise ValidationException('Invalid path format')

    try:
        document = parent
        if not force:
            ModelImporter.model(model).requireAccess(document, user)
        for token in pathArray[2:]:
            document, model = lookUpToken(token, model, document)
            if not force:
                ModelImporter.model(model).requireAccess(document, user)
    except (ValidationException, AccessException):
        # We should not distinguish the response between access and validation errors so that
        # adversarial users cannot discover the existence of data they don't have access to by
        # looking up a path.
        raise ResourcePathNotFound('Path not found: %s' % path)

    if filter:
        document = ModelImporter.model(model).filter(document, user)

    return {'model': model, 'document': document}
Exemple #26
0
def admin(db):
    """
    Require an admin user.

    Provides a user with the admin flag set to True.
    """
    from girderformindlogger.models.user import User
    u = User().createUser(email='*****@*****.**',
                          login='******',
                          firstName='Admin',
                          password='******',
                          admin=True)

    yield u
Exemple #27
0
def _getLdapUser(attrs, server):
    emails = attrs.get('mail')
    if not emails:
        raise Exception('No email record present for the given LDAP user.')

    if not isinstance(emails, (list, tuple)):
        emails = (emails, )

    emails = [e.decode('utf8').lower() for e in emails]
    existing = User().find({'email': {'$in': emails}}, limit=1)
    if existing.count():
        return next(existing)

    return _registerLdapUser(attrs, emails[0], server)
Exemple #28
0
    def listChildJobs(self, job):
        """
        Lists the child jobs for a given job

        :param job: Job document
        :type job: Job
        """
        query = {'parentId': job['_id']}
        cursor = self.find(query)
        user = User().load(job['userId'], force=True)
        for r in self.filterResultsByPermission(cursor=cursor,
                                                user=user,
                                                level=AccessType.READ):
            yield r
Exemple #29
0
    def getMembers(self, group, offset=0, limit=0, sort=None):
        """
        Return the list of all users who belong to this group.

        :param group: The group to list members on.
        :param offset: Offset into the result set of users.
        :param limit: Result set size limit.
        :param sort: Sort parameter for the find query.
        :returns: List of user documents.
        """
        from girderformindlogger.models.user import User
        return User().find({'groups': group['_id']},
                           offset=offset,
                           limit=limit,
                           sort=sort)
Exemple #30
0
def user(db, admin):
    """
    Require a user.

    Provides a regular user with no additional privileges. Note this fixture requires
    the admin fixture since an administrative user must exist before a regular user can.
    """
    from girderformindlogger.models.user import User
    u = User().createUser(email='*****@*****.**',
                          login='******',
                          firstName='user',
                          password='******',
                          admin=False)

    yield u