diff --git a/gooddata-api-client/docs/ActionsApi.md b/gooddata-api-client/docs/ActionsApi.md index 06dbed974..2ef2aee38 100644 --- a/gooddata-api-client/docs/ActionsApi.md +++ b/gooddata-api-client/docs/ActionsApi.md @@ -279,7 +279,7 @@ with gooddata_api_client.ApiClient() as api_client: workspace_id = "/6bUUGjjNSwg0_bs" # str | Workspace identifier elements_request = ElementsRequest( complement_filter=False, - data_sampling_percentage=100.0, + data_sampling_percentage=100, exact_filter=[ "exact_filter_example", ], diff --git a/gooddata-api-client/docs/ComputationApi.md b/gooddata-api-client/docs/ComputationApi.md index 1075d0107..7e376fc93 100644 --- a/gooddata-api-client/docs/ComputationApi.md +++ b/gooddata-api-client/docs/ComputationApi.md @@ -46,7 +46,7 @@ with gooddata_api_client.ApiClient() as api_client: workspace_id = "/6bUUGjjNSwg0_bs" # str | Workspace identifier elements_request = ElementsRequest( complement_filter=False, - data_sampling_percentage=100.0, + data_sampling_percentage=100, exact_filter=[ "exact_filter_example", ], diff --git a/gooddata-api-client/docs/ElementsRequest.md b/gooddata-api-client/docs/ElementsRequest.md index 46e259e07..0a9d886b0 100644 --- a/gooddata-api-client/docs/ElementsRequest.md +++ b/gooddata-api-client/docs/ElementsRequest.md @@ -6,7 +6,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **label** | **str** | Requested label. | **complement_filter** | **bool** | Inverse filters: * ```false``` - return items matching ```patternFilter``` and ```exactFilter``` * ```true``` - return items not matching ```patternFilter``` and ```exactFilter``` | [optional] if omitted the server will use the default value of False -**data_sampling_percentage** | **float** | Specifies percentage of source table data scanned during the computation. This field is deprecated and is no longer used during the elements computation. | [optional] if omitted the server will use the default value of 100.0 +**data_sampling_percentage** | **float** | Specifies percentage of source table data scanned during the computation. This field is deprecated and is no longer used during the elements computation. | [optional] if omitted the server will use the default value of 100 **exact_filter** | **[str, none_type]** | Return only items, whose ```label``` title exactly matches one of ```filter```. | [optional] **exclude_primary_label** | **bool** | Excludes items from the result that differ only by primary label * ```false``` - return items with distinct primary label * ```true``` - return items with distinct requested label | [optional] if omitted the server will use the default value of False **filter_by** | [**FilterBy**](FilterBy.md) | | [optional] diff --git a/gooddata-api-client/gooddata_api_client/model/elements_request.py b/gooddata-api-client/gooddata_api_client/model/elements_request.py index 68e25ffa8..cf5143129 100644 --- a/gooddata-api-client/gooddata_api_client/model/elements_request.py +++ b/gooddata-api-client/gooddata_api_client/model/elements_request.py @@ -168,7 +168,7 @@ def _from_openapi_data(cls, label, *args, **kwargs): # noqa: E501 through its discriminator because we passed in _visited_composed_classes = (Animal,) complement_filter (bool): Inverse filters: * ```false``` - return items matching ```patternFilter``` and ```exactFilter``` * ```true``` - return items not matching ```patternFilter``` and ```exactFilter```. [optional] if omitted the server will use the default value of False # noqa: E501 - data_sampling_percentage (float): Specifies percentage of source table data scanned during the computation. This field is deprecated and is no longer used during the elements computation.. [optional] if omitted the server will use the default value of 100.0 # noqa: E501 + data_sampling_percentage (float): Specifies percentage of source table data scanned during the computation. This field is deprecated and is no longer used during the elements computation.. [optional] if omitted the server will use the default value of 100 # noqa: E501 exact_filter ([str, none_type]): Return only items, whose ```label``` title exactly matches one of ```filter```.. [optional] # noqa: E501 exclude_primary_label (bool): Excludes items from the result that differ only by primary label * ```false``` - return items with distinct primary label * ```true``` - return items with distinct requested label. [optional] if omitted the server will use the default value of False # noqa: E501 filter_by (FilterBy): [optional] # noqa: E501 @@ -264,7 +264,7 @@ def __init__(self, label, *args, **kwargs): # noqa: E501 through its discriminator because we passed in _visited_composed_classes = (Animal,) complement_filter (bool): Inverse filters: * ```false``` - return items matching ```patternFilter``` and ```exactFilter``` * ```true``` - return items not matching ```patternFilter``` and ```exactFilter```. [optional] if omitted the server will use the default value of False # noqa: E501 - data_sampling_percentage (float): Specifies percentage of source table data scanned during the computation. This field is deprecated and is no longer used during the elements computation.. [optional] if omitted the server will use the default value of 100.0 # noqa: E501 + data_sampling_percentage (float): Specifies percentage of source table data scanned during the computation. This field is deprecated and is no longer used during the elements computation.. [optional] if omitted the server will use the default value of 100 # noqa: E501 exact_filter ([str, none_type]): Return only items, whose ```label``` title exactly matches one of ```filter```.. [optional] # noqa: E501 exclude_primary_label (bool): Excludes items from the result that differ only by primary label * ```false``` - return items with distinct primary label * ```true``` - return items with distinct requested label. [optional] if omitted the server will use the default value of False # noqa: E501 filter_by (FilterBy): [optional] # noqa: E501 diff --git a/gooddata-sdk/gooddata_sdk/__init__.py b/gooddata-sdk/gooddata_sdk/__init__.py index 01642601f..37e68220a 100644 --- a/gooddata-sdk/gooddata_sdk/__init__.py +++ b/gooddata-sdk/gooddata_sdk/__init__.py @@ -89,9 +89,11 @@ CatalogDeclarativeDashboardPermissionsForAssignee, CatalogDeclarativeDashboardPermissionsForAssigneeRule, CatalogDeclarativeDataSourcePermission, + CatalogDeclarativeOrganizationPermission, CatalogDeclarativeSingleWorkspacePermission, CatalogDeclarativeWorkspaceHierarchyPermission, CatalogDeclarativeWorkspacePermissions, + CatalogOrganizationPermissionAssignment, ) from gooddata_sdk.catalog.rule import CatalogAssigneeRule from gooddata_sdk.catalog.user.declarative_model.user import CatalogDeclarativeUser, CatalogDeclarativeUsers diff --git a/gooddata-sdk/gooddata_sdk/catalog/permission/declarative_model/permission.py b/gooddata-sdk/gooddata_sdk/catalog/permission/declarative_model/permission.py index fa9d13652..b91f6f3e8 100644 --- a/gooddata-sdk/gooddata_sdk/catalog/permission/declarative_model/permission.py +++ b/gooddata-sdk/gooddata_sdk/catalog/permission/declarative_model/permission.py @@ -12,9 +12,11 @@ DeclarativeAnalyticalDashboardPermissionForAssigneeRule, ) from gooddata_api_client.model.declarative_data_source_permission import DeclarativeDataSourcePermission +from gooddata_api_client.model.declarative_organization_permission import DeclarativeOrganizationPermission from gooddata_api_client.model.declarative_single_workspace_permission import DeclarativeSingleWorkspacePermission from gooddata_api_client.model.declarative_workspace_hierarchy_permission import DeclarativeWorkspaceHierarchyPermission from gooddata_api_client.model.declarative_workspace_permissions import DeclarativeWorkspacePermissions +from gooddata_api_client.model.organization_permission_assignment import OrganizationPermissionAssignment from gooddata_sdk.catalog.base import Base, value_in_allowed from gooddata_sdk.catalog.identifier import CatalogAssigneeIdentifier from gooddata_sdk.catalog.rule import CatalogAssigneeRule @@ -78,3 +80,23 @@ class CatalogDeclarativeDashboardPermissionsForAssigneeRule(Base): @staticmethod def client_class() -> Type[DeclarativeAnalyticalDashboardPermissionForAssigneeRule]: return DeclarativeAnalyticalDashboardPermissionForAssigneeRule + + +@attr.s(auto_attribs=True, kw_only=True) +class CatalogDeclarativeOrganizationPermission(Base): + name: str = attr.field(validator=value_in_allowed) + assignee: CatalogAssigneeIdentifier + + @staticmethod + def client_class() -> Type[DeclarativeOrganizationPermission]: + return DeclarativeOrganizationPermission + + +@attr.s(auto_attribs=True, kw_only=True) +class CatalogOrganizationPermissionAssignment(Base): + assignee_identifier: CatalogAssigneeIdentifier + permissions: List[str] = attr.field(factory=list) + + @staticmethod + def client_class() -> Type[OrganizationPermissionAssignment]: + return OrganizationPermissionAssignment diff --git a/gooddata-sdk/gooddata_sdk/catalog/permission/service.py b/gooddata-sdk/gooddata_sdk/catalog/permission/service.py index c11a86a6c..27446d5d3 100644 --- a/gooddata-sdk/gooddata_sdk/catalog/permission/service.py +++ b/gooddata-sdk/gooddata_sdk/catalog/permission/service.py @@ -4,7 +4,9 @@ from gooddata_sdk import ( CatalogAvailableAssignees, CatalogDashboardPermissions, + CatalogDeclarativeOrganizationPermission, CatalogDeclarativeWorkspacePermissions, + CatalogOrganizationPermissionAssignment, CatalogPermissionsForAssignee, CatalogPermissionsForAssigneeRule, GoodDataApiClient, @@ -106,3 +108,56 @@ def manage_dashboard_permissions( [permission.to_api() for permission in permissions_for_assignee], _check_return_type=False, ) + + def get_declarative_organization_permissions(self) -> List[CatalogDeclarativeOrganizationPermission]: + """Get a list of all declarative organization permissions. + + Args: + None + + Returns: + [CatalogDeclarativeOrganizationPermission]: + List of all declarative organization permissions. + """ + + catalog_list = [] + for permission in self._layout_api.get_organization_permissions(): + catalog_list.append(CatalogDeclarativeOrganizationPermission.from_api(permission)) + return catalog_list + + def put_declarative_organization_permissions( + self, org_permissions: List[CatalogDeclarativeOrganizationPermission] + ) -> None: + """Put a list of all declarative organization permissions. + + Args: + org_permissions([CatalogDeclarativeOrganizationPermission]) + list of declarative organization permissions + + Returns: + None + """ + + declarative_organization_permissions = [] + for catalog_permission in org_permissions: + declarative_organization_permissions.append(catalog_permission.to_api()) + self._layout_api.set_organization_permissions(declarative_organization_permissions) + + def manage_organization_permissions( + self, organization_permission_assignments: List[CatalogOrganizationPermissionAssignment] + ) -> None: + """Provide managing organization permissions for user and user groups. + + Args: + organization_permission_assignments ([CatalogOrganizationPermissionAssignment]): + Object containing List of users and user group and desired organization permissions. Set empty list + permissions for user/user group means remove organization permissions. + Returns: + None + """ + permissions = [permission.to_api() for permission in organization_permission_assignments] + print(permissions) + self._actions_api.manage_organization_permissions( + [permission.to_api() for permission in organization_permission_assignments], + _check_return_type=False, + ) diff --git a/gooddata-sdk/tests/catalog/expected/declarative_organization_permissions.json b/gooddata-sdk/tests/catalog/expected/declarative_organization_permissions.json new file mode 100644 index 000000000..bb38b4ed0 --- /dev/null +++ b/gooddata-sdk/tests/catalog/expected/declarative_organization_permissions.json @@ -0,0 +1,16 @@ +[ + { + "assignee": { + "id": "adminGroup", + "type": "userGroup" + }, + "name": "MANAGE" + }, + { + "assignee": { + "id": "adminGroup", + "type": "userGroup" + }, + "name": "SELF_CREATE_TOKEN" + } +] diff --git a/gooddata-sdk/tests/catalog/fixtures/permissions/manage_organization_permissions.yaml b/gooddata-sdk/tests/catalog/fixtures/permissions/manage_organization_permissions.yaml new file mode 100644 index 000000000..f4f9e57a8 --- /dev/null +++ b/gooddata-sdk/tests/catalog/fixtures/permissions/manage_organization_permissions.yaml @@ -0,0 +1,162 @@ +# (C) 2023 GoodData Corporation +version: 1 +interactions: + - request: + method: POST + uri: http://localhost:3000/api/v1/actions/organization/managePermissions + body: + - assigneeIdentifier: + id: adminGroup + type: userGroup + permissions: + - MANAGE + - SELF_CREATE_TOKEN + headers: + Accept-Encoding: + - br, gzip, deflate + Content-Type: + - application/json + X-GDC-VALIDATE-RELATIONS: + - 'true' + X-Requested-With: + - XMLHttpRequest + response: + status: + code: 204 + message: No Content + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Expose-Headers: + - Content-Disposition, Content-Length, Content-Range, Set-Cookie + Cache-Control: + - no-cache, no-store, max-age=0, must-revalidate + Connection: + - keep-alive + Content-Security-Policy: + - 'default-src ''self'' *.wistia.com *.wistia.net; script-src ''self'' ''unsafe-inline'' + ''unsafe-eval'' *.wistia.com *.wistia.net *.hsforms.net *.hsforms.com + src.litix.io matomo.anywhere.gooddata.com *.jquery.com unpkg.com cdn.jsdelivr.net + cdnjs.cloudflare.com; img-src ''self'' data: blob: *.wistia.com *.wistia.net + *.hsforms.net *.hsforms.com embedwistia-a.akamaihd.net privacy-policy.truste.com + www.gooddata.com; style-src ''self'' ''unsafe-inline'' fonts.googleapis.com + cdn.jsdelivr.net fast.fonts.net; font-src ''self'' data: fonts.gstatic.com + *.alicdn.com *.wistia.com cdn.jsdelivr.net info.gooddata.com; frame-src + ''self'' *.hsforms.net *.hsforms.com; object-src ''none''; worker-src + ''self'' blob:; child-src blob:; connect-src ''self'' *.tiles.mapbox.com + *.mapbox.com *.litix.io *.wistia.com *.hsforms.net *.hsforms.com embedwistia-a.akamaihd.net + matomo.anywhere.gooddata.com; media-src ''self'' blob: data: *.wistia.com + *.wistia.net embedwistia-a.akamaihd.net' + DATE: &id001 + - PLACEHOLDER + Expires: + - '0' + GoodData-Deployment: + - aio + Permission-Policy: + - geolocation 'none'; midi 'none'; sync-xhr 'none'; microphone 'none'; camera + 'none'; magnetometer 'none'; gyroscope 'none'; fullscreen 'none'; payment + 'none'; + Pragma: + - no-cache + Referrer-Policy: + - no-referrer + Server: + - nginx + Set-Cookie: + - SPRING_REDIRECT_URI=; Path=/; Max-Age=0; Expires=Thu, 01 Jan 1970 00:00:00 + GMT; HttpOnly; SameSite=Lax + Vary: + - Origin + - Access-Control-Request-Method + - Access-Control-Request-Headers + X-Content-Type-Options: + - nosniff + X-GDC-TRACE-ID: *id001 + X-XSS-Protection: + - 1 ; mode=block + body: + string: '' + - request: + method: GET + uri: http://localhost:3000/api/v1/layout/organization/permissions + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - br, gzip, deflate + X-GDC-VALIDATE-RELATIONS: + - 'true' + X-Requested-With: + - XMLHttpRequest + response: + status: + code: 200 + message: OK + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Expose-Headers: + - Content-Disposition, Content-Length, Content-Range, Set-Cookie + Cache-Control: + - no-cache, no-store, max-age=0, must-revalidate + Connection: + - keep-alive + Content-Security-Policy: + - 'default-src ''self'' *.wistia.com *.wistia.net; script-src ''self'' ''unsafe-inline'' + ''unsafe-eval'' *.wistia.com *.wistia.net *.hsforms.net *.hsforms.com + src.litix.io matomo.anywhere.gooddata.com *.jquery.com unpkg.com cdn.jsdelivr.net + cdnjs.cloudflare.com; img-src ''self'' data: blob: *.wistia.com *.wistia.net + *.hsforms.net *.hsforms.com embedwistia-a.akamaihd.net privacy-policy.truste.com + www.gooddata.com; style-src ''self'' ''unsafe-inline'' fonts.googleapis.com + cdn.jsdelivr.net fast.fonts.net; font-src ''self'' data: fonts.gstatic.com + *.alicdn.com *.wistia.com cdn.jsdelivr.net info.gooddata.com; frame-src + ''self'' *.hsforms.net *.hsforms.com; object-src ''none''; worker-src + ''self'' blob:; child-src blob:; connect-src ''self'' *.tiles.mapbox.com + *.mapbox.com *.litix.io *.wistia.com *.hsforms.net *.hsforms.com embedwistia-a.akamaihd.net + matomo.anywhere.gooddata.com; media-src ''self'' blob: data: *.wistia.com + *.wistia.net embedwistia-a.akamaihd.net' + Content-Type: + - application/json + DATE: *id001 + Expires: + - '0' + GoodData-Deployment: + - aio + Permission-Policy: + - geolocation 'none'; midi 'none'; sync-xhr 'none'; microphone 'none'; camera + 'none'; magnetometer 'none'; gyroscope 'none'; fullscreen 'none'; payment + 'none'; + Pragma: + - no-cache + Referrer-Policy: + - no-referrer + Server: + - nginx + Set-Cookie: + - SPRING_REDIRECT_URI=; Path=/; Max-Age=0; Expires=Thu, 01 Jan 1970 00:00:00 + GMT; HttpOnly; SameSite=Lax + Transfer-Encoding: + - chunked + Vary: + - Origin + - Access-Control-Request-Method + - Access-Control-Request-Headers + X-Content-Type-Options: + - nosniff + X-GDC-TRACE-ID: *id001 + X-XSS-Protection: + - 1 ; mode=block + content-length: + - '113' + body: + string: + - assignee: + id: adminGroup + type: userGroup + name: MANAGE + - assignee: + id: adminGroup + type: userGroup + name: SELF_CREATE_TOKEN diff --git a/gooddata-sdk/tests/catalog/fixtures/permissions/put_declarative_organization_permissions.yaml b/gooddata-sdk/tests/catalog/fixtures/permissions/put_declarative_organization_permissions.yaml new file mode 100644 index 000000000..3d098118e --- /dev/null +++ b/gooddata-sdk/tests/catalog/fixtures/permissions/put_declarative_organization_permissions.yaml @@ -0,0 +1,249 @@ +# (C) 2023 GoodData Corporation +version: 1 +interactions: + - request: + method: GET + uri: http://localhost:3000/api/v1/layout/organization/permissions + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - br, gzip, deflate + X-GDC-VALIDATE-RELATIONS: + - 'true' + X-Requested-With: + - XMLHttpRequest + response: + status: + code: 200 + message: OK + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Expose-Headers: + - Content-Disposition, Content-Length, Content-Range, Set-Cookie + Cache-Control: + - no-cache, no-store, max-age=0, must-revalidate + Connection: + - keep-alive + Content-Security-Policy: + - 'default-src ''self'' *.wistia.com *.wistia.net; script-src ''self'' ''unsafe-inline'' + ''unsafe-eval'' *.wistia.com *.wistia.net *.hsforms.net *.hsforms.com + src.litix.io matomo.anywhere.gooddata.com *.jquery.com unpkg.com cdn.jsdelivr.net + cdnjs.cloudflare.com; img-src ''self'' data: blob: *.wistia.com *.wistia.net + *.hsforms.net *.hsforms.com embedwistia-a.akamaihd.net privacy-policy.truste.com + www.gooddata.com; style-src ''self'' ''unsafe-inline'' fonts.googleapis.com + cdn.jsdelivr.net fast.fonts.net; font-src ''self'' data: fonts.gstatic.com + *.alicdn.com *.wistia.com cdn.jsdelivr.net info.gooddata.com; frame-src + ''self'' *.hsforms.net *.hsforms.com; object-src ''none''; worker-src + ''self'' blob:; child-src blob:; connect-src ''self'' *.tiles.mapbox.com + *.mapbox.com *.litix.io *.wistia.com *.hsforms.net *.hsforms.com embedwistia-a.akamaihd.net + matomo.anywhere.gooddata.com; media-src ''self'' blob: data: *.wistia.com + *.wistia.net embedwistia-a.akamaihd.net' + Content-Type: + - application/json + DATE: &id001 + - PLACEHOLDER + Expires: + - '0' + GoodData-Deployment: + - aio + Permission-Policy: + - geolocation 'none'; midi 'none'; sync-xhr 'none'; microphone 'none'; camera + 'none'; magnetometer 'none'; gyroscope 'none'; fullscreen 'none'; payment + 'none'; + Pragma: + - no-cache + Referrer-Policy: + - no-referrer + Server: + - nginx + Set-Cookie: + - SPRING_REDIRECT_URI=; Path=/; Max-Age=0; Expires=Thu, 01 Jan 1970 00:00:00 + GMT; HttpOnly; SameSite=Lax + Transfer-Encoding: + - chunked + Vary: + - Origin + - Access-Control-Request-Method + - Access-Control-Request-Headers + X-Content-Type-Options: + - nosniff + X-GDC-TRACE-ID: *id001 + X-XSS-Protection: + - 1 ; mode=block + content-length: + - '292' + body: + string: + - assignee: + id: adminGroup + type: userGroup + name: MANAGE + - request: + method: PUT + uri: http://localhost:3000/api/v1/layout/organization/permissions + body: + - assignee: + id: adminGroup + type: userGroup + name: MANAGE + - assignee: + id: adminGroup + type: userGroup + name: SELF_CREATE_TOKEN + headers: + Accept-Encoding: + - br, gzip, deflate + Content-Type: + - application/json + X-GDC-VALIDATE-RELATIONS: + - 'true' + X-Requested-With: + - XMLHttpRequest + response: + status: + code: 204 + message: No Content + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Expose-Headers: + - Content-Disposition, Content-Length, Content-Range, Set-Cookie + Cache-Control: + - no-cache, no-store, max-age=0, must-revalidate + Connection: + - keep-alive + Content-Security-Policy: + - 'default-src ''self'' *.wistia.com *.wistia.net; script-src ''self'' ''unsafe-inline'' + ''unsafe-eval'' *.wistia.com *.wistia.net *.hsforms.net *.hsforms.com + src.litix.io matomo.anywhere.gooddata.com *.jquery.com unpkg.com cdn.jsdelivr.net + cdnjs.cloudflare.com; img-src ''self'' data: blob: *.wistia.com *.wistia.net + *.hsforms.net *.hsforms.com embedwistia-a.akamaihd.net privacy-policy.truste.com + www.gooddata.com; style-src ''self'' ''unsafe-inline'' fonts.googleapis.com + cdn.jsdelivr.net fast.fonts.net; font-src ''self'' data: fonts.gstatic.com + *.alicdn.com *.wistia.com cdn.jsdelivr.net info.gooddata.com; frame-src + ''self'' *.hsforms.net *.hsforms.com; object-src ''none''; worker-src + ''self'' blob:; child-src blob:; connect-src ''self'' *.tiles.mapbox.com + *.mapbox.com *.litix.io *.wistia.com *.hsforms.net *.hsforms.com embedwistia-a.akamaihd.net + matomo.anywhere.gooddata.com; media-src ''self'' blob: data: *.wistia.com + *.wistia.net embedwistia-a.akamaihd.net' + Content-Type: + - application/json + DATE: &id002 + - PLACEHOLDER + Expires: + - '0' + GoodData-Deployment: + - aio + Permission-Policy: + - geolocation 'none'; midi 'none'; sync-xhr 'none'; microphone 'none'; camera + 'none'; magnetometer 'none'; gyroscope 'none'; fullscreen 'none'; payment + 'none'; + Pragma: + - no-cache + Referrer-Policy: + - no-referrer + Server: + - nginx + Set-Cookie: + - SPRING_REDIRECT_URI=; Path=/; Max-Age=0; Expires=Thu, 01 Jan 1970 00:00:00 + GMT; HttpOnly; SameSite=Lax + Transfer-Encoding: + - chunked + Vary: + - Origin + - Access-Control-Request-Method + - Access-Control-Request-Headers + X-Content-Type-Options: + - nosniff + X-GDC-TRACE-ID: *id002 + X-XSS-Protection: + - 1 ; mode=block + body: + string: '' + - request: + method: GET + uri: http://localhost:3000/api/v1/layout/organization/permissions + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - br, gzip, deflate + X-GDC-VALIDATE-RELATIONS: + - 'true' + X-Requested-With: + - XMLHttpRequest + response: + status: + code: 200 + message: OK + headers: + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Expose-Headers: + - Content-Disposition, Content-Length, Content-Range, Set-Cookie + Cache-Control: + - no-cache, no-store, max-age=0, must-revalidate + Connection: + - keep-alive + Content-Security-Policy: + - 'default-src ''self'' *.wistia.com *.wistia.net; script-src ''self'' ''unsafe-inline'' + ''unsafe-eval'' *.wistia.com *.wistia.net *.hsforms.net *.hsforms.com + src.litix.io matomo.anywhere.gooddata.com *.jquery.com unpkg.com cdn.jsdelivr.net + cdnjs.cloudflare.com; img-src ''self'' data: blob: *.wistia.com *.wistia.net + *.hsforms.net *.hsforms.com embedwistia-a.akamaihd.net privacy-policy.truste.com + www.gooddata.com; style-src ''self'' ''unsafe-inline'' fonts.googleapis.com + cdn.jsdelivr.net fast.fonts.net; font-src ''self'' data: fonts.gstatic.com + *.alicdn.com *.wistia.com cdn.jsdelivr.net info.gooddata.com; frame-src + ''self'' *.hsforms.net *.hsforms.com; object-src ''none''; worker-src + ''self'' blob:; child-src blob:; connect-src ''self'' *.tiles.mapbox.com + *.mapbox.com *.litix.io *.wistia.com *.hsforms.net *.hsforms.com embedwistia-a.akamaihd.net + matomo.anywhere.gooddata.com; media-src ''self'' blob: data: *.wistia.com + *.wistia.net embedwistia-a.akamaihd.net' + Content-Type: + - application/json + DATE: &id003 + - PLACEHOLDER + Expires: + - '0' + GoodData-Deployment: + - aio + Permission-Policy: + - geolocation 'none'; midi 'none'; sync-xhr 'none'; microphone 'none'; camera + 'none'; magnetometer 'none'; gyroscope 'none'; fullscreen 'none'; payment + 'none'; + Pragma: + - no-cache + Referrer-Policy: + - no-referrer + Server: + - nginx + Set-Cookie: + - SPRING_REDIRECT_URI=; Path=/; Max-Age=0; Expires=Thu, 01 Jan 1970 00:00:00 + GMT; HttpOnly; SameSite=Lax + Transfer-Encoding: + - chunked + Vary: + - Origin + - Access-Control-Request-Method + - Access-Control-Request-Headers + X-Content-Type-Options: + - nosniff + X-GDC-TRACE-ID: *id003 + X-XSS-Protection: + - 1 ; mode=block + content-length: + - '292' + body: + string: + - assignee: + id: adminGroup + type: userGroup + name: MANAGE + - assignee: + id: adminGroup + type: userGroup + name: SELF_CREATE_TOKEN diff --git a/gooddata-sdk/tests/catalog/test_catalog_permission.py b/gooddata-sdk/tests/catalog/test_catalog_permission.py index 1fa750466..ce742d4ca 100644 --- a/gooddata-sdk/tests/catalog/test_catalog_permission.py +++ b/gooddata-sdk/tests/catalog/test_catalog_permission.py @@ -12,9 +12,11 @@ CatalogAssigneeRule, CatalogDashboardAssigneeIdentifier, CatalogDeclarativeDataSourcePermission, + CatalogDeclarativeOrganizationPermission, CatalogDeclarativeSingleWorkspacePermission, CatalogDeclarativeWorkspaceHierarchyPermission, CatalogDeclarativeWorkspacePermissions, + CatalogOrganizationPermissionAssignment, CatalogPermissionsForAssignee, CatalogPermissionsForAssigneeRule, GoodDataApiClient, @@ -54,6 +56,12 @@ def _assert_default_permissions(catalog_declarative_permissions: CatalogDeclarat assert set(permission.name for permission in catalog_declarative_permissions.permissions) == {"ANALYZE", "VIEW"} +def _assert_organization_permissions_id( + catalog_organization_permissions: [CatalogDeclarativeOrganizationPermission], +) -> None: + assert set(org_permission.assignee.id for org_permission in catalog_organization_permissions) == {"adminGroup"} + + def _validation_helper(class_type, attribute_name: str): client_class = class_type.client_class() allowed_values = list(client_class.allowed_values.get((attribute_name,)).values()) @@ -164,3 +172,53 @@ def test_list_dashboard_permissions(test_config): assert len(dashboard_permissions.user_groups) == 0 assert len(dashboard_permissions.users) == 0 assert len(dashboard_permissions.rules) == 0 + + +@gd_vcr.use_cassette(str(_fixtures_dir / "put_declarative_organization_permissions.yaml")) +def test_put_and_get_declarative_organization_permissions(test_config): + expected_json_path = _current_dir / "expected" / "declarative_organization_permissions.json" + sdk = GoodDataSdk.create(host_=test_config["host"], token_=test_config["token"]) + catalog_declarative_permissions_initial = sdk.catalog_permission.get_declarative_organization_permissions() + + assert len(catalog_declarative_permissions_initial) == 1 + _assert_organization_permissions_id(catalog_declarative_permissions_initial) + assert set(org_permission.name for org_permission in catalog_declarative_permissions_initial) == {"MANAGE"} + + with open(expected_json_path, "r", encoding="utf-8") as f: + data = json.load(f) + + declarative_organization_permissions = [] + for permission in data: + declarative_organization_permissions.append(CatalogDeclarativeOrganizationPermission.from_api(permission)) + + sdk.catalog_permission.put_declarative_organization_permissions(declarative_organization_permissions) + + catalog_declarative_permissions_after_put = sdk.catalog_permission.get_declarative_organization_permissions() + assert len(catalog_declarative_permissions_after_put) == 2 + _assert_organization_permissions_id(catalog_declarative_permissions_after_put) + assert set(org_permission.name for org_permission in catalog_declarative_permissions_after_put) == { + "MANAGE", + "SELF_CREATE_TOKEN", + } + + +@gd_vcr.use_cassette(str(_fixtures_dir / "manage_organization_permissions.yaml")) +def test_manage_organization_permissions(test_config): + sdk = GoodDataSdk.create(host_=test_config["host"], token_=test_config["token"]) + + # assign permissions to adminGroup + sdk.catalog_permission.manage_organization_permissions( + [ + CatalogOrganizationPermissionAssignment( + assignee_identifier=CatalogAssigneeIdentifier(id="adminGroup", type="userGroup"), + permissions=["MANAGE", "SELF_CREATE_TOKEN"], + ) + ], + ) + + catalog_declarative_permissions_initial = sdk.catalog_permission.get_declarative_organization_permissions() + assert len(catalog_declarative_permissions_initial) == 2 + assert set(org_permission.name for org_permission in catalog_declarative_permissions_initial) == { + "MANAGE", + "SELF_CREATE_TOKEN", + } diff --git a/schemas/gooddata-afm-client.json b/schemas/gooddata-afm-client.json index 6a0f654f4..13c18c243 100644 --- a/schemas/gooddata-afm-client.json +++ b/schemas/gooddata-afm-client.json @@ -756,7 +756,7 @@ "type": "boolean" }, "dataSamplingPercentage": { - "default": 100.0, + "default": 100, "deprecated": true, "description": "Specifies percentage of source table data scanned during the computation. This field is deprecated and is no longer used during the elements computation.", "format": "float", @@ -886,7 +886,7 @@ "description": "A multi-dimensional array of computed results. The most common one being a 2-dimensional array. The arrays can be composed of Double or null values.", "example": [ [ - 1.0, + 1, 2.5 ], [ @@ -931,7 +931,7 @@ "description": "A multi-dimensional array of computed results. The most common one being a 2-dimensional array. The arrays can be composed of Double or null values.", "example": [ [ - 1.0, + 1, 2.5 ], [ diff --git a/schemas/gooddata-api-client.json b/schemas/gooddata-api-client.json index bc2cd070a..bbbf655a6 100644 --- a/schemas/gooddata-api-client.json +++ b/schemas/gooddata-api-client.json @@ -3516,7 +3516,7 @@ "type": "boolean" }, "dataSamplingPercentage": { - "default": 100.0, + "default": 100, "deprecated": true, "description": "Specifies percentage of source table data scanned during the computation. This field is deprecated and is no longer used during the elements computation.", "format": "float", @@ -3708,7 +3708,7 @@ "description": "A multi-dimensional array of computed results. The most common one being a 2-dimensional array. The arrays can be composed of Double or null values.", "example": [ [ - 1.0, + 1, 2.5 ], [ @@ -3753,7 +3753,7 @@ "description": "A multi-dimensional array of computed results. The most common one being a 2-dimensional array. The arrays can be composed of Double or null values.", "example": [ [ - 1.0, + 1, 2.5 ], [