def check_create_other(backend_input, instance, context): """Admins/superadmins can create ResourceAdminships. Admins/superadmins can create a new ResourceAdminship instance for a given resource and a given user, only if the user has role 'serviceadmin', she/he does not already admin the resource and user's Organisation is the same as the Resource's Organisation. The ResourceAdminship created by admins/superadmins has state 'approved'. """ admin = user_m.objects.get(id=backend_input['admin_id']) if admin.role != 'serviceadmin': raise ValidationError(_('Wrong admin role')) resource = r_m.objects.get(pk=backend_input['resource_id']) resource_org_id = resource.erp_bai_2_organisation.pk if resource_org_id != admin.organisation.id: raise ValidationError(_('Forbidden Resource Organisation')) try: sa_m.objects.get(admin=backend_input['admin_id'], resource=backend_input['resource_id']) raise ValidationError(_('Object exists')) except sa_m.DoesNotExist: backend_input['state'] = 'approved' return
def resource_update_eosc(backend_input, instance, context): eosc_req = create_eosc_api_json_resource(instance) if 'resourceOrganisation' not in eosc_req or eosc_req[ 'resourceOrganisation'] == None or len( eosc_req['resourceOrganisation'].strip()) == 0: raise ValidationError('Resource provider has not an eosc_id') url = EOSC_API_URL + 'resource' id = str(instance.id) username = context['auth/user'].username eosc_token = get_access_token(OIDC_URL, OIDC_REFRESH_TOKEN, OIDC_CLIENT_ID) headers = { 'Authorization': eosc_token, 'Accept': 'application/json', 'Content-Type': 'application/json', } logger.info('EOSC PORTAL API call to PUT resource \ with id %s to %s has been made by %s at %s \ ' % (id, url, username, datetime.now())) try: response = requests.put(url, headers=headers, json=eosc_req) response.raise_for_status() logger.info('Response status code: %s' % (response.status_code)) logger.info('Response json: %s' % (response.json())) instance.eosc_state = "Updated" instance.eosc_updated_at = datetime.now(timezone.utc) except requests.exceptions.RequestException as err: logger.info('Response status code: %s, %s, %s' % (url, err, response.json())) instance.eosc_state = "Error" raise ValidationError("EOSC API: " + response.json()['error']) instance.save() return instance
def check_create_other_own_organisation(backend_input, instance, context): """Provider Admins can create ResourceAdminships. Provider Admins can create a new ResourceAdminship instance for a given resource and a given user, only if: - the user has role 'serviceadmin' - she/he does not already admin - the resource user's Organisation is the same as the Resource's Organisation - the Resource's Organsation is the same as the Provider Admins The ResourceAdminship created by Provider Admins has state 'approved'. """ auth_user = context['auth/user'] user_org_id = auth_user.organisation.id admin = user_m.objects.get(id=backend_input['admin_id']) if admin.role != 'serviceadmin': raise ValidationError(_('Wrong admin role')) resource = r_m.objects.get(pk=backend_input['resource_id']) resource_org_id = resource.erp_bai_2_organisation.pk if not admin.organisation: raise ValidationError(_('No organisation')) if resource_org_id != admin.organisation.id: raise ValidationError(_('Forbidden Resource Organisation')) if resource_org_id != user_org_id: raise ValidationError(_('Forbidden Resource Organisation')) try: sa_m.objects.get(admin=backend_input['admin_id'], resource=backend_input['resource_id']) raise ValidationError(_('ResourceAdminship Object exists')) except sa_m.DoesNotExist: backend_input['state'] = 'approved' return
def update_owns_service_unique(backend_input, instance, context): """CIDL update rules for serviceadmins. A serviceadmin can update a CIDL only if she/he admins the Service of the CIDL. She/he should also admin the updated Service. If there is an update in the value of the service_type, it should be unique. """ auth_user = context['auth/user'] auth_user_id = str(auth_user.id) service_admins_ids = instance.service_admins_ids.split(",") if auth_user_id not in service_admins_ids: raise ValidationError(_('Unauthorized action')) try: sa_m.objects.get(admin=auth_user_id, service=backend_input['service_id_id']) except sa_m.DoesNotExist: raise ValidationError(_('User should admin the service')) if (backend_input['service_type'] == instance.service_type): return try: cidl_m.objects.get(service_type=backend_input['service_type']) raise ValidationError(_('Service_type should be unique')) except cidl_m.DoesNotExist: return
def provider_approve_eosc(backend_input, instance, context): url = EOSC_API_URL + 'provider/verifyProvider/' + instance.eosc_id id = str(instance.id) username = context['auth/user'].username eosc_token = get_access_token(OIDC_URL, OIDC_REFRESH_TOKEN, OIDC_CLIENT_ID) headers = {'Authorization': 'Bearer ' + eosc_token} params = '''active=true&status=approved''' logger.info('EOSC PORTAL API call to PATCH provider approval \ with id %s to %s has been made by %s at %s \ ' % (id, url, username, datetime.now())) try: response = requests.patch(url + '/?' + params, headers=headers) response.raise_for_status() logger.info('Response status code: %s' % (response.status_code)) logger.info('Response json: %s' % (response.json())) instance.eosc_state = response.json()['status'] instance.eosc_id = response.json()['id'] instance.eosc_published_at = datetime.now(timezone.utc) except requests.exceptions.RequestException as err: try: logger.info('Response status code: %s, %s, %s' % (url, err, response.json())) raise ValidationError("EOSC API: " + response.json()['error']) except: raise ValidationError( "EOSC API: Provider should publish at least one resource to be fully approved" ) instance.save() return instance
def check_create_other(backend_input, instance, context): admin = user_m.objects.get(id=backend_input['admin_id']) if admin.role != 'serviceadmin': raise ValidationError(_('Wrong admin role')) try: sa_m.objects.get(admin=backend_input['admin_id'], service=backend_input['service_id']) raise ValidationError(_('Object exists')) except sa_m.DoesNotExist: backend_input['state'] = 'approved' return
def set_cycle(backend_input, instance, context): assert instance is None kwargs = context['request/meta/kwargs'] endpoint_id = kwargs['id0'] endpoint = get_endpoint_for_update(endpoint_id) if not endpoint.public: raise ValidationError('Cannot post to a private endpoint') if endpoint.current_cycle is None: raise ValidationError('No open cycle') backend_input['cycle_id'] = endpoint.current_cycle_id
def provider_update_eosc(backend_input, instance, context): provider_email = context['auth/user'].email eosc_req = create_eosc_api_json_provider(instance, provider_email) url = EOSC_API_URL + 'provider' id = str(instance.id) username = context['auth/user'].username eosc_token = get_access_token(OIDC_URL, OIDC_REFRESH_TOKEN, OIDC_CLIENT_ID) headers = { 'Authorization': eosc_token, 'Accept': 'application/json', 'Content-Type': 'application/json', } logger.info('EOSC PORTAL API call to PUT provider \ with id %s to %s has been made by %s at %s \ ' % (id, url, username, datetime.now())) try: response = requests.put(url, headers=headers, json=eosc_req) response.raise_for_status() logger.info('Response status code: %s' % (response.status_code)) logger.info('Response json: %s' % (response.json())) instance.eosc_updated_at = datetime.now(timezone.utc) except requests.exceptions.RequestException as err: logger.info('Response status code: %s, %s, %s' % (url, err, response.json())) raise ValidationError("EOSC API: " + response.json()['error']) instance.save() return instance
def resource_deactivate_eosc(backend_input, instance, context): url = EOSC_API_URL + 'service/publish/' + instance.eosc_id id = str(instance.id) username = context['auth/user'].username eosc_token = get_access_token(OIDC_URL, OIDC_REFRESH_TOKEN, OIDC_CLIENT_ID) headers = {'Authorization': 'Bearer ' + eosc_token} params = '''active=false''' logger.info('EOSC PORTAL API call to PATCH resource deactivate \ with id %s to %s has been made by %s at %s \ ' % (id, url, username, datetime.now())) try: response = requests.patch(url + '/?' + params, headers=headers) response.raise_for_status() logger.info('Response status code: %s' % (response.status_code)) logger.info('Response json: %s' % (response.json())) instance.eosc_state = response.json()['status'] instance.eosc_id = response.json()['id'] instance.eosc_published_at = datetime.now(timezone.utc) except requests.exceptions.RequestException as err: logger.info('Response status code: %s, %s, %s' % (url, err, response.json())) instance.eosc_state = "error" raise ValidationError("EOSC API: " + response.json()['error']) instance.save() return instance
def unique(backend_input, instance, context): """Admins/superadmins create CIDL with unique service_type. """ try: cidl_m.objects.get(service_type=backend_input['service_type']) raise ValidationError(_('Service_type should be unique')) except cidl_m.DoesNotExist: return
def owned(backend_input, instance, context): auth_user = context.extract('auth/user') auth_user_id = str(auth_user.id) service_admins_ids = instance.service_admins_ids.split(",") if auth_user_id in service_admins_ids: return else: raise ValidationError("Unauthorized action")
def update_organisation_owned(backend_input, instance, context): """Servicadmins must belong to the same Organisation as the Contact Information they are about to edit. """ auth_user = context['auth/user'] user_org_id = str(auth_user.organisation.id) contact_org_id = str(backend_input.get('organisation_id')) if not contact_org_id == user_org_id: raise ValidationError(_('Unauthorized organisation(s)'))
def check_create_other(backend_input, instance, context): """Admins/superadmins can create ServiceAdminships. Admins/superadmins can create a new ServiceAdminship instance for a given service and a given user, only if the user has role 'serviceadmin' and she/he does not already admin the service. The ServiceAdminship created by admins/superadmins has state 'approved'. """ admin = user_m.objects.get(id=backend_input['admin_id']) if admin.role != 'serviceadmin': raise ValidationError(_('Wrong admin role')) try: sa_m.objects.get(admin=backend_input['admin_id'], service=backend_input['service_id']) raise ValidationError(_('Object exists')) except sa_m.DoesNotExist: backend_input['state'] = 'approved' return
def update_organisation_owned(backend_input, instance, context): """ Serviceproviders can edit the Organisation they belong to. """ auth_user = context['auth/user'] user_org_id = str(auth_user.organisation.id) org_id = str(instance.pk) if not org_id == user_org_id: raise ValidationError(_('Unauthorized organisation(s)'))
def check_create_self(backend_input, instance, context): auth_user = context.extract('auth/user') try: sa_m.objects.get(admin=auth_user.id, service=backend_input['service_id']) raise ValidationError(_('Object exists')) except sa_m.DoesNotExist: backend_input['admin_id'] = auth_user.id backend_input['state'] = 'pending' return
def bulk_upload(backend_input, cycle, context): messages_input = backend_input['cycle_messages'] endpoint = cycle.endpoint if endpoint.current_cycle != cycle: raise ValidationError("Cycle is not current") messages = [] for message_input in messages_input: messages.append( models.Message(endpoint=endpoint, cycle=cycle, **message_input)) models.Message.objects.bulk_create(messages)
def create_owns_service_unique(backend_input, instance, context): """Serviceadmins can conditionally create CIDLs. A serviceadmin can create a CIDL only if he/she admins the Service of the CIDL. The CIDL is created only if the service_type is unique. """ auth_user = context['auth/user'] auth_user_id = str(auth_user.id) try: sa_m.objects.get(admin=auth_user_id, service=backend_input['service_id_id']) except sa_m.DoesNotExist: raise ValidationError(_('User should admin the service')) try: cidl_m.objects.get(service_type=backend_input['service_type']) raise ValidationError(_('Service_type should be unique')) except cidl_m.DoesNotExist: return
def organisation_owned(backend_input, instance, context): """Servicadmins must belong to Resource's organisation. The resource's organisations must be the same as the one the serviceadmin belongs to. """ auth_user = context['auth/user'] resource_org_id = str(backend_input.get('erp_bai_2_organisation_id')) user_org_id = str(auth_user.organisation.id) if not user_org_id == resource_org_id: raise ValidationError(_('Unauthorized organisation(s)'))
def create_owns_service(backend_input, instance, context): """ Serviceadmins can create ServiceVersion of Services the admin. """ auth_user = context['auth/user'] auth_user_id = str(auth_user.id) try: sa_m.objects.get(admin=auth_user_id, service=backend_input['id_service_id']) except sa_m.DoesNotExist: raise ValidationError(_('User should admin the service'))
def owned(backend_input, instance, context): """Servicadmins can update Resources they own. A serviceadmin owns a Resource if resource's resource_admins_ids computed property contains the id of the user. The resource's organisations must be the same as the one the serviceadmin belongs to. """ auth_user = context['auth/user'] auth_user_id = str(auth_user.id) service_admins_ids = instance.resource_admins_ids.split(",") resource_org_id = str(backend_input.get('erp_bai_2_organisation_id')) user_org_id = str(auth_user.organisation.id) if not user_org_id == resource_org_id: raise ValidationError(_('Unauthorized organisation(s)')) if auth_user_id in service_admins_ids: return else: raise ValidationError(_('Unauthorized action'))
def organisation_owned(backend_input, instance, context): """Servicadmins must belong to Service's organisation(s). The service's organisations must be subset of the organisations in which the serviceadmin belongs. """ auth_user = context['auth/user'] service_orgs = backend_input.get('organisations', []) service_orgs_ids = [s['organisation_id'] for s in service_orgs] user_orgs_ids = [str(o.id) for o in auth_user.organisations.all()] if not set(service_orgs_ids).issubset(set(user_orgs_ids)): raise ValidationError(_('Unauthorized organisation(s)'))
def owned(backend_input, instance, context): """Servicadmins can update Services they own. A serviceadmin owns a Service if service's service_admins_ids computed property contains the id of the user. The service's organisations must be subset of the organisations in which the serviceadmin belongs. """ auth_user = context['auth/user'] auth_user_id = str(auth_user.id) service_admins_ids = instance.service_admins_ids.split(",") service_orgs = backend_input.get('organisations', []) service_orgs_ids = [s['organisation_id'] for s in service_orgs] user_orgs_ids = [str(o.id) for o in auth_user.organisations.all()] if not set(service_orgs_ids).issubset(set(user_orgs_ids)): raise ValidationError(_('Unauthorized organisation(s)')) if auth_user_id in service_admins_ids: return else: raise ValidationError(_('Unauthorized action'))
def update_owns_service(backend_input, instance, context): """ ServiceVersions update rules for serviceadmins. Serviceadmins can update a ServiceVersion if they own the Service of the ServiceVersion. If they choose to update the Service, they should also own the new Service. """ auth_user = context['auth/user'] auth_user_id = str(auth_user.id) service_admins_ids = instance.service_admins_ids.split(",") try: sa_m.objects.get(admin=auth_user_id, state='approved', service=backend_input['id_service_id']) except sa_m.DoesNotExist: raise ValidationError(_('User should admin the service')) if auth_user_id in service_admins_ids: return else: raise ValidationError(_('Unauthorized action'))
def check_update(backend_input, instance, context): TRANSITIONS = set([ ('pending', 'approved'), ('pending', 'rejected'), ('rejected', 'pending'), ('approved', 'pending'), ]) current_state = instance.state input_state = backend_input['state'] if (current_state, input_state) not in TRANSITIONS: raise ValidationError("Transition not allowed")
def check_create_self(backend_input, instance, context): """Serviceadmins can request ResourceAdminships. A user can create a ResourceAdminship instance only if she/he does not already admin the resource and user's Organisation is the same as the resource's Organisation. The ResourceAdminship created is not yet approved/rejected, so it is created with state 'pending'. """ auth_user = context['auth/user'] resource = r_m.objects.get(pk=backend_input['resource_id']) resource_org_id = resource.erp_bai_2_organisation.pk if resource_org_id != auth_user.organisation.id: raise ValidationError(_('Forbidden Resource Organisation')) try: sa_m.objects.get(admin=auth_user.id, resource=backend_input['resource_id']) raise ValidationError(_('Object exists')) except sa_m.DoesNotExist: backend_input['admin_id'] = auth_user.id backend_input['state'] = 'pending' return
def set_message_state(backend_input, cycle, context): objects = cycle.cycle_messages action_input = backend_input['cycle_messages'] if len(action_input) == 1 and action_input[0]['id'] == -1: state = action_input[0]['state'] else: message_ids = [msg['id'] for msg in action_input] states = set(msg['state'] for msg in action_input) if len(states) != 1: raise ValidationError("Must set the same state") state = states.pop() objects = objects.filter(id__in=message_ids) objects.update(state=state)
def update_unique(backend_input, instance, context): """CIDL update rules for admins/superadmins. If a admin/superadmin updates a CIDL, the new service_type value should be unique. """ if (backend_input['service_type'] == instance.service_type): return try: cidl_m.objects.get(service_type=backend_input['service_type']) raise ValidationError(_('Service_type should be unique')) except cidl_m.DoesNotExist: return
def get_access_token(oidc_url, refresh_token, client_id): obj = { 'grant_type': 'refresh_token', 'refresh_token': refresh_token, 'client_id': client_id, 'scope': 'openid email profile' } try: response = requests.post(oidc_url, data=obj) response.raise_for_status() except requests.exceptions.RequestException as err: logger.info('Response status code: %s, %s, %s' % (oidc_url, err, response.json())) raise ValidationError("AAI: " + response.json()['error']) return response.json()['access_token']
def check_unique(backend_input, instance, context): backend_email = backend_input['email'] instance_email = instance.email if backend_email != instance_email: try: user_m.objects.get(email=backend_email) raise ValidationError( details={'email': 'Email unique contstraint failed'}) except user_m.DoesNotExist: pass backend_username = backend_input['username'] instance_username = instance.username if backend_username != instance_username: try: user_m.objects.get(username=backend_username) raise ValidationError( details={'username': '******'}) except user_m.DoesNotExist: pass return
def check_update(backend_input, instance, context): """Check allowed transitions between ResourceAdminship instances. The transition between 'approved' and 'rejected' must go via 'pending'. """ TRANSITIONS = set([ ('pending', 'approved'), ('pending', 'rejected'), ('rejected', 'pending'), ('approved', 'pending'), ]) current_state = instance.state input_state = backend_input['state'] if (current_state, input_state) not in TRANSITIONS: raise ValidationError(_('Transition not allowed'))