예제 #1
0
    def delete_app(self, client_id):
        """
        Delete an application from the database
        """
        user = pylons.request.environ['fts3.User.Credentials']
        app = Session.query(OAuth2Application).get(client_id)
        if app is None:
            raise HTTPNotFound('Application not found')
        if app.owner != user.user_dn:
            raise HTTPForbidden()

        try:
            Session.delete(app)
            Session.query(OAuth2Token).filter(
                OAuth2Token.client_id == client_id).delete()
            Session.query(OAuth2Code).filter(
                OAuth2Code.client_id == client_id).delete()
            Session.commit()
        except:
            Session.rollback()
            raise

        log.info("Application removed: %s" % client_id)

        return None
예제 #2
0
    def delete_share(self, start_response):
        """
        Delete a share
        """
        input_dict = get_input_as_dict(request, from_query=True)
        source = input_dict.get('source')
        destination = input_dict.get('destination')
        vo = input_dict.get('vo')

        if not source or not destination or not vo:
            raise HTTPBadRequest('Missing source, destination and/or vo')

        try:
            share = Session.query(ShareConfig).get((source, destination, vo))
            if share:
                Session.delete(share)
                audit_configuration(
                    'share-delete', 'Share %s, %s, %s has been deleted' %
                    (source, destination, vo))
                Session.commit()
        except:
            Session.rollback()
            raise

        start_response('204 No Content', [])
        return ['']
예제 #3
0
    def update_app(self, client_id):
        """
        Update an application
        """
        user = pylons.request.environ['fts3.User.Credentials']
        app = Session.query(OAuth2Application).get(client_id)
        if not app:
            raise HTTPNotFound('Application not found')
        if app.owner != user.user_dn:
            raise HTTPForbidden()
        if pylons.request.headers['Content-Type'].startswith('application/json'):
            fields = json.loads(pylons.request.body)
        else:
            fields = pylons.request.POST

        try:
            if 'delete' not in fields:
                app.description = fields.get('description', '')
                app.website = fields.get('website', '')
                app.redirect_to = fields.get('redirect_to', '')
                Session.merge(app)
                Session.commit()
                redirect(url_for(controller='oauth2', action='get_app'), code=HTTPSeeOther.code)
            else:
                Session.delete(app)
                Session.query(OAuth2Token).filter(OAuth2Token.client_id == client_id).delete()
                Session.query(OAuth2Code).filter(OAuth2Code.client_id == client_id).delete()
                Session.commit()
                redirect(url_for(controller='oauth2', action='get_my_apps'), code=HTTPSeeOther.code)
        except:
            Session.rollback()
            raise
예제 #4
0
파일: __init__.py 프로젝트: mhellmic/fts3
	def popDelegation(self):
		cred = self.getUserCredentials()
		if cred and cred.delegation_id:
			delegated = Session.query(Credential).get((cred.delegation_id, cred.user_dn))
			if delegated:
				Session.delete(delegated)
				Session.commit()
예제 #5
0
파일: __init__.py 프로젝트: mhellmic/fts3
 def popDelegation(self):
     cred = self.getUserCredentials()
     if cred and cred.delegation_id:
         delegated = Session.query(Credential).get(
             (cred.delegation_id, cred.user_dn))
         if delegated:
             Session.delete(delegated)
             Session.commit()
예제 #6
0
 def remove_token(self):
     info = self._get_dropbox_user_info()
     if info is None:
         raise HTTPNotFound('No registered user for the service "%s" has been found' % self.service)
     try:
         Session.delete(info)
         Session.commit()
     except:
         Session.rollback()
         raise
예제 #7
0
 def pop_delegation(self):
     """
     Remove the mock proxy from the database
     """
     cred = self.get_user_credentials()
     if cred and cred.delegation_id:
         delegated = Session.query(Credential).get((cred.delegation_id, cred.user_dn))
         if delegated:
             Session.delete(delegated)
             Session.commit()
예제 #8
0
 def pop_delegation(self):
     """
     Remove the mock proxy from the database
     """
     cred = self.get_user_credentials()
     if cred and cred.delegation_id:
         delegated = Session.query(Credential).get(
             (cred.delegation_id, cred.user_dn))
         if delegated:
             Session.delete(delegated)
             Session.commit()
예제 #9
0
파일: se.py 프로젝트: cern-fts/fts-rest
    def set_se_config(self):
        """
        Set the configuration parameters for a given SE
        """
        input_dict = get_input_as_dict(request)
        try:
            for storage, cfg in input_dict.iteritems():
                if not storage or storage.isspace():
                    raise ValueError
                se_info = None
                se_info_new = cfg.get('se_info', None)
                if se_info_new:
                    se_info = Session.query(Se).get(storage)
                    if not se_info:
                        se_info = Se(storage=storage)
                    for key, value in se_info_new.iteritems():
                        #value = validate_type(Se, key, value)
                        setattr(se_info, key, value)

                    audit_configuration(
                        'set-se-config',
                        'Set config %s: %s' % (storage, json.dumps(cfg)))
                    Session.merge(se_info)

                    # Operation limits
                    operations = cfg.get('operations', None)
                    if operations:
                        for vo, limits in operations.iteritems():
                            for op, limit in limits.iteritems():
                                limit = int(limit)
                                new_limit = Session.query(OperationConfig).get(
                                    (vo, storage, op))
                                if limit > 0:
                                    if not new_limit:
                                        new_limit = OperationConfig(
                                            vo_name=vo,
                                            host=storage,
                                            operation=op)
                                    new_limit.concurrent_ops = limit
                                    Session.merge(new_limit)
                                elif new_limit:
                                    Session.delete(new_limit)
                        audit_configuration(
                            'set-se-limits', 'Set limits for %s: %s' %
                            (storage, json.dumps(operations)))
            Session.commit()
        except (AttributeError, ValueError):
            Session.rollback()
            raise HTTPBadRequest('Malformed configuration')
        except:
            Session.rollback()
            raise
        return (se_info, operations)
예제 #10
0
    def update_app(self, client_id):
        """
        Update an application
        """
        user = pylons.request.environ['fts3.User.Credentials']
        app = Session.query(OAuth2Application).get(client_id)
        if not app:
            raise HTTPNotFound('Application not found')
        if app.owner != user.user_dn:
            raise HTTPForbidden()
        if pylons.request.headers['Content-Type'].startswith(
                'application/json'):
            fields = json.loads(pylons.request.body)
            scopes = fields.get('scope', list())
        else:
            fields = pylons.request.POST
            scopes = fields.getall('scope')

        if isinstance(scopes, basestring):
            scopes = scopes.split(',')

        for s in scopes:
            if str(s) not in VALID_OPERATIONS:
                raise HTTPBadRequest('Invalid scope (%s)' % s)

        try:
            if 'delete' not in fields:
                app.description = fields.get('description', '')
                app.website = fields.get('website', '')
                app.redirect_to = fields.get('redirect_to', '')
                app.scope = scopes
                Session.merge(app)
                Session.commit()
                redirect(url_for(controller='oauth2', action='get_app'),
                         code=HTTPSeeOther.code)
            else:
                Session.delete(app)
                Session.query(OAuth2Token).filter(
                    OAuth2Token.client_id == client_id).delete()
                Session.query(OAuth2Code).filter(
                    OAuth2Code.client_id == client_id).delete()
                Session.commit()
                redirect(url_for(controller='oauth2', action='get_my_apps'),
                         code=HTTPSeeOther.code)
        except:
            Session.rollback()
            raise
예제 #11
0
 def delete_activity_shares(self, vo_name, start_response):
     """
     Delete an existing activity share
     """
     activity_share = Session.query(ActivityShare).get(vo_name)
     if activity_share is None:
         raise HTTPNotFound('No activity shares for %s' % vo_name)
     try:
         Session.delete(activity_share)
         audit_configuration('activity-share',
                             'Activity share removed for "%s"' % (vo_name))
         Session.commit()
     except:
         Session.rollback()
         raise
     start_response('204 No Content', [])
     return ['']
예제 #12
0
    def is_access_requested(self):
        info = self._get_dropbox_user_info()
        if info is None:
            raise HTTPNotFound('No registered user for the service "%s" has been found' % self.service)

        if info.is_registered():
            res = self._get_content("/")
            if res.startswith("401"):
                try:
                    Session.delete(info)
                    Session.commit()
                except:
                    Session.rollback()
                    raise
                raise HTTPNotFound('No registered user for the service "%s" has been found' % self.service)

        return info
예제 #13
0
    def is_access_requested(self):
        info = self._get_dropbox_user_info()
        if info is None:
            raise HTTPNotFound('No registered user for the service "%s" has been found' % self.service)

        if info.is_registered():
            res = self._get_content("/")
            if res.startswith("401"):
                try:
                    Session.delete(info)
                    Session.commit()
                except:
                    Session.rollback()
                    raise
                raise HTTPNotFound('No registered user for the service "%s" has been found' % self.service)

        return info.storage_name
예제 #14
0
    def test_put_cred_without_cache(self):
        """
        This is a regression test. It tries to PUT directly
        credentials without the previous negotiation, so there is no
        CredentialCache in the database. This attempt must fail.
        """
        self.setup_gridsite_environment()
        creds = self.get_user_credentials()

        request = self.app.get(url="/delegation/%s/request" % creds.delegation_id,
                               status=200)
        proxy = self.get_x509_proxy(request.body)

        Session.delete(Session.query(CredentialCache).get((creds.delegation_id, creds.user_dn)))

        self.app.put(url="/delegation/%s/credential" % creds.delegation_id,
                     params=proxy,
                     status=400)
예제 #15
0
    def remove_cloud_storage(self, storage_name, start_response):
        """
        Remove a registered cloud storage
        """
        storage = Session.query(CloudStorage).get(storage_name)
        if not storage:
            raise HTTPNotFound('The storage does not exist')

        try:
            Session.query(CloudStorageUser).filter(CloudStorageUser.storage_name == storage_name).delete()
            Session.delete(storage)
            Session.commit()
        except:
            Session.rollback()
            raise

        start_response('204 No Content', [])
        return [''] 
예제 #16
0
    def test_put_cred_without_cache(self):
        """
        This is a regression test. It tries to PUT directly
        credentials without the previous negotiation, so there is no
        CredentialCache in the database. This attempt must fail.
        """
        self.setup_gridsite_environment()
        creds = self.get_user_credentials()

        request = self.app.get(url="/delegation/%s/request" %
                               creds.delegation_id,
                               status=200)
        proxy = self.get_x509_proxy(request.body)

        Session.delete(
            Session.query(CredentialCache).get(
                (creds.delegation_id, creds.user_dn)))

        self.app.put(url="/delegation/%s/credential" % creds.delegation_id,
                     params=proxy,
                     status=400)
예제 #17
0
    def delete(self, dlg_id, start_response):
        """
        Delete the delegated credentials from the database
        """
        user = request.environ['fts3.User.Credentials']

        if dlg_id != user.delegation_id:
            raise HTTPForbidden('The requested ID and the credentials ID do not match')

        cred = Session.query(Credential).get((user.delegation_id, user.user_dn))
        if not cred:
            raise HTTPNotFound('Delegated credentials not found')
        else:
            try:
                Session.delete(cred)
                Session.commit()
            except Exception:
                Session.rollback()
                raise
            start_response('204 No Content', [])
            return ['']
예제 #18
0
    def delete(self, dlg_id, start_response):
        """
        Delete the delegated credentials from the database
        """
        user = request.environ['fts3.User.Credentials']

        if dlg_id != user.delegation_id:
            raise HTTPForbidden('The requested ID and the credentials ID do not match')

        cred = Session.query(Credential).get((user.delegation_id, user.user_dn))
        if not cred:
            raise HTTPNotFound('Delegated credentials not found')
        else:
            try:
                Session.delete(cred)
                Session.commit()
            except Exception:
                Session.rollback()
                raise
            start_response('204 No Content', [])
            return ['']
예제 #19
0
    def unban_se(self, start_response):
        """
        Unban a storage element
        """
        storage = request.params.get('storage', None)
        if not storage:
            raise HTTPBadRequest('Missing storage parameter')

        banned = Session.query(BannedSE).get(storage)
        if banned:
            try:
                Session.delete(banned)
                Session.commit()
            except Exception:
                Session.rollback()
            log.warn("Storage %s unbanned" % storage)
        else:
            log.warn("Unban of storage %s without effect" % storage)

        start_response('204 No Content', [])
        return ['']
예제 #20
0
    def remove_user_from_cloud_storage(self, storage_name, id, start_response):
        """
        Delete credentials for a given user/vo
        """
        storage = Session.query(CloudStorage).get(storage_name)
        if not storage:
            raise HTTPNotFound('The storage does not exist')

        users = Session.query(CloudStorageUser)\
            .filter(CloudStorageUser.storage_name == storage_name)\
            .filter((CloudStorageUser.vo_name == id) | (CloudStorageUser.user_dn == id))

        try:
            for user in users:
                Session.delete(user)
            Session.commit()
        except:
            Session.rollback()
            raise

        start_response('204 No Content', [])
        return ['']
예제 #21
0
    def unban_dn(self, start_response):
        """
        Unban a user
        """
        dn = request.params.get('user_dn', None)
        if not dn:
            raise HTTPBadRequest('Missing user_dn parameter')

        banned = Session.query(BannedDN).get(dn)
        if banned:
            try:

                Session.delete(banned)
                Session.commit()
            except Exception:
                Session.rollback()
            log.warn("User %s unbanned" % dn)
        else:
            log.warn("Unban of user %s without effect" % dn)

        start_response('204 No Content', [])
        return ['']
예제 #22
0
    def delete_app(self, client_id):
        """
        Delete an application from the database
        """
        user = pylons.request.environ['fts3.User.Credentials']
        app = Session.query(OAuth2Application).get(client_id)
        if app is None:
            raise HTTPNotFound('Application not found')
        if app.owner != user.user_dn:
            raise HTTPForbidden()

        try:
            Session.delete(app)
            Session.query(OAuth2Token).filter(OAuth2Token.client_id == client_id).delete()
            Session.query(OAuth2Code).filter(OAuth2Code.client_id == client_id).delete()
            Session.commit()
        except:
            Session.rollback()
            raise

        log.info("Application removed: %s" % client_id)

        return None
예제 #23
0
    def unban_dn(self, start_response):
        """
        Unban a user
        """
        dn = request.params.get('user_dn', None)
        if not dn:
            raise HTTPBadRequest('Missing user_dn parameter')

        banned = Session.query(BannedDN).get(dn)
        if banned:
            try:

                Session.delete(banned)
                Session.commit()
            except Exception:
                Session.rollback()
            log.warn("User %s unbanned" % dn)
        else:
            log.warn("Unban of user %s without effect" % dn)

        audit_configuration('unban-dn', "User %s unbanned" % (dn))
        start_response('204 No Content', [])
        return ['']
예제 #24
0
    def validate_access_token(self, access_token, authorization):
        """
        Validate access token offline or online

        Description of the algorithm:
        - Validate access token offline (using cached keys) or online (using introspection RFC 7662).
        - If a credential already exists in the DB and has not expired, the new token is discarded and the old
        credential is used.
        - If a credential already exists in the DB but has expired, delete it.
        - If there's no credential, Instrospect the token to get additional information (if not done before). Then,
        exchange the access token with a refresh token. Store both tokens in the DB.

        :param access_token:
        :param authorization: attribute .is_valid is set to True if validation successful
        """
        authorization.is_valid = False

        if self._should_validate_offline():
            valid, credential = self._validate_token_offline(access_token)
        else:
            valid, credential = self._validate_token_online(access_token)
        if not valid:
            log.warning("Access token provided is not valid")
            return

        # Check if a credential already exists in the DB
        credential_db = Session.query(Credential).filter(Credential.dn == credential['sub']).first()
        if credential_db and credential_db.expired():
            log.debug("credential_db_has_expired")
            Session.delete(credential_db)
            Session.commit()
            credential_db = None

        if not credential_db:
            if self._should_validate_offline():
                log.debug("offline and not in db")
                # Introspect to obtain additional information
                valid, credential = self._validate_token_online(access_token)
                if not valid:
                    log.debug("Access token provided is not valid")
                    return
            # Store credential in DB
            log.debug("Store credential in DB")
            dlg_id = generate_delegation_id(credential['sub'], "")
            try:
                if 'wlcg' in credential['iss']:
                    # Hardcoded scope and audience for wlcg tokens. To change once the wlcg standard evolves
                    scope = 'offline_access openid storage.read:/ storage.modify:/ wlcg.groups'
                    audience = 'https://wlcg.cern.ch/jwt/v1/any'
                    access_token, refresh_token = oidc_manager.generate_token_with_scope(credential['iss'],
                                                                                         access_token,
                                                                                         scope,
                                                                                         audience,
                                                                                         )
                else:
                    refresh_token = oidc_manager.generate_refresh_token(credential['iss'], access_token)
            except Exception:
                return
            credential_db = self._save_credential(dlg_id, credential['sub'],
                                                  str(access_token) + ':' + str(refresh_token),
                                                  self._generate_voms_attrs(credential),
                                                  datetime.utcfromtimestamp(credential['exp']))

        authorization.is_oauth = True
        authorization.token = credential_db.proxy.split(':')[0]
        authorization.dlg_id = credential_db.dlg_id
        authorization.expires_in = credential_db.termination_time - datetime.utcnow()
        if authorization.expires_in > timedelta(seconds=0):
            authorization.credentials = self._get_credentials(credential_db.dlg_id)
            if authorization.credentials:
                authorization.is_valid = True
예제 #25
0
 def discard_refresh_token(self, client_id, refresh_token):
     token = Session.query(OAuth2Token).get((client_id, refresh_token))
     if token is not None:
         Session.delete(token)
         Session.commit()
예제 #26
0
 def discard_authorization_code(self, client_id, code):
     auth_code = Session.query(OAuth2Code).get(code)
     if auth_code is not None:
         Session.delete(auth_code)
         Session.commit()