def auth(self, username, password): """ Returns a dict of user information. Raises AutheError otherwise. """ password = self.digest(password) with self.session as session: query = session.query(AuthRecord) if not query.first(): raise AuthError("No username / password configured in indexd") # Select on username / password. query = query.filter(AuthRecord.username == username) query = query.filter(AuthRecord.password == password) try: query.one() except NoResultFound as err: raise AuthError("username / password mismatch") context = { "username": username, # TODO include other user information } return context
def authz(self, method, resource): if not self.arborist: raise AuthError( "Arborist is not configured; cannot perform authorization check" ) try: # A successful call from arborist returns a bool, else returns ArboristError try: authorized = self.arborist.auth_request( get_jwt_token(), "indexd", method, resource) except Exception as e: logger.error( f"Request to Arborist failed; now checking admin access. Details:\n{e}" ) authorized = False if not authorized: # admins can perform all operations is_admin = self.arborist.auth_request( get_jwt_token(), "indexd", method, ["/services/indexd/admin"]) if not is_admin and not resource: # if `authz` is empty (no `resource`), admin == access to # `/programs` (deprecated - for backwards compatibility). is_admin = self.arborist.auth_request( get_jwt_token(), "indexd", method, ["/programs"]) if is_admin: logger.warning( "The indexd admin '/programs' logic is deprecated. Please update your policy to '/services/indexd/admin'" ) if not is_admin: raise AuthError("Permission denied.") except Exception as err: logger.error(err) raise AuthzError(err)
def authz(self, method, resource): if not self.arborist: raise AuthError( "Arborist is not configured; cannot perform authorization check" ) if not resource: # TODO: fix this. Setting authz to [] throws this error but # admins should be able to do it raise AuthError("Permission denied.") if not self.arborist.auth_request(get_jwt_token(), "indexd", method, resource): raise AuthError("Permission denied.")
def authz(self, method, resource): if not self.arborist: raise AuthError( "Arborist is not configured; cannot perform authorization check" ) if not resource: # if the `authz` is empty, admins should still be able to perform # operations on the record. For now, admin = access to `/programs`. # TODO: Figure out how to handle Gen3 operational admins in a better way resource = ["/programs"] if not self.arborist.auth_request(get_jwt_token(), "indexd", method, resource): raise AuthError("Permission denied.")
def get_signed_url_for_object(self, object_id, access_id): fence_server = self.url api_url = fence_server.rstrip("/") + "/data/download/" url = api_url + object_id headers = flask.request.headers if "AUTHORIZATION" not in headers: logger.error("Bearer Token not available.") raise AuthError("Not Authorized. Access Token Required.") if access_id: url += "?protocol=" + access_id try: req = requests.get(url, headers=headers) except Exception as e: logger.error("failed to reach fence at {0}: {1}".format( url + object_id, e)) raise IndexdUnexpectedError("Failed to retrieve access url") if req.status_code == 404: logger.error( "Not found. Fence could not find {}: {} with access id: {}". format(url + object_id, req.text, access_id)) raise IndexNoRecordFound( "No document with id:{} with access_id:{}".format( object_id, access_id)) if req.status_code == 401: raise AuthzError( "Unauthorized: Access denied due to invalid credentials.") elif req.status_code != 200: err_msg = "Unable to get presigned URL from Fence" logger.error("{} - code: {} - details:\n{}".format( err_msg, req.status_code, req.text)) raise IndexdUnexpectedError(code=req.status_code, message=err_msg) return req.json()
def delete(self, username): with self.session as session: user = (session.query(AuthRecord).filter( AuthRecord.username == username).first()) if not user: raise AuthError("User {} doesn't exist".format(username)) session.delete(user)
def get_signed_url_for_object(self, object_id, access_id): fence_server = self.url api_url = fence_server.rstrip("/") + "/data/download/" url = api_url + object_id headers = flask.request.headers if "AUTHORIZATION" not in headers: logger.error("Bearer Token not available.") raise AuthError("Not Authorized. Access Token Required.") if access_id: url += "?protocol=" + access_id try: req = requests.get(url, headers=headers) except Exception as e: logger.error("failed to reach fence at {0}: {1}".format( url + object_id, e)) raise UnexpectedError("Failed to retrieve access url") if req.status_code == 404: logger.error( "Not found. Fence could not find {}: {} with access id: {}". format(url + object_id, req.text, access_id)) raise IndexNoRecordFound( "No document with id:{} with access_id:{}".format( object_id, access_id)) elif req.status_code != 200: raise UnexpectedError(req.text) return req.json()
def mock_authz(method, resources): for resource in resources: if (method, resource) not in allowed_permissions: raise AuthError( "Mock indexd.auth.authz: ({},{}) is not one of the allowed permissions: {}".format( method, resource, allowed_permissions ) )
def add(self, username, password): password = self.digest(password) with self.session as session: if (session.query(AuthRecord).filter( AuthRecord.username == username).first()): raise AuthError("User {} already exists".format(username)) new_record = AuthRecord(username=username, password=password) session.add(new_record)
def authz(self, method, resource): if not self.arborist: raise AuthError( "Arborist is not configured; cannot perform authorization check" ) try: # A successful call from arborist returns a bool, else returns ArboristError if not self.arborist.auth_request(get_jwt_token(), "indexd", method, resource): # admins can perform all operations is_admin = self.arborist.auth_request( get_jwt_token(), "indexd", method, ["/services/indexd/admin"]) if not is_admin and not resource: # if `authz` is empty (no `resource`), admin == access to # `/programs` (deprecated - for backwards compatibility). is_admin = self.arborist.auth_request( get_jwt_token(), "indexd", method, ["/programs"]) if not is_admin: raise AuthError("Permission denied.") except Exception as err: logger.error(err) raise AuthzError(err)
def auth(self, username, password): ''' Returns a dict of user information. Raises AutheError otherwise. ''' password = self.digest(password) with self.session as session: query = session.query(AuthRecord) # Select on username / password. query = query.filter(AuthRecord.username == username) query = query.filter(AuthRecord.password == password) try: query.one() except NoResultFound as err: raise AuthError('username / password mismatch') context = { 'username': username, # TODO include other user information } return context