Ejemplo n.º 1
0
    def initializeOtp(self, user):
        """
        Initialize the use of one-time passwords with this user.

        This does not save the modified user model.

        :param user: The user to modify.
        :return: The new OTP keys, each in KeyUriFormat.
        :rtype: dict
        """
        totp = self._TotpFactory.new()

        user['otp'] = {'enabled': False, 'totp': totp.to_dict()}

        # Use the brand name as the OTP issuer if it's non-default (since that's prettier and more
        # meaningful for users), but fallback to the site hostname if the brand name isn't set
        # (to disambiguate otherwise identical "Girder" issuers)
        # Prevent circular import
        from girderformindlogger.api.rest import getUrlParts
        brandName = Setting().get(SettingKey.BRAND_NAME)
        defaultBrandName = Setting().getDefault(SettingKey.BRAND_NAME)
        # OTP URIs ( https://github.com/google/google-authenticator/wiki/Key-Uri-Format ) do not
        # allow colons, so use only the hostname component
        serverHostname = getUrlParts().netloc.partition(':')[0]
        # Normally, the issuer would be set when "self._TotpFactory" is instantiated, but that
        # happens during model initialization, when there's no current request, so the server
        # hostname is not known then
        otpIssuer = brandName if brandName != defaultBrandName else serverHostname

        return {'totpUri': totp.to_uri(label=user['login'], issuer=otpIssuer)}
Ejemplo n.º 2
0
def _setCommonCORSHeaders():
    """
    Set CORS headers that should be passed back with either a preflight OPTIONS
    or a simple CORS request. We set these headers anytime there is an Origin
    header present since browsers will simply ignore them if the request is not
    cross-origin.
    """
    origin = cherrypy.request.headers.get('origin')
    if not origin:
        # If there is no origin header, this is not a cross origin request
        return

    allowed = Setting().get(SettingKey.CORS_ALLOW_ORIGIN)

    if allowed:
        setResponseHeader('Access-Control-Allow-Credentials', 'true')
        setResponseHeader(
            'Access-Control-Expose-Headers', Setting().get(SettingKey.CORS_EXPOSE_HEADERS))

        allowedList = {o.strip() for o in allowed.split(',')}

        if origin in allowedList:
            setResponseHeader('Access-Control-Allow-Origin', origin)
        elif '*' in allowedList:
            setResponseHeader('Access-Control-Allow-Origin', '*')
Ejemplo n.º 3
0
    def hasCreatePrivilege(self, user):
        """
        Tests whether a given user has the authority to create collections on
        this instance. This is based on the collection creation policy settings.
        By default, only admins are allowed to create collections.

        :param user: The user to test.
        :returns: bool
        """
        from girderformindlogger.models.setting import Setting

        if user['admin']:
            return True

        policy = Setting().get(SettingKey.COLLECTION_CREATE_POLICY)

        if policy['open'] is True:
            return True

        if user['_id'] in policy.get('users', ()):
            return True

        if set(policy.get('groups', ())) & set(user.get('groups', ())):
            return True

        return False
Ejemplo n.º 4
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
    def testAutoComputeHashes(self):
        with self.assertRaises(ValidationException):
            Setting().set(hashsum_download.PluginSettings.AUTO_COMPUTE, 'bad')

        old = hashsum_download.SUPPORTED_ALGORITHMS
        hashsum_download.SUPPORTED_ALGORITHMS = {'sha512', 'sha256'}
        Setting().set(hashsum_download.PluginSettings.AUTO_COMPUTE, True)

        file = Upload().uploadFromFile(
            obj=six.BytesIO(self.userData), size=len(self.userData), name='Another file',
            parentType='folder', parent=self.privateFolder, user=self.user)

        start = time.time()
        while time.time() < start + 15:
            file = File().load(file['_id'], force=True)
            if 'sha256' in file:
                break
            time.sleep(0.2)

        expected = hashlib.sha256()
        expected.update(self.userData)
        self.assertIn('sha256', file)
        self.assertEqual(file['sha256'], expected.hexdigest())

        expected = hashlib.sha512()
        expected.update(self.userData)
        self.assertIn('sha512', file)
        self.assertEqual(file['sha512'], expected.hexdigest())

        hashsum_download.SUPPORTED_ALGORITHMS = old
Ejemplo n.º 6
0
    def _setQuotaDefault(self,
                         model,
                         value,
                         testVal='__NOCHECK__',
                         error=None):
        """
        Set the default quota for a particular model.

        :param model: either 'user' or 'collection'.
        :param value: the value to set.  Either None or a positive integer.
        :param testVal: if not __NOCHECK__, test the current value to see if it
                        matches this.
        :param error: if set, this is a substring expected in an error message.
        """
        if model == 'user':
            key = PluginSettings.DEFAULT_USER_QUOTA
        elif model == 'collection':
            key = PluginSettings.DEFAULT_COLLECTION_QUOTA
        try:
            Setting().set(key, value)
        except ValidationException as err:
            if not error:
                raise
            if error not in err.args[0]:
                raise
            return
        if testVal != '__NOCHECK__':
            newVal = Setting().get(key)
            self.assertEqual(newVal, testVal)
Ejemplo n.º 7
0
def getLicenses(self, default):
    if default:
        licenses = Setting().getDefault(PluginSettings.LICENSES)
    else:
        licenses = Setting().get(PluginSettings.LICENSES)

    return licenses
Ejemplo n.º 8
0
 def emailVerificationRequired(self, user):
     """
     Returns True if email verification is required and this user has not
     yet verified their email address.
     """
     from girderformindlogger.models.setting import Setting
     return (not user['emailVerified']) and \
         (Setting().get(SettingKey.EMAIL_VERIFICATION) == 'required' or Setting().get(SettingKey.EMAIL_VERIFICATION) == 'enabled')
Ejemplo n.º 9
0
    def OPTIONS(self, *path, **param):
        _setCommonCORSHeaders()
        cherrypy.lib.caching.expires(0)

        allowHeaders = Setting().get(SettingKey.CORS_ALLOW_HEADERS)
        allowMethods = Setting().get(SettingKey.CORS_ALLOW_METHODS)

        setResponseHeader('Access-Control-Allow-Methods', allowMethods)
        setResponseHeader('Access-Control-Allow-Headers', allowHeaders)
Ejemplo n.º 10
0
    def testLicensesSettingValidation(self):
        """
        Test validation of licenses setting.
        """
        # Test valid settings
        Setting().set(
            PluginSettings.LICENSES,
            [])
        Setting().set(
            PluginSettings.LICENSES,
            [{'category': 'A', 'licenses': []}])
        Setting().set(
            PluginSettings.LICENSES,
            [{'category': 'A', 'licenses': [{'name': '1'}]}])
        Setting().set(
            PluginSettings.LICENSES,
            [{'category': 'A', 'licenses': [{'name': '1'}, {'name': '2'}]}])
        Setting().set(
            PluginSettings.LICENSES,
            [{'category': 'A', 'licenses': []},
             {'category': 'B', 'licenses': [{'name': '1'}]}])
        Setting().set(
            PluginSettings.LICENSES,
            [{'category': 'A', 'licenses': []},
             {'category': 'B', 'licenses': [{'name': '1'}, {'name': '2'}]}])

        # Test invalid top-level types
        for val in (None, 1, '', {}, [{}]):
            self.assertRaises(ValidationException, Setting().set, PluginSettings.LICENSES, val)

        # Test invalid category types
        for category, licenses in ((None, []), (1, []), ('', []), ({}, [])):
            self.assertRaises(
                ValidationException,
                Setting().set,
                PluginSettings.LICENSES,
                [{'category': category, 'licenses': licenses}])

        # Test invalid licenses types
        for val in (None, {}, [1], ['']):
            self.assertRaises(
                ValidationException,
                Setting().set,
                PluginSettings.LICENSES,
                [{'category': 'A', 'licenses': val}])

        # Test invalid license names
        for val in (None, 1, '', {}, []):
            self.assertRaises(
                ValidationException,
                Setting().set,
                PluginSettings.LICENSES,
                [{'category': 'A', 'licenses': [{'name': val}]}])
Ejemplo n.º 11
0
def _submitEmail(msg, recipients):
    from girderformindlogger.models.setting import Setting

    setting = Setting()
    smtp = _SMTPConnection(host=setting.get(SettingKey.SMTP_HOST),
                           port=setting.get(SettingKey.SMTP_PORT),
                           encryption=setting.get(SettingKey.SMTP_ENCRYPTION),
                           username=setting.get(SettingKey.SMTP_USERNAME),
                           password=setting.get(SettingKey.SMTP_PASSWORD))

    logger.info('Sending email to %s through %s', ', '.join(recipients),
                smtp.host)

    with smtp:
        smtp.send(msg['From'], recipients, msg.as_string())
Ejemplo n.º 12
0
def _createMessage(subject, text, to, bcc):
    from girderformindlogger.models.setting import Setting

    # Coerce and validate arguments
    if isinstance(to, six.string_types):
        to = [to]
    if isinstance(bcc, six.string_types):
        bcc = [bcc]
    elif bcc is None:
        bcc = []
    if not to and not bcc:
        raise Exception('You must specify email recipients via "to" or "bcc".')

    if not subject:
        subject = '[no subject]'

    if isinstance(text, six.text_type):
        # TODO: needed?
        text = text.encode('utf8')

    # Build message
    msg = MIMEText(text, 'html', 'UTF-8')
    if to:
        msg['To'] = ', '.join(to)
    if bcc:
        msg['Bcc'] = ', '.join(bcc)
    msg['Subject'] = subject
    msg['From'] = Setting().get(SettingKey.EMAIL_FROM_ADDRESS)

    # Compute recipients
    recipients = list(set(to) | set(bcc))

    return msg, recipients
Ejemplo n.º 13
0
def _ldapAuth(event):
    login, password = event.info['login'], event.info['password']
    servers = Setting().get(PluginSettings.SERVERS)

    for server in servers:
        try:
            # ldap requires a uri complete with protocol.
            # Append one if the user did not specify.
            conn = ldap.initialize(server['uri'])
            conn.set_option(ldap.OPT_TIMEOUT, _CONNECT_TIMEOUT)
            conn.set_option(ldap.OPT_NETWORK_TIMEOUT, _CONNECT_TIMEOUT)
            conn.bind_s(server['bindName'], server['password'], ldap.AUTH_SIMPLE)

            searchStr = '%s=%s' % (server['searchField'], login)
            # Add the searchStr to the attributes, keep local scope.
            lattr = _LDAP_ATTRS + (server['searchField'],)
            results = conn.search_s(server['baseDn'], ldap.SCOPE_SUBTREE, searchStr, lattr)
            if results:
                entry, attrs = results[0]
                dn = attrs['distinguishedName'][0].decode('utf8')
                try:
                    conn.bind_s(dn, password, ldap.AUTH_SIMPLE)
                except ldap.LDAPError:
                    # Try other LDAP servers or fall back to core auth
                    continue
                finally:
                    conn.unbind_s()

                user = _getLdapUser(attrs, server)
                if user:
                    event.stopPropagation().preventDefault().addResponse(user)
        except ldap.LDAPError:
            logger.exception('LDAP connection exception (%s).' % server['uri'])
            continue
Ejemplo n.º 14
0
    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)
Ejemplo n.º 15
0
    def generateTemporaryPassword(self, email):
        user = self._model.findOne({'email': self._model.hash(email.lower()), 'email_encrypted': True})

        if not user:
            user = self._model.findOne({'email': email.lower(), 'email_encrypted': {'$ne': True}})

        if not user:
            raise RestException('That email is not registered.')

        token = Token().createToken(user, days=(15/1440.0), scope=TokenScope.TEMPORARY_USER_AUTH)

        url = '%s#useraccount/%s/token/%s' % (
            mail_utils.getEmailUrlPrefix(), str(user['_id']), str(token['_id']))

        html = mail_utils.renderTemplate('temporaryAccess.mako', {
            'url': url,
            'token': str(token['_id'])
        })

        mail_utils.sendMail(
            '%s: Temporary access' % Setting().get(SettingKey.BRAND_NAME),
            html,
            [email]
        )
        return {'message': 'Sent temporary access email.'}
Ejemplo n.º 16
0
    def _addDefaultFolders(self, event):
        """
        This callback creates "Public" and "Private" folders on a user, after
        it is first created.

        This generally should not be called or overridden directly, but it may
        be unregistered from the `model.user.save.created` event.
        """
        from girderformindlogger.models.folder import Folder
        from girderformindlogger.models.setting import Setting

        if Setting().get(SettingKey.USER_DEFAULT_FOLDERS) == 'public_private':
            user = event.info

            publicFolder = Folder().createFolder(user,
                                                 'Public',
                                                 parentType='user',
                                                 public=True,
                                                 creator=user)
            privateFolder = Folder().createFolder(user,
                                                  'Private',
                                                  parentType='user',
                                                  public=False,
                                                  creator=user)
            # Give the user admin access to their own folders
            Folder().setUserAccess(publicFolder,
                                   user,
                                   AccessType.ADMIN,
                                   save=True)
            Folder().setUserAccess(privateFolder,
                                   user,
                                   AccessType.ADMIN,
                                   save=True)
Ejemplo n.º 17
0
def getApiUrl(url=None, preferReferer=False):
    """
    In a request thread, call this to get the path to the root of the REST API.
    The returned path does *not* end in a forward slash.

    :param url: URL from which to extract the base URL. If not specified, uses
        the server root system setting. If that is not specified, uses `cherrypy.url()`
    :param preferReferer: if no url is specified, this is true, and this is in
        a cherrypy request that has a referer header that contains the api
        string, use that referer as the url.
    """
    apiStr = config.getConfig()['server']['api_root']

    if not url:
        if preferReferer and apiStr in cherrypy.request.headers.get('referer', ''):
            url = cherrypy.request.headers['referer']
        else:
            root = Setting().get(SettingKey.SERVER_ROOT)
            if root:
                return posixpath.join(root, apiStr.lstrip('/'))

    url = url or cherrypy.url()
    idx = url.find(apiStr)

    if idx < 0:
        raise GirderException('Could not determine API root in %s.' % url)

    return url[:idx + len(apiStr)]
Ejemplo n.º 18
0
def _computeHashHook(event):
    """
    Event hook that computes the file hashes in the background after
    a completed upload. Only done if the AUTO_COMPUTE setting enabled.
    """
    if Setting().get(PluginSettings.AUTO_COMPUTE):
        _computeHash(event.info['file'])
Ejemplo n.º 19
0
    def stream(self, timeout, params):
        if not Setting().get(SettingKey.ENABLE_NOTIFICATION_STREAM):
            raise RestException('The notification stream is not enabled.',
                                code=503)

        user, token = self.getCurrentUser(returnToken=True)

        setResponseHeader('Content-Type', 'text/event-stream')
        setResponseHeader('Cache-Control', 'no-cache')
        since = params.get('since')
        if since is not None:
            since = datetime.utcfromtimestamp(since)

        def streamGen():
            lastUpdate = since
            start = time.time()
            wait = MIN_POLL_INTERVAL
            while cherrypy.engine.state == cherrypy.engine.states.STARTED:
                wait = min(wait + MIN_POLL_INTERVAL, MAX_POLL_INTERVAL)
                for event in NotificationModel().get(user,
                                                     lastUpdate,
                                                     token=token):
                    if lastUpdate is None or event['updated'] > lastUpdate:
                        lastUpdate = event['updated']
                    wait = MIN_POLL_INTERVAL
                    start = time.time()
                    yield sseMessage(event)
                if time.time() - start > timeout:
                    break

                time.sleep(wait)

        return streamGen
Ejemplo n.º 20
0
def updateItemLicense(event):
    """
    REST event handler to update item with license parameter, if provided.
    """
    params = event.info['params']
    if 'license' not in params:
        return

    itemModel = Item()
    item = itemModel.load(event.info['returnVal']['_id'], force=True, exc=True)
    newLicense = validateString(params['license'])
    if item['license'] == newLicense:
        return

    # Ensure that new license name is in configured list of licenses.
    #
    # Enforcing this here, instead of when validating the item, avoids an extra
    # database lookup (for the settings) on every future item save.
    if newLicense:
        licenseSetting = Setting().get(PluginSettings.LICENSES)
        validLicense = any(
            license['name'] == newLicense
            for group in licenseSetting
            for license in group['licenses'])
        if not validLicense:
            raise ValidationException(
                'License name must be in configured list of licenses.', 'license')

    item['license'] = newLicense
    item = itemModel.save(item)
    event.preventDefault()
    event.addResponse(item)
    def testManualComputeHashes(self):
        Setting().set(hashsum_download.PluginSettings.AUTO_COMPUTE, False)
        old = hashsum_download.SUPPORTED_ALGORITHMS
        hashsum_download.SUPPORTED_ALGORITHMS = {'sha512', 'sha256'}

        self.assertNotIn('sha256', self.privateFile)

        expected = hashlib.sha256()
        expected.update(self.userData)

        # Running the compute endpoint should only compute the missing ones
        resp = self.request(
            '/file/%s/hashsum' % self.privateFile['_id'], method='POST', user=self.user)
        self.assertStatusOk(resp)
        self.assertEqual(resp.json, {
            'sha256': expected.hexdigest()
        })

        # Running again should be a no-op
        resp = self.request(
            '/file/%s/hashsum' % self.privateFile['_id'], method='POST', user=self.user)
        self.assertStatusOk(resp)
        self.assertEqual(resp.json, None)

        file = File().load(self.privateFile['_id'], force=True)
        self.assertEqual(file['sha256'], expected.hexdigest())

        hashsum_download.SUPPORTED_ALGORITHMS = old
Ejemplo n.º 22
0
def getEmailUrlPrefix():
    """
    Return the URL prefix for links back to the server. This is the link to the
    server root, so Girder-level path information and any query parameters or
    fragment value should be appended to this value.
    """
    from girderformindlogger.models.setting import Setting
    return Setting().get(SettingKey.EMAIL_HOST)
Ejemplo n.º 23
0
    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)
Ejemplo n.º 24
0
 def adminApprovalRequired(self, user):
     """
     Returns True if the registration policy requires admin approval and
     this user is pending approval.
     """
     from girderformindlogger.models.setting import Setting
     return user.get('status', 'enabled') == 'pending' and \
         Setting().get(SettingKey.REGISTRATION_POLICY) == 'approve'
Ejemplo n.º 25
0
    def createUser(
        self,
        login,
        password,
        displayName="",
        email="",
        admin=False,
        lastName=None,
        firstName=None
    ): # 🔥 delete lastName once fully deprecated
        currentUser = self.getCurrentUser()

        regPolicy = Setting().get(SettingKey.REGISTRATION_POLICY)

        if not currentUser or not currentUser['admin']:
            admin = False
            if regPolicy == 'closed':
                raise RestException(
                    'Registration on this instance is closed. Contact an '
                    'administrator to create an account for you.')

        user = self._model.createUser(
            login=login, password=password, email=email,
            firstName=displayName if len(
                displayName
            ) else firstName if firstName is not None else "",
            lastName=lastName, admin=admin, currentUser=currentUser) # 🔥 delete firstName and lastName once fully deprecated

        if not currentUser and self._model.canLogin(user):
            setCurrentUser(user)
            token = self.sendAuthTokenCookie(user)
            user['authToken'] = {
                'token': token['_id'],
                'expires': token['expires']
            }

        # Assign all new users to a "New Users" Group
        newUserGroup = GroupModel().findOne({'name': 'New Users'})
        newUserGroup = newUserGroup if (
            newUserGroup is not None and bool(newUserGroup)
        ) else GroupModel(
        ).createGroup(
            name="New Users",
            creator=UserModel().findOne(
                query={'admin': True},
                sort=[('created', SortDir.ASCENDING)]
            ),
            public=False
        )
        group = GroupModel().addUser(
            newUserGroup,
            user,
            level=AccessType.READ
        )
        group['access'] = GroupModel().getFullAccessList(group)
        group['requests'] = list(GroupModel().getFullRequestList(group))

        return(user)
Ejemplo n.º 26
0
    def testGetLicenses(self):
        """
        Test getting list of licenses.
        """
        # Get default settings
        resp = self.request(path='/item/licenses', user=self.user, params={
            'default': True
        })
        self.assertStatusOk(resp)
        self.assertGreater(len(resp.json), 1)
        self.assertIn('category', resp.json[0])
        self.assertIn('licenses', resp.json[0])
        self.assertGreater(len(resp.json[0]['licenses']), 8)
        self.assertIn('name', resp.json[0]['licenses'][0])
        self.assertGreater(len(resp.json[0]['licenses'][0]['name']), 0)
        self.assertIn('name', resp.json[0]['licenses'][1])
        self.assertGreater(len(resp.json[0]['licenses'][1]['name']), 0)

        # Get current settings
        resp = self.request(path='/item/licenses', user=self.user)
        self.assertStatusOk(resp)
        self.assertGreater(len(resp.json), 1)
        self.assertIn('category', resp.json[0])
        self.assertIn('licenses', resp.json[0])
        self.assertGreater(len(resp.json[0]['licenses']), 8)
        self.assertIn('name', resp.json[0]['licenses'][0])
        self.assertGreater(len(resp.json[0]['licenses'][0]['name']), 0)
        self.assertIn('name', resp.json[0]['licenses'][1])
        self.assertGreater(len(resp.json[0]['licenses'][1]['name']), 0)

        # Change licenses
        Setting().set(
            PluginSettings.LICENSES,
            [{'category': 'A', 'licenses': [{'name': '1'}]},
             {'category': 'B', 'licenses': [{'name': '2'}, {'name': '3'}]}])

        # Get default settings after changing licenses
        resp = self.request(path='/item/licenses', user=self.user, params={
            'default': True
        })
        self.assertStatusOk(resp)
        self.assertStatusOk(resp)
        self.assertGreater(len(resp.json), 1)
        self.assertIn('category', resp.json[0])
        self.assertIn('licenses', resp.json[0])
        self.assertGreater(len(resp.json[0]['licenses']), 8)
        self.assertIn('name', resp.json[0]['licenses'][0])
        self.assertGreater(len(resp.json[0]['licenses'][0]['name']), 0)
        self.assertIn('name', resp.json[0]['licenses'][1])
        self.assertGreater(len(resp.json[0]['licenses'][1]['name']), 0)

        # Get current settings after changing licenses
        resp = self.request(path='/item/licenses', user=self.user)
        self.assertStatusOk(resp)
        six.assertCountEqual(
            self, resp.json,
            [{'category': 'A', 'licenses': [{'name': '1'}]},
             {'category': 'B', 'licenses': [{'name': '2'}, {'name': '3'}]}])
Ejemplo n.º 27
0
    def setSetting(self, key, value, list):
        if list is None:
            list = ({'key': key, 'value': value}, )

        for setting in list:
            key, value = setting['key'], setting['value']
            if isinstance(value, six.string_types):
                try:
                    value = json.loads(value)
                except ValueError:
                    pass

            if value is None:
                Setting().unset(key=key)
            else:
                Setting().set(key=key, value=value)

        return True
Ejemplo n.º 28
0
    def destroy(self, path):
        """
        Handle shutdown of the FUSE.

        :param path: always '/'.
        """
        Setting().unset(SettingKey.GIRDER_MOUNT_INFORMATION)
        events.trigger('server_fuse.destroy')
        return super(ServerFuse, self).destroy(path)
Ejemplo n.º 29
0
def computeBaseUrl(user):
    """
    Compute the base gravatar URL for a user and return it. For the moment, the
    current default image is cached in this URL. It is the caller's
    responsibility to save this value on the user document.
    """
    defaultImage = Setting().get(PluginSettings.DEFAULT_IMAGE)

    md5 = hashlib.md5(user['email'].encode('utf8')).hexdigest()
    return 'https://www.gravatar.com/avatar/%s?d=%s' % (md5, defaultImage)
Ejemplo n.º 30
0
 def createKey(self, name, scope, tokenDuration, active):
     if Setting().get(SettingKey.API_KEYS):
         return ApiKeyModel().createApiKey(user=self.getCurrentUser(),
                                           name=name,
                                           scope=scope,
                                           days=tokenDuration,
                                           active=active)
     else:
         raise RestException(
             'API key functionality is disabled on this instance.')