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
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 ['']
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
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()
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()
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
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()
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()
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)
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
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 ['']
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
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
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)
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 ['']
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)
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 ['']
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 ['']
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 ['']
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 ['']
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
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 ['']
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
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()
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()