Exemplo n.º 1
0
def _check_permissions(model, table, user, object_uuids, owner_ids,
                       need_permission):
    # Validate parameter values
    if table == cl_group_bundle_permission:
        object_type = 'bundle'
    elif table == cl_group_worksheet_permission:
        object_type = 'worksheet'
    else:
        raise IntegrityError('Unexpected table: %s' % table)

    if len(object_uuids) == 0:
        return

    have_permissions = model.get_user_permissions(
        table, user.unique_id if user else None, object_uuids, owner_ids)
    if min(have_permissions.values()) >= need_permission:
        return
    if user:
        user_str = '%s(%s)' % (user.name, user.unique_id)
    else:
        user_str = None

    raise PermissionError(
        "User %s does not have sufficient permissions on %s %s (have %s, need %s)."
        % (
            user_str,
            object_type,
            ' '.join(object_uuids),
            ' '.join(map(permission_str, list(have_permissions.values()))),
            permission_str(need_permission),
        ))
Exemplo n.º 2
0
def new_worksheet(name):
    """
    Create a new worksheet with the given |name|.
    """
    if not request.user.is_authenticated:
        raise PermissionError("You must be logged in to create a worksheet.")
    ensure_unused_worksheet_name(name)

    # Don't need any permissions to do this.
    worksheet = Worksheet({
        'name': name,
        'title': None,
        'frozen': None,
        'items': [],
        'owner_id': request.user.user_id
    })
    local.model.new_worksheet(worksheet)

    # Make worksheet publicly readable by default
    set_worksheet_permission(worksheet, local.model.public_group_uuid,
                             GROUP_OBJECT_PERMISSION_READ)
    if spec_util.is_dashboard(name):
        populate_worksheet(worksheet, 'dashboard', 'CodaLab Dashboard')
    if spec_util.is_public_home(name):
        populate_worksheet(worksheet, 'home', 'Public Home')
    return worksheet.uuid
Exemplo n.º 3
0
 def inner(*args, **kwargs):
     import time
     time_delay = 1
     if self.verbose >= 2:
         print 'remote_bundle_client: %s %s %s' % (command, args,
                                                   kwargs)
     while True:
         try:
             return getattr(self.proxy, command)(*args, **kwargs)
         except xmlrpclib.ProtocolError, e:
             raise UsageError("Could not authenticate on %s: %s" %
                              (host, e))
         except xmlrpclib.Fault, e:
             # Transform server-side UsageErrors into client-side UsageErrors.
             if 'codalab.common.UsageError' in e.faultString:
                 index = e.faultString.find(':')
                 raise UsageError(e.faultString[index + 1:])
             if 'codalab.common.NotFoundError' in e.faultString:
                 index = e.faultString.find(':')
                 raise NotFoundError(e.faultString[index + 1:])
             elif 'codalab.common.PermissionError' in e.faultString:
                 index = e.faultString.find(':')
                 raise PermissionError(e.faultString[index + 1:])
             elif 'codalab.common.AuthorizationError' in e.faultString:
                 index = e.faultString.find(':')
                 raise AuthorizationError(e.faultString[index + 1:])
             else:
                 raise
 def get_access_token(self):
     if not self.grant or time.time(
     ) > self.expires_at - self.REFRESH_BUFFER_SECONDS:
         self.grant = self.auth_handler.generate_token(
             'credentials', self.username, self.password)
         if self.grant is None:
             raise PermissionError('Invalid username or password.')
         self.expires_at = time.time() + self.grant['expires_in']
     return self.grant['access_token']
Exemplo n.º 5
0
    def generate_token(self, grant_type, username, key):
        '''
        Generate OAuth access token from username/password or from a refresh token.

        If the grant succeeds, the method returns a dictionary of the form:
        { 'token_type': 'Bearer',
          'access_token': <token>,
          'expires_in': <span in seconds>,
          'refresh_token': <token> }
        If the grant fails because of invalid credentials, None is returned.
        '''
        if grant_type == 'credentials':
            if len(username) < self.min_username_length or len(
                    key) < self.min_key_length:
                raise PermissionError("Invalid username or password.")
            return self._generate_new_token(username, key)
        if grant_type == 'refresh_token':
            return self._refresh_token(username, key)
        raise ValueError("Bad request: grant_type is not valid.")
Exemplo n.º 6
0
def _check_permissions(model, table, user, object_uuids, need_permission,
                       session_cache):
    if len(object_uuids) == 0:
        return {}
    have_permissions = model.get_user_permissions(
        table, user.unique_id if user else None, object_uuids, session_cache)
    #print '_check_permissions %s %s, have %s, need %s' % (user, object_uuids, map(permission_str, have_permissions.values()), permission_str(need_permission))
    if min(have_permissions.values()) >= need_permission:
        return have_permissions
    if user:
        user_str = '%s(%s)' % (user.name, user.unique_id)
    else:
        user_str = None
    if table == cl_group_bundle_permission:
        object_type = 'bundle'
    elif table == cl_group_worksheet_permission:
        object_type = 'worksheet'
    else:
        raise IntegrityError('Unexpected table: %s' % table)
    raise PermissionError("User %s does not have sufficient permissions on %s %s (have %s, need %s)." % \
        (user_str, object_type, ' '.join(object_uuids), ' '.join(map(permission_str, have_permissions.values())), permission_str(need_permission)))
Exemplo n.º 7
0
def check_worksheet_not_frozen(worksheet):
    if worksheet.frozen:
        raise PermissionError('Cannot mutate frozen worksheet %s(%s).' %
                              (worksheet.uuid, worksheet.name))
Exemplo n.º 8
0
    def _authenticate(self, cache_key, auth_handler):
        """
        Authenticate with the given client. This will prompt user for password
        unless valid credentials are already available. Client state will be
        updated if new tokens are generated.

        :param cache_key: key by which to cache the access token, typically
                          the address of the CodaLab instance
        :param auth_handler: AuthHandler through which to authenticate
        :return: access token
        """
        auth = self.state['auth'].get(cache_key, {})

        def _cache_token(token_info, username=None):
            '''
            Helper to update state with new token info and optional username.
            Returns the latest access token.
            '''
            # Make sure this is in sync with auth.py.
            token_info['expires_at'] = time.time() + float(
                token_info['expires_in'])
            del token_info['expires_in']
            auth['token_info'] = token_info
            if username is not None:
                auth['username'] = username
            self.save_state()
            return token_info['access_token']

        # Check the cache for a valid token
        if 'token_info' in auth:
            token_info = auth['token_info']
            expires_at = token_info.get('expires_at', 0.0)

            # If token is not nearing expiration, just return it.
            if expires_at >= (time.time() + 10 * 60):
                return token_info['access_token']

            # Otherwise, let's refresh the token.
            token_info = auth_handler.generate_token(
                'refresh_token', auth['username'], token_info['refresh_token'])
            if token_info is not None:
                return _cache_token(token_info)

        # If we get here, a valid token is not already available.
        auth = self.state['auth'][cache_key] = {}

        username = os.environ.get('CODALAB_USERNAME')
        password = os.environ.get('CODALAB_PASSWORD')
        if username is None or password is None:
            print('Requesting access at %s' % cache_key)
        if username is None:
            sys.stdout.write('Username: '******'credentials', username,
                                                 password)
        if token_info is None:
            raise PermissionError("Invalid username or password.")
        return _cache_token(token_info, username)
Exemplo n.º 9
0
    def _authenticate(self, client):
        '''
        Authenticate with the given client. This will prompt user for password
        unless valid credentials are already available. Client state will be
        updated if new tokens are generated.

        client: The client pointing to the bundle service to authenticate with.

        Returns an access token.
        '''
        address = client.address
        auth = self.state['auth'].get(address, {})

        def _cache_token(token_info, username=None):
            '''
            Helper to update state with new token info and optional username.
            Returns the latest access token.
            '''
            # Make sure this is in sync with auth.py.
            token_info['expires_at'] = time.time() + float(
                token_info['expires_in'])
            del token_info['expires_in']
            auth['token_info'] = token_info
            if username is not None:
                auth['username'] = username
            self.save_state()
            return token_info['access_token']

        # Check the cache for a valid token
        if 'token_info' in auth:
            token_info = auth['token_info']
            expires_at = token_info.get('expires_at', 0.0)
            if expires_at > time.time():
                # Token is usable but check if it's nearing expiration (10 minutes)
                # If not nearing, then just return it.
                if expires_at >= (time.time() + 10 * 60):
                    return token_info['access_token']
                # Otherwise, let's refresh the token.
                token_info = client.login('refresh_token', auth['username'],
                                          token_info['refresh_token'])
                if token_info is not None:
                    return _cache_token(token_info)

        # If we get here, a valid token is not already available.
        auth = self.state['auth'][address] = {}

        username = None
        # For a local client with mock credentials, use the default username.
        if is_local_address(client.address):
            username = self.root_user_name()
            password = ''
        if not username:
            print 'Requesting access at %s' % address
            sys.stdout.write('Username: '******'credentials', username, password)
        if token_info is None:
            raise PermissionError("Invalid username or password.")
        return _cache_token(token_info, username)