コード例 #1
0
    def client(self, address, is_cli=True):
        '''
        Return a client given the address.  Note that this can either be called
        by the CLI (is_cli=True) or the server (is_cli=False).
        If called by the CLI, we don't need to authenticate.
        Cache the Client if necessary.
        '''
        if address in self.clients:
            return self.clients[address]
        # if local force mockauth or if locl server use correct auth
        if is_local_address(address):
            bundle_store = self.bundle_store()
            model = self.model()
            auth_handler = self.auth_handler(mock=is_cli)

            from codalab.client.local_bundle_client import LocalBundleClient
            client = LocalBundleClient(address, bundle_store, model, auth_handler, self.cli_verbose)
            self.clients[address] = client
            if is_cli:
                # Set current user
                access_token = self._authenticate(client)
                auth_handler.validate_token(access_token)
        else:
            from codalab.client.remote_bundle_client import RemoteBundleClient
            client = RemoteBundleClient(address, lambda a_client: self._authenticate(a_client), self.cli_verbose())
            self.clients[address] = client
            self._authenticate(client)
        return client
コード例 #2
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)
コード例 #3
0
 def derive_rest_address(self, address):
     """
     Given bundle service address, return corresponding REST address
     using manual translations (described in the comments below).
     Temporary hack to ease transition to REST API.
     """
     o = urlparse(address)
     if is_local_address(address):
         # local => http://localhost:<rest_port>
         precondition('server' in self.config and
                      'rest_host' in self.config['server'] and
                      'rest_port' in self.config['server'],
                      'Working on local now requires running a local '
                      'server, please configure "rest_host" and '
                      '"rest_port" under "server" in your config.json.')
         address = 'http://{rest_host}:{rest_port}'.format(**self.config['server'])
     elif (o.hostname == 'localhost' and
                   'server' in self.config and
                   'port' in self.config['server'] and
                   'rest_port' in self.config['server'] and
                   o.port == self.config['server']['port']):
         # http://localhost:<port> => http://localhost:<rest_port>
         # Note that this does not affect the address of the NLP
         # CodaLab instance behind an SSH tunnel
         address = address.replace(str(self.config['server']['port']),
                                   str(self.config['server']['rest_port']))
     elif (o.netloc == 'worksheets.codalab.org' or
                   o.netloc == 'worksheets-test.codalab.org'):
         # http://worksheets.codalab.org/bundleservice => http://worksheets.codalab.org
         address = address.replace('/bundleservice', '')
     return address
コード例 #4
0
    def client(self, address, is_cli=True):
        '''
        Return a client given the address.  Note that this can either be called
        by the CLI (is_cli=True) or the server (is_cli=False).
        If called by the CLI, we don't need to authenticate.
        Cache the Client if necessary.
        '''
        if address in self.clients:
            return self.clients[address]
        # if local force mockauth or if locl server use correct auth
        if is_local_address(address):
            bundle_store = self.bundle_store()
            model = self.model()
            auth_handler = self.auth_handler(mock=is_cli)

            from codalab.client.local_bundle_client import LocalBundleClient
            client = LocalBundleClient(address, bundle_store, model,
                                       auth_handler, self.cli_verbose)
            self.clients[address] = client
            if is_cli:
                # Set current user
                access_token = self._authenticate(client)
                auth_handler.validate_token(access_token)
        else:
            from codalab.client.remote_bundle_client import RemoteBundleClient
            client = RemoteBundleClient(
                address, lambda a_client: self._authenticate(a_client),
                self.cli_verbose())
            self.clients[address] = client
            self._authenticate(client)
        return client
コード例 #5
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.
            '''
            token_info['expires_at'] = time.time() + float(token_info['expires_in']) - 60.0
            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
                if expires_at >= (time.time() + 900.0):
                    return token_info['access_token']
                # Try to refresh 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] = {}
        # For a local client with mock credentials, use the default username.
        username = ''
        if is_local_address(client.address):
            from codalab.server.auth import MockAuthHandler
            if type(self.auth_handler()) is MockAuthHandler:
                username = '******'
                password = ''
        if not username:
            print 'Requesting access at %s' % address
            print 'Username: '******'credentials', username, password)
        if token_info is None:
            raise UsageError("Invalid username or password")
        return _cache_token(token_info, username)
コード例 #6
0
    def client(self, address, is_cli=True, use_rest=False):
        '''
        Return a client given the address.  Note that this can either be called
        by the CLI (is_cli=True) or the server (is_cli=False).
        If called by the CLI, we don't need to authenticate.
        Cache the Client if necessary.
        '''
        # FIXME(sckoo): temporary hack
        # When BundleCLI is no longer dependent on RemoteBundleClient
        # or LocalBundleClient, simplify everything to only using
        # JsonApiClient, and remove all use_rest kwargs.
        # Users should also then update their aliases to point at the
        # correct addresses of the REST servers.
        if use_rest:
            address = self.derive_rest_address(address)

        # Return cached client
        # TODO(sckoo): Remove is_cli check when REST migration complete
        if not is_cli and address in self.clients:
            return self.clients[address]

        # Create new client
        if use_rest:
            # Create RestOAuthHandler that authenticates directly with
            # OAuth endpoints on the REST server
            from codalab.server.auth import RestOAuthHandler
            auth_handler = RestOAuthHandler(address, None)

            # Create JsonApiClient with a callback to get access tokens
            from codalab.client.json_api_client import JsonApiClient
            client = JsonApiClient(
                address, lambda: self._authenticate(address, auth_handler))
        elif is_local_address(address):
            # if local force mockauth or if local server use correct auth
            bundle_store = self.bundle_store()
            model = self.model()
            worker_model = self.worker_model()
            upload_manager = self.upload_manager()
            download_manager = self.download_manager()
            auth_handler = self.auth_handler(mock=is_cli)

            from codalab.client.local_bundle_client import LocalBundleClient
            client = LocalBundleClient(address, bundle_store, model, worker_model, upload_manager, download_manager, auth_handler, self.cli_verbose)
            if is_cli:
                # Set current user
                access_token = self._authenticate(client.address, client.auth_handler)
                auth_handler.validate_token(access_token)
        else:
            from codalab.client.remote_bundle_client import RemoteBundleClient

            client = RemoteBundleClient(address, lambda a_client: self._authenticate(a_client.address, a_client), self.cli_verbose)
            self._authenticate(client.address, client)

        # Cache and return client
        self.clients[address] = client
        return client
コード例 #7
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)