def post(self, user_id): """ Create User-Organisation relationship """ data = self.get_json_body(required=['organisation_id']) organisation_id = data['organisation_id'] pre_verified = data.get('pre_verified', False) try: organisation = yield perch.Organisation.get(organisation_id) except couch.NotFound: raise HTTPError(400, 'Organisation does not exist') if organisation.state != State.approved: raise HTTPError(400, 'Organisation is not approved') user_org = yield perch.UserOrganisation.create( user=self.user, id=organisation_id, user_id=user_id, pre_verified=pre_verified ) user = user_org.parent msg = ("created user-organisation link, user id: {}, " "organisation id: {}".format(user_id, organisation_id)) audit_log.info(self, msg) if not (self.user.is_reseller() and data.get('pre_verified', False)): yield email.send_join_request_emails(user, organisation) self.finish({ 'status': 200, 'data': user.clean() })
def get(self): """ Retrieve licensors """ source_id_type = self.get_argument('source_id_type', None) source_id = self.get_argument('source_id', None) if not source_id_type or not source_id: raise HTTPError( 400, 'Must have "source_id_type" and "source_id" parameters') try: translated_id = common.translate_id_pair({ 'source_id_type': source_id_type, 'source_id': source_id }) except ValueError: raise HTTPError(400, '{} is an invalid hub key'.format(source_id)) try: result = yield licensors.get_asset_licensors( translated_id['source_id_type'], translated_id['source_id']) self.finish(result) except httpclient.HTTPError as exc: body = json.loads(exc.response.body) raise HTTPError(exc.response.code, body)
def post(self): """Create user""" data = self.get_json_body() try: password = data.pop('password') except KeyError: errors = [{ 'field': 'password', 'message': 'user "password" is missing' }] # check for other validation errors try: yield perch.User(**data).validate() except exceptions.ValidationError as exc: errors.extend(exc.args[0]) raise HTTPError(400, errors) try: user = yield perch.User.create(self.user, password, **data) except exceptions.ValidationError as exc: raise HTTPError(400, exc.args[0]) audit_log.info(self, "user created, user_id: {}".format(user.id)) # only send verification email if hash exists if (getattr(user, 'verification_hash', None)) is not None: audit_log.info(self, "send verification email to user_id: {}".format(user.id)) yield email.send_verification_email(user) self.finish({ 'status': 200, 'data': user.clean() })
def get(self, repository_id=None, entity_type=None, entity_id=None): if repository_id is None: try: hub_key = self.get_query_argument('hub_key') except MissingArgumentError: raise HTTPError(400, 'hub_key parameter is required') try: parts = parse_hub_key(hub_key) except ValueError: raise HTTPError(404, 'Invalid hub key') if parts['schema_version'] == 's0': raise HTTPError( 404, 'Only hub keys matching ' 'schema >= s1 are supported') else: parts = { 'repository_id': repository_id, 'entity_type': entity_type, 'entity_id': entity_id } try: entity = yield get_entity(parts['repository_id'], parts['entity_type'], parts['entity_id']) except httpclient.HTTPError, e: raise HTTPError(e.code, e.message)
def get(self, repository_id, set_id): """ Return all assets associated to a set :param repository_id: the id of the repository :param set_id: the id of an offer :return: A JSON object containing an offer """ repository = DatabaseConnection(repository_id) set_exists = yield Set.exists(repository, set_id) if not set_exists: raise HTTPError(404, "Set {} not found".format(set_id)) page = int(self.get_argument("page", "1")) page_size = int(self.get_argument("page_size", "100")) page_size = min(page_size, 1000) elements = yield Set.get_elements(repository, set_id, page, page_size) self.finish({ 'status': 200, 'data': { 'assets': [e.split('/')[-1] for e in elements] } })
class OffersHandler(BaseHandler): """ Handler for offers """ METHOD_ACCESS = { "POST": BaseHandler.READ_ACCESS, "OPTIONS": BaseHandler.READ_ACCESS } @gen.coroutine def post(self): """ Retrieve offers by id and id type """ try: ids = [common.translate_id_pair(i) for i in self.get_json_body()] except ValueError, e: raise HTTPError(400, "Invalid id submitted : {}".format(e)) try: result = yield offers.get_asset_offers(ids) self.finish(result) except httpclient.HTTPError as exc: body = json.loads(exc.response.body) raise HTTPError(exc.response.code, body)
def get(self, organisation_id): """Get an organisation""" try: result = yield perch.Organisation.get(organisation_id) except couch.NotFound: raise HTTPError(404, 'Not Found') self.finish({'status': 200, 'data': result.clean()})
def post(self): """ Retrieve offers by id and id type """ try: ids = [common.translate_id_pair(i) for i in self.get_json_body()] except ValueError, e: raise HTTPError(400, "Invalid id submitted : {}".format(e))
def get_asset_licensors(source_id_type, source_id): """ Get licensors from repository services for list of assets :param source_id_type - The id type of the asset to get :param source_id - The id of the id type for the asset to get """ response = yield get_asset_repositories(source_id_type, source_id) if 'errors' in response: raise HTTPError(response['status'], response['errors']) outputs = [] for repository in response['data']['repositories']: result = (yield get_licensors_from_one_repo(repository))[0] if 'errors' in result: raise HTTPError(result['status'], result['errors']) if 'data' in result: outputs.append(result['data']['organisation']) raise Return({'status': 200, 'data': outputs})
def _validate_offer_expiry(dbconn, offer_id, expires): """ Check offer is not expired and that expires is a valid date :param repository_id: id of repository/namespace :param offer_id: id of offer :param expires: datetime """ if isinstance(dbconn, basestring): dbconn = DatabaseConnection(dbconn) try: arrow.get(expires) except ParserError: raise HTTPError(400, "Invalid expires") now = arrow.utcnow().isoformat() expired = yield Offer.expired(dbconn, offer_id, now) if expired: raise HTTPError(400, "Already expired")
def put(self, user_id): """Change the user password""" body = self.get_json_body(required=['previous', 'password']) try: user = yield perch.User.get(user_id) except couch.NotFound: raise HTTPError(403, 'Forbidden') try: yield user.change_password(body['previous'], body['password']) except exceptions.Unauthorized: raise HTTPError(401, 'Unauthorized') audit_log.info(self, "user password changed, user id: {}".format(user_id)) self.finish({ 'status': 200, 'data': { 'message': 'password changed' } })
def delete(self, repository_id, set_id, asset_id): """ Create the link between an element and a set. :param repository_id: the id of the repository :param set_id: the id of an offer :return: A JSON object containing an offer """ repository = DatabaseConnection(repository_id) set_exists = yield Set.exists(repository, set_id) if not set_exists: raise HTTPError(404, "Set {} not found".format(set_id)) asset_exists = yield Asset.exists(repository, asset_id) if not asset_exists: raise HTTPError(404, "Asset {} not found".format(asset_id)) yield Set.remove_elements(repository, set_id, [asset_id]) self.finish({'status': 200})
def get(self, repository_id, set_id, asset_id): """ Tells if an element is part of a set. :param repository_id: the id of the repository :param set_id: the id of an offer :return: A JSON object containing an offer """ repository = DatabaseConnection(repository_id) set_exists = yield Set.exists(repository, set_id) if not set_exists: raise HTTPError(404, "Set {} not found".format(set_id)) asset_exists = yield Asset.exists(repository, asset_id) if not asset_exists: raise HTTPError(404, "Asset {} not found".format(asset_id)) res = yield Set.has_element(repository, set_id, asset_id) self.finish({'status': 200, 'data': {"is_member": res}})
def get(self, repository_id, agreement_id): """ Retrieve an agreement :param repository_id: the repository's ID :param agreement_id: the agreement's ID """ db = DatabaseConnection(repository_id) obj = yield Agreement.retrieve(db, agreement_id) if not obj: raise HTTPError(404, "Agreement {} not found".format(agreement_id)) self.finish({'status': 200, 'data': obj})
def get(self, repository_id, offer_id): """ Retrieve one offer by offer_id :param repository_id: the id of the repository :param offer_id: the id of an offer :return: A JSON object containing an offer """ offer_obj = yield Offer.retrieve(DatabaseConnection(repository_id), offer_id) if not offer_obj: raise HTTPError(404, "offer {} not found".format(offer_id)) self.finish({'status': 200, 'data': offer_obj})
def put(self, user_id): """Verify a user based on verification hash""" body = self.get_json_body(required=['verification_hash']) try: user = yield perch.User.verify(user_id, body.get('verification_hash')) except exceptions.ValidationError as exc: raise HTTPError(400, exc.args[0]) audit_log.info(self, "user verified, user id: {}".format(user_id)) self.finish({ 'status': 200, 'data': user.clean() })
def get(self): """ Get all organisations (authenticated) Or get organisation by filtered by name (optional authentication) """ state = self.get_argument('state', None) name = self.get_query_argument('name', None) if name: try: result = yield perch.Organisation.get_by_name(searchName=name) except exceptions.NotFound as exc: raise HTTPError(404, "Not found") else: if self.user: try: result = yield perch.Organisation.all(state=state) except exceptions.ValidationError as exc: raise HTTPError(400, exc.args[0]) else: raise HTTPError( 401, "Can only query by name when no valid Token sent") self.finish({'status': 200, 'data': [r.clean() for r in result]})
def put(self, user_id): """Update a user""" data = self.get_json_body() user = yield perch.User.get(user_id) try: yield user.update(self.user, **data) except exceptions.ValidationError as exc: raise HTTPError(400, exc.args[0]) msg = "updated user, user id: {}, data: {}".format(user_id, data) audit_log.info(self, msg) self.finish({ 'status': 200, 'data': user.clean() })
def post(self, organisation_id): """Query for the reference links for an organisation""" data = self.get_json_body(required=['source_id', 'source_id_type']) source_id = data['source_id'] source_id_type = data['source_id_type'] organisation = yield perch.Organisation.get(organisation_id) reference_links = getattr(organisation, 'reference_links', {}) links = reference_links.get('links', {}) link = links.get(source_id_type) if not link: raise HTTPError(404, 'Not Found') self.finish({'status': 200, 'data': link.format(source_id=source_id)})
def get(self, repository_id, set_id): """ Retrieve one offer by set_id :param repository_id: the id of the repository :param set_id: the id of an offer :return: A JSON object containing an offer """ repository = DatabaseConnection(repository_id) set_exists = yield Set.exists(repository, set_id) if not set_exists: raise HTTPError(404, "Set {} not found".format(set_id)) set_obj = yield Set.retrieve(repository, set_id) self.finish({'status': 200, 'data': set_obj})
def post(self): """Create an organisation""" data = self.get_json_body() data['created_by'] = self.user.id try: organisation = yield perch.Organisation.create(self.user, **data) except exceptions.ValidationError as exc: raise HTTPError(400, exc.args[0]) msg = ("organisation created, organisation id:{}, data: {}".format( organisation.id, data)) audit_log.info(self, msg) if not (self.user.is_reseller() and data.get('pre_verified', False)): yield email.send_create_request_emails(self.user, organisation) self.finish({'status': 200, 'data': organisation.clean()})
def post(self, repository_id, set_id): """ Replace all the elements in a set. :param repository_id: the id of the repository :param set_id: the id of an offer :return: A JSON object containing an offer """ body = self.get_json_body(['assets']) repository = DatabaseConnection(repository_id) set_exists = yield Set.exists(repository, set_id) if not set_exists: raise HTTPError(404, "Set {} not found".format(set_id)) yield Set.set_elements(repository, set_id, body['assets']) self.finish({'status': 200})
def post(self, repository_id): """ Create one offer. If the data contains an expires key, then that is the id of an offer that should be replaced with the new one. :param repository_id: str """ offer_id = yield Offer.new_offer( DatabaseConnection(repository_id), self.request.body, assigner=self.organisation_id, format=self.data_format()) errors = [] if errors: raise HTTPError(400, errors) else: audit.log_added_offer(offer_id, self.token) self.set_header('Content-Type', 'application/json; charset=UTF-8') self.finish({'status': 200, 'data': {'id': offer_id}})
class EntityHandler(BaseHandler): """ Handler for querying entities using their hub key NOTE: s0 hub keys are unsupported because the do not contain the repository ID """ @coroutine def get(self, repository_id=None, entity_type=None, entity_id=None): if repository_id is None: try: hub_key = self.get_query_argument('hub_key') except MissingArgumentError: raise HTTPError(400, 'hub_key parameter is required') try: parts = parse_hub_key(hub_key) except ValueError: raise HTTPError(404, 'Invalid hub key') if parts['schema_version'] == 's0': raise HTTPError( 404, 'Only hub keys matching ' 'schema >= s1 are supported') else: parts = { 'repository_id': repository_id, 'entity_type': entity_type, 'entity_id': entity_id } try: entity = yield get_entity(parts['repository_id'], parts['entity_type'], parts['entity_id']) except httpclient.HTTPError, e: raise HTTPError(e.code, e.message) if not entity: raise HTTPError(404, 'Not found') self.finish({'status': 200, 'data': entity})
def put(self, organisation_id): """Update an organisation""" data = self.get_json_body() try: organisation = yield perch.Organisation.get(organisation_id) except couch.NotFound: raise HTTPError(404, 'Not Found') yield organisation.update(self.user, **data) audit_log.info( self, "organisation updated, organisation_id:{}".format(organisation_id)) if 'state' in data: creator = yield perch.User.get(organisation.created_by) yield email.send_request_update_email(creator, organisation, organisation.state, self.user, 'create') self.finish({'status': 200, 'data': organisation.clean()})
def put(self, user_id, organisation_id): """ Update the join state or role of a user's organisation """ user_org = yield perch.UserOrganisation.get([user_id, organisation_id]) body = self.get_json_body() if not ('state' in body or 'role' in body): raise HTTPError(400, 'state or role is required') yield user_org.update(self.user, **body) if 'state' in body: # Send email to user notifying of change in join state organisation = yield perch.Organisation.get(organisation_id) yield email.send_request_update_email( user_org.parent, organisation, body['state'], self.user, 'join') self.finish({'status': 200, 'data': user_org.parent.clean()})