def save_organisation(): confirm_write_access() data = current_request.get_json() _clear_api_keys(data) cleanse_short_name(data) data["identifier"] = str(uuid.uuid4()) administrators = data.get("administrators", []) intended_role = data.get("intended_role", "admin") message = data.get("message", None) res = save(Organisation, custom_json=data) user = User.query.get(current_user_id()) organisation = res[0] for administrator in administrators: invitation = OrganisationInvitation(hash=generate_token(), message=message, invitee_email=administrator, organisation_id=organisation.id, user_id=user.id, intended_role=intended_role, expiry_date=default_expiry_date(), created_by=user.uid) invitation = db.session.merge(invitation) mail_organisation_invitation({ "salutation": "Dear", "invitation": invitation, "base_url": current_app.app_config.base_url, "recipient": administrator }, organisation, [administrator]) mail_platform_admins(organisation) return res
def save_service(): data = current_request.get_json() validate_ip_networks(data) _token_validity_days(data) data["status"] = STATUS_ACTIVE cleanse_short_name(data, "abbreviation") # Before the JSON is cleaned in the save method administrators = data.get("administrators", []) message = data.get("message", None) res = save(Service, custom_json=data, allow_child_cascades=False, allowed_child_collections=["ip_networks"]) service = res[0] user = User.query.get(current_user_id()) for administrator in administrators: invitation = ServiceInvitation(hash=generate_token(), message=message, invitee_email=administrator, service_id=service.id, user=user, intended_role="admin", expiry_date=default_expiry_date(), created_by=user.uid) invitation = db.session.merge(invitation) mail_service_invitation({ "salutation": "Dear", "invitation": invitation, "base_url": current_app.app_config.base_url, "wiki_link": current_app.app_config.wiki_link, "recipient": administrator }, service, [administrator]) mail_platform_admins(service) service.ip_networks return res
def _validate_collaboration(data, organisation, new_collaboration=True): cleanse_short_name(data) expiry_date = data.get("expiry_date") if expiry_date: dt = datetime.utcfromtimestamp(int(expiry_date)) + timedelta(hours=4) data["expiry_date"] = datetime(year=dt.year, month=dt.month, day=dt.day, hour=0, minute=0, second=0) else: data["expiry_date"] = None # Check if the status needs updating if new_collaboration or "status" not in data: data["status"] = STATUS_ACTIVE else: collaboration = Collaboration.query.get(data["id"]) if collaboration.status == STATUS_EXPIRED and (not expiry_date or data["expiry_date"] > datetime.now()): data["status"] = STATUS_ACTIVE if collaboration.status == STATUS_SUSPENDED: data["status"] = STATUS_ACTIVE if _do_name_exists(data["name"], organisation.id, existing_collaboration="" if new_collaboration else data["name"]): raise BadRequest(f"Collaboration with name '{data['name']}' already exists within " f"organisation '{organisation.name}'.") if _do_short_name_exists(data["short_name"], organisation.id, existing_collaboration="" if new_collaboration else data["short_name"]): raise BadRequest(f"Collaboration with short_name '{data['short_name']}' already exists within " f"organisation '{organisation.name}'.") _assign_global_urn(data["organisation_id"], data)
def create_group(collaboration_id, data): cleanse_short_name(data) # Check uniqueness of name and short_name of group for the collaboration collaboration = Collaboration.query.get(collaboration_id) duplicates = [g.id for g in collaboration.groups if g.name == data["name"] or g.short_name == data["short_name"]] if duplicates: return {}, 201 _assign_global_urn(collaboration, data) data["identifier"] = str(uuid.uuid4()) res = save(Group, custom_json=data, allow_child_cascades=False) auto_provision_all_members_and_invites(res[0]) return res
def update_group(): data = current_request.get_json() collaboration_id = int(data["collaboration_id"]) confirm_collaboration_admin(collaboration_id) collaboration = Collaboration.query.get(collaboration_id) _assign_global_urn(collaboration, data) cleanse_short_name(data) res = update(Group, custom_json=data, allow_child_cascades=False) auto_provision_all_members_and_invites(res[0]) return res
def request_collaboration(): data = current_request.get_json() user = User.query.get(current_user_id()) organisation = Organisation.query \ .join(Organisation.schac_home_organisations) \ .filter(SchacHomeOrganisation.name == user.schac_home_organisation) \ .first() if not organisation: raise BadRequest(f"There is no organisation with a schac_home_organisation that equals the " f"schac_home_organisation {user.schac_home_organisation} of User {user.email}") data["requester_id"] = user.id cleanse_short_name(data) message = data["message"] auto_create = organisation.collaboration_creation_allowed entitlement = current_app.app_config.collaboration_creation_allowed_entitlement auto_aff = user.entitlement and entitlement in user.entitlement recipients = list(map(lambda membership: membership.user.email, organisation.organisation_memberships)) if auto_create or auto_aff: collaboration = do_save_collaboration(data, organisation, user, current_user_admin=True)[0] context = {"salutation": f"Dear {organisation.name} organisation admin,", "base_url": current_app.app_config.base_url, "collaboration": collaboration, "message": message, "organisation": organisation, "collaboration_creation_allowed_entitlement": entitlement, "user": user} if recipients: mail_automatic_collaboration_request(context, collaboration, organisation, recipients) return collaboration, 201 else: data["status"] = STATUS_OPEN collaboration_request = save(CollaborationRequest, custom_json=data)[0] context = {"salutation": f"Dear {organisation.name} organisation admin,", "base_url": current_app.app_config.base_url, "collaboration_request": collaboration_request, "user": user} if recipients: mail_collaboration_request(context, munchify(data), recipients) return collaboration_request, 201
def update_service(): data = current_request.get_json() service_id = data["id"] confirm_service_admin(service_id) validate_ip_networks(data) _token_validity_days(data) cleanse_short_name(data, "abbreviation") service = Service.query.get(service_id) if not is_application_admin() and is_service_admin(service_id): forbidden = ["white_listed", "non_member_users_access_allowed", "token_enabled", "token", "entity_id"] for attr in [fb for fb in forbidden if fb in data]: data[attr] = getattr(service, attr) res = update(Service, custom_json=data, allow_child_cascades=False, allowed_child_collections=["ip_networks"]) service = res[0] service.ip_networks return res
def update_organisation(): def override_func(): user_id = current_user_id() organisation_id = current_request.get_json()["id"] count = OrganisationMembership.query \ .filter(OrganisationMembership.user_id == user_id) \ .filter(OrganisationMembership.organisation_id == organisation_id) \ .filter(OrganisationMembership.role == "admin") \ .count() return count > 0 confirm_write_access(override_func=override_func) data = current_request.get_json() _clear_api_keys(data) cleanse_short_name(data) organisation = Organisation.query.get(data["id"]) if organisation.short_name != data["short_name"]: for collaboration in organisation.collaborations: collaboration.global_urn = f"{data['short_name']}:{collaboration.short_name}" db.session.merge(collaboration) for group in collaboration.groups: group.global_urn = f"{data['short_name']}:{collaboration.short_name}:{group.short_name}" db.session.merge(group) if not is_application_admin() and organisation.services_restricted: data["services_restricted"] = True # Corner case: user removed name and added the exact same name again, prevent duplicate entry existing_names = [sho.name for sho in organisation.schac_home_organisations] if "schac_home_organisations" in data: if len([sho for sho in data["schac_home_organisations"] if not sho.get("id") and sho["name"] in existing_names]) > 0: organisation.schac_home_organisations.clear() return update(Organisation, custom_json=data, allow_child_cascades=False, allowed_child_collections=["schac_home_organisations"])
def update_service_group(): data = current_request.get_json() confirm_write_access() cleanse_short_name(data) return update(ServiceGroup, custom_json=data, allow_child_cascades=False)
def _test_cleansing(short_name, expected): data = {"short_name": short_name} cleanse_short_name(data) self.assertEqual(expected, data["short_name"])
def raises_bad_request(): cleanse_short_name({})