예제 #1
0
파일: system.py 프로젝트: SURFscz/SBS
def validations():
    confirm_write_access()

    organizations_subquery = ~OrganisationMembership.query \
        .filter(OrganisationMembership.role == "admin") \
        .filter(OrganisationMembership.organisation_id == Organisation.id) \
        .exists()
    organisations_without_admins = Organisation.query.filter(organizations_subquery).all()

    services_subquery = ~ServiceMembership.query \
        .filter(ServiceMembership.role == "admin") \
        .filter(ServiceMembership.service_id == Service.id) \
        .exists()
    services_without_admins = Service.query.filter(services_subquery).all()

    organisation_invitations = OrganisationInvitation.query \
        .options(joinedload(OrganisationInvitation.organisation)) \
        .options(joinedload(OrganisationInvitation.user)) \
        .all()

    return {
            "organisations": organisations_without_admins,
            "organisation_invitations": organisation_invitations,
            "services": services_without_admins
           }, 200
예제 #2
0
def get_platform_admins():
    confirm_write_access()
    config = current_app.app_config
    admin_users_upgrade = config.feature.admin_users_upgrade
    admin_users = [u.uid for u in config.admin_users]
    platform_admins = User.query.filter(User.uid.in_(admin_users)).all()
    return {"platform_admins": platform_admins, "admin_users_upgrade": admin_users_upgrade}, 200
예제 #3
0
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
예제 #4
0
def add_collaborations_services():
    data = current_request.get_json()
    organisation_id = int(data["organisation_id"])
    service_id = int(data["service_id"])

    confirm_organisation_admin_or_manager(organisation_id)
    # Ensure that the connection is allowed
    service = Service.query.get(service_id)
    is_allowed = organisation_id in list(
        map(lambda org: org.id, service.allowed_organisations)) or service.access_allowed_for_all
    if not is_allowed:
        raise BadRequest("not_allowed_organisation")

    if not service.automatic_connection_allowed and not service.access_allowed_for_all:
        raise BadRequest("automatic_connection_not_allowed")

    organisation = Organisation.query.get(organisation_id)

    if organisation.services_restricted:
        confirm_write_access()

    organisation.services.append(service)
    db.session.merge(organisation)
    # Create groups from service_groups
    for collaboration in organisation.collaborations:
        create_service_groups(service, collaboration)

    return None, 201
예제 #5
0
파일: system.py 프로젝트: SURFscz/SBS
def clear_audit_logs():
    confirm_write_access()

    if not current_app.app_config.feature.seed_allowed:
        raise BadRequest("clear-audit-logs not allowed in this environment")

    db.session.execute(text("DELETE FROM audit_logs"))
    return {}, 201
예제 #6
0
파일: system.py 프로젝트: SURFscz/SBS
def run_seed():
    confirm_write_access()

    if not current_app.app_config.feature.seed_allowed:
        raise BadRequest("seed not allowed in this environment")

    seed(db, current_app.app_config, skip_seed=False, perf_test=True)

    return {}, 201
예제 #7
0
def all_service_request_connections_by_service(service_id):
    confirm_write_access(service_id, override_func=is_service_admin)
    return ServiceConnectionRequest.query \
               .join(ServiceConnectionRequest.collaboration) \
               .join(ServiceConnectionRequest.requester) \
               .options(contains_eager(ServiceConnectionRequest.collaboration)) \
               .options(contains_eager(ServiceConnectionRequest.requester)) \
               .filter(ServiceConnectionRequest.service_id == service_id) \
               .all(), 200
예제 #8
0
파일: system.py 프로젝트: SURFscz/SBS
def clean_slate():
    confirm_write_access()

    if not current_app.app_config.feature.seed_allowed:
        raise BadRequest("clean_slate not allowed in this environment")

    seed(db, current_app.app_config, skip_seed=True)

    return {}, 201
예제 #9
0
파일: system.py 프로젝트: SURFscz/SBS
def scheduled_jobs():
    confirm_write_access()

    if not hasattr(current_app, "scheduler"):
        return [], 200

    jobs = current_app.scheduler.get_jobs()

    return [{"name": job.name, "next_run_time": job.next_run_time} for job in jobs], 200
예제 #10
0
def delete_all_services(collaboration_id):
    confirm_collaboration_admin(collaboration_id)

    collaboration = Collaboration.query.get(collaboration_id)
    if collaboration.organisation.services_restricted:
        confirm_write_access()

    collaboration.services = []
    db.session.merge(collaboration)
    return None, 204
예제 #11
0
    def test_is_admin(self):
        with self.app.app_context():
            session["user"] = {"uid": "urn:john", "admin": True, "confirmed_admin": True}

            self.assertTrue(is_admin_user({"uid": "urn:john"}))
            self.assertTrue(is_application_admin())

            confirm_allow_impersonation()
            request_context.is_authorized_api_call = False
            confirm_write_access()
예제 #12
0
def delete_collaborations_services(collaboration_id, service_id):
    confirm_collaboration_admin(collaboration_id)

    collaboration = Collaboration.query.get(collaboration_id)
    if collaboration.organisation.services_restricted:
        confirm_write_access()

    collaboration.services.remove(Service.query.get(service_id))
    db.session.merge(collaboration)

    return {'collaboration_id': collaboration_id, 'service_id': service_id}, 204
예제 #13
0
def delete_organisations_services(organisation_id, service_id):
    confirm_organisation_admin_or_manager(organisation_id)

    organisation = Organisation.query.get(organisation_id)

    if organisation.services_restricted:
        confirm_write_access()

    organisation.services.remove(Service.query.get(service_id))
    db.session.merge(organisation)

    return None, 204
예제 #14
0
파일: system.py 프로젝트: SURFscz/SBS
def do_db_stats():
    confirm_write_access()

    results = []
    tables = list(map(lambda t: str(t.name), metadata.sorted_tables))
    tables.append("audit_logs")
    for table in tables:
        rows = db.session.execute(text(f"SELECT COUNT(*) FROM `{table}`"))
        for row in rows:
            results.append({"name": table, "count": row[0]})

    return sorted(results, key=lambda k: k["count"], reverse=True), 200
예제 #15
0
def activate():
    body = current_request.get_json()
    if "collaboration_id" in body:
        confirm_collaboration_admin(body["collaboration_id"], org_manager_allowed=False)
    elif "organisation_id" in body:
        confirm_organisation_admin(body["organisation_id"])
    else:
        confirm_write_access()

    user = User.query.get(body["user_id"])

    user.suspended = False
    retention = current_app.app_config.retention
    user.last_login_date = datetime.datetime.now() - datetime.timedelta(days=retention.allowed_inactive_period_days)
    user.suspend_notifications = []
    db.session.merge(user)

    create_suspend_notification(user, retention, current_app, True)
    return {}, 201
예제 #16
0
def organisation_search():
    confirm_write_access(override_func=is_service_admin)

    res = []
    q = query_param("q")
    if q and len(q):
        base_query = "SELECT id, name, description, category, logo, short_name FROM organisations "
        not_wild_card = "*" not in q
        if not_wild_card:
            q = replace_full_text_search_boolean_mode_chars(q)
            base_query += f"WHERE MATCH (name, description) AGAINST (:q IN BOOLEAN MODE) " \
                          f"AND id > 0  ORDER BY NAME LIMIT {full_text_search_autocomplete_limit}"
        sql = text(base_query if not_wild_card else base_query + " ORDER BY NAME")
        if not_wild_card:
            sql = sql.bindparams(bindparam("q", type_=String))
        result_set = db.engine.execute(sql, {"q": f"{q}*"}) if not_wild_card else db.engine.execute(sql)

        res = [{"id": row[0], "name": row[1], "description": row[2], "category": row[3], "logo": row[4],
                "short_name": row[5]} for row in result_set]
    return res, 200
예제 #17
0
파일: service.py 프로젝트: SURFscz/SBS
def add_allowed_organisations(service_id):
    confirm_write_access()

    service = Service.query.get(service_id)
    data = current_request.get_json()
    allowed_organisations = data.get("allowed_organisations", None)

    org_sql = f"DELETE FROM services_organisations WHERE service_id = {service_id}"
    coll_sql = f"DELETE sc FROM services_collaborations sc INNER JOIN collaborations c on c.id = sc.collaboration_id " \
               f"WHERE sc.service_id = {service_id}"

    need_to_delete = not bool(allowed_organisations)
    if allowed_organisations:
        # find delta, e.g. which one to remove and which ones to add
        current_allowed = [org.id for org in service.allowed_organisations]
        new_allowed = [int(value["organisation_id"]) for value in allowed_organisations]

        to_remove = [org_id for org_id in current_allowed if org_id not in new_allowed]
        to_append = [org_id for org_id in new_allowed if org_id not in current_allowed]
        for org_id in to_remove:
            service.allowed_organisations.remove(Organisation.query.get(org_id))
        for org_id in to_append:
            service.allowed_organisations.append(Organisation.query.get(org_id))

        if to_remove:
            need_to_delete = True
            org_del_ids = ",".join([str(org_id) for org_id in to_remove])
            org_sql += f" AND organisation_id in ({org_del_ids})"
            coll_sql += f" AND c.organisation_id in ({org_del_ids})"

    else:
        service.allowed_organisations.clear()

    db.session.merge(service)

    if need_to_delete:
        db.engine.execute(text(org_sql))
        db.engine.execute(text(coll_sql))

    return None, 201
예제 #18
0
def connect_service_collaboration(service_id, collaboration_id, force=False):
    # Ensure that the connection is allowed
    service = Service.query.get(service_id)
    organisation_id = Collaboration.query.get(collaboration_id).organisation_id
    organisation_not_allowed = organisation_id not in list(map(lambda org: org.id, service.allowed_organisations))
    if organisation_not_allowed and not service.access_allowed_for_all:
        raise BadRequest("not_allowed_organisation")

    if not force and not service.automatic_connection_allowed:
        raise BadRequest("automatic_connection_not_allowed")

    collaboration = Collaboration.query.get(collaboration_id)
    if collaboration.organisation.services_restricted:
        confirm_write_access()

    collaboration.services.append(service)
    db.session.merge(collaboration)

    # Create groups from service_groups
    create_service_groups(service, collaboration)

    return 1
예제 #19
0
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"])
예제 #20
0
파일: service.py 프로젝트: SURFscz/SBS
def _do_get_services(restrict_for_current_user=False, include_counts=False):
    def override_func():
        return is_collaboration_admin() or _is_org_member() or is_service_admin()

    confirm_write_access(override_func=override_func)
    query = Service.query \
        .options(selectinload(Service.allowed_organisations)) \
        .options(selectinload(Service.service_connection_requests))

    if restrict_for_current_user:
        query = query.join(Service.service_memberships) \
            .filter(ServiceMembership.user_id == current_user_id())

    services = query.all()
    if not include_counts:
        return services, 200

    query = """
        select s.id as id,
            (select count(so.id) from services_organisations so where so.service_id = s.id) as so_count ,
            ((select count(sc.id) from services_collaborations sc where sc.service_id = s.id) +
            (select count(c.id) from collaborations c where c.organisation_id in (
                    select so.organisation_id from services_organisations so where so.service_id = s.id
                ) and c.id not in (
                    select sc.collaboration_id from services_collaborations sc where sc.service_id = s.id
            ))) as c_count from services s
    """
    if restrict_for_current_user:
        query += f" where s.id in ({','.join([str(s.id) for s in services])})"

    result_set = db.engine.execute(text(query))
    services_json = jsonify(services).json
    services_json_dict = {s["id"]: s for s in services_json}
    for row in result_set:
        service_json = services_json_dict.get(row[0])
        service_json["organisations_count"] = row[1]
        service_json["collaborations_count"] = row[2]
    return services_json, 200
예제 #21
0
파일: system.py 프로젝트: SURFscz/SBS
def do_expire_collaboration():
    confirm_write_access()

    from server.cron.collaboration_expiration import expire_collaborations

    return expire_collaborations(current_app), 201
예제 #22
0
def delete_organisation(id):
    confirm_write_access()
    return delete(Organisation, id)
예제 #23
0
def organisation_all():
    confirm_write_access()
    organisations = Organisation.query.all()
    return organisations, 200
예제 #24
0
def find_by_id():
    confirm_write_access()
    return _user_query() \
               .options(joinedload(User.service_aups)
                        .subqueryload(ServiceAup.service)) \
               .filter(User.id == query_param("id")).one(), 200
예제 #25
0
def suspended():
    confirm_write_access()
    return User.query.filter(User.suspended == True).all(), 200  # noqa: E712
예제 #26
0
파일: system.py 프로젝트: SURFscz/SBS
def do_suspend_collaborations():
    confirm_write_access()

    from server.cron.collaboration_inactivity_suspension import suspend_collaborations

    return suspend_collaborations(current_app), 201
예제 #27
0
파일: system.py 프로젝트: SURFscz/SBS
def do_expire_memberships():
    confirm_write_access()

    from server.cron.membership_expiration import expire_memberships

    return expire_memberships(current_app), 201
예제 #28
0
파일: system.py 프로젝트: SURFscz/SBS
def do_cleanup_non_open_requests():
    confirm_write_access()

    from server.cron.cleanup_non_open_requests import cleanup_non_open_requests

    return cleanup_non_open_requests(current_app), 201
예제 #29
0
파일: system.py 프로젝트: SURFscz/SBS
def do_outstanding_requests():
    confirm_write_access()

    from server.cron.outstanding_requests import outstanding_requests

    return outstanding_requests(current_app), 200
예제 #30
0
파일: system.py 프로젝트: SURFscz/SBS
def do_suspend_users():
    confirm_write_access()

    from server.cron.user_suspending import suspend_users

    return suspend_users(current_app), 201