feature: add beta drive listing endpoints to the graph api (#7861)

* feature: add beta drive listing endpoints to the graph api and hydrate them to contain the new grantedtoV2 property and use unified roles instead of the cs3 roles

* enhancement: make use of owner conditions for drive listing

* enhancement: provide GetDrivesV1Beta1 and GetAllDrivesV1Beta1 graph endpoint tests
This commit is contained in:
Florian Schade
2023-12-06 10:01:38 +01:00
committed by GitHub
parent 59d8c43164
commit 34f3ab66c1
14 changed files with 578 additions and 84 deletions
+2
View File
@@ -84,6 +84,7 @@ Class | Method | HTTP request | Description
*DrivesApi* | [**GetDrive**](docs/DrivesApi.md#getdrive) | **Get** /v1.0/drives/{drive-id} | Get drive by id
*DrivesApi* | [**UpdateDrive**](docs/DrivesApi.md#updatedrive) | **Patch** /v1.0/drives/{drive-id} | Update the drive
*DrivesGetDrivesApi* | [**ListAllDrives**](docs/DrivesGetDrivesApi.md#listalldrives) | **Get** /v1.0/drives | Get all available drives
*DrivesGetDrivesApi* | [**ListAllDrivesBeta**](docs/DrivesGetDrivesApi.md#listalldrivesbeta) | **Get** /v1beta1/drives | Alias for '/v1.0/drives', the difference is that grantedtoV2 is used and roles contain unified roles instead of cs3 roles
*DrivesPermissionsApi* | [**CreateLink**](docs/DrivesPermissionsApi.md#createlink) | **Post** /v1beta1/drives/{drive-id}/items/{item-id}/createLink | Create a sharing link for a DriveItem
*DrivesPermissionsApi* | [**DeletePermission**](docs/DrivesPermissionsApi.md#deletepermission) | **Delete** /v1beta1/drives/{drive-id}/items/{item-id}/permissions/{perm-id} | Remove access to a DriveItem
*DrivesPermissionsApi* | [**GetPermission**](docs/DrivesPermissionsApi.md#getpermission) | **Get** /v1beta1/drives/{drive-id}/items/{item-id}/permissions/{perm-id} | Get sharing permission for a file or folder
@@ -134,6 +135,7 @@ Class | Method | HTTP request | Description
*MeDriveRootApi* | [**HomeGetRoot**](docs/MeDriveRootApi.md#homegetroot) | **Get** /v1.0/me/drive/root | Get root from personal space
*MeDriveRootChildrenApi* | [**HomeGetChildren**](docs/MeDriveRootChildrenApi.md#homegetchildren) | **Get** /v1.0/me/drive/root/children | Get children from drive
*MeDrivesApi* | [**ListMyDrives**](docs/MeDrivesApi.md#listmydrives) | **Get** /v1.0/me/drives | Get all drives where the current user is a regular member of
*MeDrivesApi* | [**ListMyDrivesBeta**](docs/MeDrivesApi.md#listmydrivesbeta) | **Get** /v1beta1/me/drives | Alias for '/v1.0/drives', the difference is that grantedtoV2 is used and roles contain unified roles instead of cs3 roles
*MeUserApi* | [**GetOwnUser**](docs/MeUserApi.md#getownuser) | **Get** /v1.0/me | Get current user
*MeUserApi* | [**UpdateOwnUser**](docs/MeUserApi.md#updateownuser) | **Patch** /v1.0/me | Update the current user
*RoleManagementApi* | [**GetPermissionRoleDefinition**](docs/RoleManagementApi.md#getpermissionroledefinition) | **Get** /v1beta1/roleManagement/permissions/roleDefinitions/{role-id} | Get unifiedRoleDefinition
+125
View File
@@ -145,3 +145,128 @@ func (a *DrivesGetDrivesApiService) ListAllDrivesExecute(r ApiListAllDrivesReque
return localVarReturnValue, localVarHTTPResponse, nil
}
type ApiListAllDrivesBetaRequest struct {
ctx context.Context
ApiService *DrivesGetDrivesApiService
orderby *string
filter *string
}
// The $orderby system query option allows clients to request resources in either ascending order using asc or descending order using desc.
func (r ApiListAllDrivesBetaRequest) Orderby(orderby string) ApiListAllDrivesBetaRequest {
r.orderby = &orderby
return r
}
// Filter items by property values
func (r ApiListAllDrivesBetaRequest) Filter(filter string) ApiListAllDrivesBetaRequest {
r.filter = &filter
return r
}
func (r ApiListAllDrivesBetaRequest) Execute() (*CollectionOfDrives1, *http.Response, error) {
return r.ApiService.ListAllDrivesBetaExecute(r)
}
/*
ListAllDrivesBeta Alias for '/v1.0/drives', the difference is that grantedtoV2 is used and roles contain unified roles instead of cs3 roles
@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
@return ApiListAllDrivesBetaRequest
*/
func (a *DrivesGetDrivesApiService) ListAllDrivesBeta(ctx context.Context) ApiListAllDrivesBetaRequest {
return ApiListAllDrivesBetaRequest{
ApiService: a,
ctx: ctx,
}
}
// Execute executes the request
// @return CollectionOfDrives1
func (a *DrivesGetDrivesApiService) ListAllDrivesBetaExecute(r ApiListAllDrivesBetaRequest) (*CollectionOfDrives1, *http.Response, error) {
var (
localVarHTTPMethod = http.MethodGet
localVarPostBody interface{}
formFiles []formFile
localVarReturnValue *CollectionOfDrives1
)
localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "DrivesGetDrivesApiService.ListAllDrivesBeta")
if err != nil {
return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}
}
localVarPath := localBasePath + "/v1beta1/drives"
localVarHeaderParams := make(map[string]string)
localVarQueryParams := url.Values{}
localVarFormParams := url.Values{}
if r.orderby != nil {
parameterAddToHeaderOrQuery(localVarQueryParams, "$orderby", r.orderby, "")
}
if r.filter != nil {
parameterAddToHeaderOrQuery(localVarQueryParams, "$filter", r.filter, "")
}
// to determine the Content-Type header
localVarHTTPContentTypes := []string{}
// set Content-Type header
localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)
if localVarHTTPContentType != "" {
localVarHeaderParams["Content-Type"] = localVarHTTPContentType
}
// to determine the Accept header
localVarHTTPHeaderAccepts := []string{"application/json"}
// set Accept header
localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
if localVarHTTPHeaderAccept != "" {
localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
}
req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)
if err != nil {
return localVarReturnValue, nil, err
}
localVarHTTPResponse, err := a.client.callAPI(req)
if err != nil || localVarHTTPResponse == nil {
return localVarReturnValue, localVarHTTPResponse, err
}
localVarBody, err := io.ReadAll(localVarHTTPResponse.Body)
localVarHTTPResponse.Body.Close()
localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))
if err != nil {
return localVarReturnValue, localVarHTTPResponse, err
}
if localVarHTTPResponse.StatusCode >= 300 {
newErr := &GenericOpenAPIError{
body: localVarBody,
error: localVarHTTPResponse.Status,
}
var v OdataError
err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
if err != nil {
newErr.error = err.Error()
return localVarReturnValue, localVarHTTPResponse, newErr
}
newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v)
newErr.model = v
return localVarReturnValue, localVarHTTPResponse, newErr
}
err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
if err != nil {
newErr := &GenericOpenAPIError{
body: localVarBody,
error: err.Error(),
}
return localVarReturnValue, localVarHTTPResponse, newErr
}
return localVarReturnValue, localVarHTTPResponse, nil
}
+125
View File
@@ -145,3 +145,128 @@ func (a *MeDrivesApiService) ListMyDrivesExecute(r ApiListMyDrivesRequest) (*Col
return localVarReturnValue, localVarHTTPResponse, nil
}
type ApiListMyDrivesBetaRequest struct {
ctx context.Context
ApiService *MeDrivesApiService
orderby *string
filter *string
}
// The $orderby system query option allows clients to request resources in either ascending order using asc or descending order using desc.
func (r ApiListMyDrivesBetaRequest) Orderby(orderby string) ApiListMyDrivesBetaRequest {
r.orderby = &orderby
return r
}
// Filter items by property values
func (r ApiListMyDrivesBetaRequest) Filter(filter string) ApiListMyDrivesBetaRequest {
r.filter = &filter
return r
}
func (r ApiListMyDrivesBetaRequest) Execute() (*CollectionOfDrives, *http.Response, error) {
return r.ApiService.ListMyDrivesBetaExecute(r)
}
/*
ListMyDrivesBeta Alias for '/v1.0/drives', the difference is that grantedtoV2 is used and roles contain unified roles instead of cs3 roles
@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
@return ApiListMyDrivesBetaRequest
*/
func (a *MeDrivesApiService) ListMyDrivesBeta(ctx context.Context) ApiListMyDrivesBetaRequest {
return ApiListMyDrivesBetaRequest{
ApiService: a,
ctx: ctx,
}
}
// Execute executes the request
// @return CollectionOfDrives
func (a *MeDrivesApiService) ListMyDrivesBetaExecute(r ApiListMyDrivesBetaRequest) (*CollectionOfDrives, *http.Response, error) {
var (
localVarHTTPMethod = http.MethodGet
localVarPostBody interface{}
formFiles []formFile
localVarReturnValue *CollectionOfDrives
)
localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "MeDrivesApiService.ListMyDrivesBeta")
if err != nil {
return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}
}
localVarPath := localBasePath + "/v1beta1/me/drives"
localVarHeaderParams := make(map[string]string)
localVarQueryParams := url.Values{}
localVarFormParams := url.Values{}
if r.orderby != nil {
parameterAddToHeaderOrQuery(localVarQueryParams, "$orderby", r.orderby, "")
}
if r.filter != nil {
parameterAddToHeaderOrQuery(localVarQueryParams, "$filter", r.filter, "")
}
// to determine the Content-Type header
localVarHTTPContentTypes := []string{}
// set Content-Type header
localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)
if localVarHTTPContentType != "" {
localVarHeaderParams["Content-Type"] = localVarHTTPContentType
}
// to determine the Accept header
localVarHTTPHeaderAccepts := []string{"application/json"}
// set Accept header
localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
if localVarHTTPHeaderAccept != "" {
localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
}
req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)
if err != nil {
return localVarReturnValue, nil, err
}
localVarHTTPResponse, err := a.client.callAPI(req)
if err != nil || localVarHTTPResponse == nil {
return localVarReturnValue, localVarHTTPResponse, err
}
localVarBody, err := io.ReadAll(localVarHTTPResponse.Body)
localVarHTTPResponse.Body.Close()
localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))
if err != nil {
return localVarReturnValue, localVarHTTPResponse, err
}
if localVarHTTPResponse.StatusCode >= 300 {
newErr := &GenericOpenAPIError{
body: localVarBody,
error: localVarHTTPResponse.Status,
}
var v OdataError
err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
if err != nil {
newErr.error = err.Error()
return localVarReturnValue, localVarHTTPResponse, newErr
}
newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v)
newErr.model = v
return localVarReturnValue, localVarHTTPResponse, newErr
}
err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
if err != nil {
newErr := &GenericOpenAPIError{
body: localVarBody,
error: err.Error(),
}
return localVarReturnValue, localVarHTTPResponse, newErr
}
return localVarReturnValue, localVarHTTPResponse, nil
}
@@ -19,7 +19,7 @@ var _ MappedNullable = &UnifiedRolePermission{}
// UnifiedRolePermission Represents a collection of allowed resource actions and the conditions that must be met for the action to be allowed. Resource actions are tasks that can be performed on a resource. For example, an application resource may support create, update, delete, and reset password actions.
type UnifiedRolePermission struct {
// Set of tasks that can be performed on a resource. Required. The following is the schema for resource actions: ``` {Namespace}/{Entity}/{PropertySet}/{Action} ``` For example: `libre.graph/applications/credentials/update` * *{Namespace}* - The services that exposes the task. For example, all tasks in libre graph use the namespace `libre.graph`. * *{Entity}* - The logical features or components exposed by the service in libre graph. For example, `applications`, `servicePrincipals`, or `groups`. * *{PropertySet}* - Optional. The specific properties or aspects of the entity for which access is being granted. For example, `libre.graph/applications/authentication/read` grants the ability to read the reply URL, logout URL, and implicit flow property on the **application** object in libre graph. The following are reserved names for common property sets: * `allProperties` - Designates all properties of the entity, including privileged properties. Examples include `libre.graph/applications/allProperties/read` and `libre.graph/applications/allProperties/update`. * `basic` - Designates common read properties but excludes privileged ones. For example, `libre.graph/applications/basic/update` includes the ability to update standard properties like display name. * `standard` - Designates common update properties but excludes privileged ones. For example, `libre.graph/applications/standard/read`. * *{Actions}* - The operations being granted. In most circumstances, permissions should be expressed in terms of CRUD operations or allTasks. Actions include: * `create` - The ability to create a new instance of the entity. * `read` - The ability to read a given property set (including allProperties). * `update` - The ability to update a given property set (including allProperties). * `delete` - The ability to delete a given entity. * `allTasks` - Represents all CRUD operations (create, read, update, and delete). Following the CS3 API we can represent the CS3 permissions by mapping them to driveItem properties or relations like this: | [CS3 ResourcePermission](https://cs3org.github.io/cs3apis/#cs3.storage.provider.v1beta1.ResourcePermissions) | action | comment | | ------------------------------------------------------------------------------------------------------------ | ------ | ------- | | `stat` | `libre.graph/driveItem/basic/read` | `basic` because it does not include versions or trashed items | | `get_quota` | `libre.graph/driveItem/quota/read` | read only the `quota` property | | `get_path` | `libre.graph/driveItem/path/read` | read only the `path` property | | `move` | `libre.graph/driveItem/path/update` | allows updating the `path` property of a CS3 resource | | `delete` | `libre.graph/driveItem/standard/delete` | `standard` because deleting is a common update operation | | `list_container` | `libre.graph/driveItem/children/read` | | | `create_container` | `libre.graph/driveItem/children/create` | | | `initiate_file_download` | `libre.graph/driveItem/content/read` | `content` is the property read when initiating a download | | `initiate_file_upload` | `libre.graph/driveItem/upload/create` | `uploads` are a separate property. postprocessing creates the `content` | | `add_grant` | `libre.graph/driveItem/permissions/create` | | | `list_grant` | `libre.graph/driveItem/permissions/read` | | | `update_grant` | `libre.graph/driveItem/permissions/update` | | | `remove_grant` | `libre.graph/driveItem/permissions/delete` | | | `deny_grant` | `libre.graph/driveItem/permissions/deny` | uses a non CRUD action `deny` | | `list_file_versions` | `libre.graph/driveItem/versions/read` | `versions` is a `driveItemVersion` collection | | `restore_file_version` | `libre.graph/driveItem/versions/update` | the only `update` action is restore | | `list_recycle` | `libre.graph/driveItem/deleted/read` | reading a driveItem `deleted` property implies listing | | `restore_recycle_item` | `libre.graph/driveItem/deleted/update` | the only `update` action is restore | | `purge_recycle` | `libre.graph/driveItem/deleted/delete` | allows purging deleted `driveItems` | Managing drives would be a different entity. A space manager role could be written as `libre.graph/drive/permission/allTasks`.
// Set of tasks that can be performed on a resource. Required. The following is the schema for resource actions: ``` {Namespace}/{Entity}/{PropertySet}/{Action} ``` For example: `libre.graph/applications/credentials/update` * *{Namespace}* - The services that exposes the task. For example, all tasks in libre graph use the namespace `libre.graph`. * *{Entity}* - The logical features or components exposed by the service in libre graph. For example, `applications`, `servicePrincipals`, or `groups`. * *{PropertySet}* - Optional. The specific properties or aspects of the entity for which access is being granted. For example, `libre.graph/applications/authentication/read` grants the ability to read the reply URL, logout URL, and implicit flow property on the **application** object in libre graph. The following are reserved names for common property sets: * `allProperties` - Designates all properties of the entity, including privileged properties. Examples include `libre.graph/applications/allProperties/read` and `libre.graph/applications/allProperties/update`. * `basic` - Designates common read properties but excludes privileged ones. For example, `libre.graph/applications/basic/update` includes the ability to update standard properties like display name. * `standard` - Designates common update properties but excludes privileged ones. For example, `libre.graph/applications/standard/read`. * *{Actions}* - The operations being granted. In most circumstances, permissions should be expressed in terms of CRUD operations or allTasks. Actions include: * `create` - The ability to create a new instance of the entity. * `read` - The ability to read a given property set (including allProperties). * `update` - The ability to update a given property set (including allProperties). * `delete` - The ability to delete a given entity. * `allTasks` - Represents all CRUD operations (create, read, update, and delete). Following the CS3 API we can represent the CS3 permissions by mapping them to driveItem properties or relations like this: | [CS3 ResourcePermission](https://cs3org.github.io/cs3apis/#cs3.storage.provider.v1beta1.ResourcePermissions) | action | comment | | ------------------------------------------------------------------------------------------------------------ | ------ | ------- | | `stat` | `libre.graph/driveItem/basic/read` | `basic` because it does not include versions or trashed items | | `get_quota` | `libre.graph/driveItem/quota/read` | read only the `quota` property | | `get_path` | `libre.graph/driveItem/path/read` | read only the `path` property | | `move` | `libre.graph/driveItem/path/update` | allows updating the `path` property of a CS3 resource | | `delete` | `libre.graph/driveItem/standard/delete` | `standard` because deleting is a common update operation | | `list_container` | `libre.graph/driveItem/children/read` | | | `create_container` | `libre.graph/driveItem/children/create` | | | `initiate_file_download` | `libre.graph/driveItem/content/read` | `content` is the property read when initiating a download | | `initiate_file_upload` | `libre.graph/driveItem/upload/create` | `uploads` are a separate property. postprocessing creates the `content` | | `add_grant` | `libre.graph/driveItem/permissions/create` | | | `list_grant` | `libre.graph/driveItem/permissions/read` | | | `update_grant` | `libre.graph/driveItem/permissions/update` | | | `remove_grant` | `libre.graph/driveItem/permissions/delete` | | | `deny_grant` | `libre.graph/driveItem/permissions/deny` | uses a non CRUD action `deny` | | `list_file_versions` | `libre.graph/driveItem/versions/read` | `versions` is a `driveItemVersion` collection | | `restore_file_version` | `libre.graph/driveItem/versions/update` | the only `update` action is restore | | `list_recycle` | `libre.graph/driveItem/deleted/read` | reading a driveItem `deleted` property implies listing | | `restore_recycle_item` | `libre.graph/driveItem/deleted/update` | the only `update` action is restore | | `purge_recycle` | `libre.graph/driveItem/deleted/delete` | allows purging deleted `driveItems` | Managing drives would be a different entity. A space manager role could be written as `libre.graph/drive/permission/allTasks`.
AllowedResourceActions []string `json:"allowedResourceActions,omitempty"`
// Optional constraints that must be met for the permission to be effective. Not supported for custom roles. Conditions define constraints that must be met. For example, a requirement that the principal be an owner of the target resource. The following are the supported conditions: * Self: `@Subject.objectId == @Resource.objectId` * Owner: `@Subject.objectId Any_of @Resource.owners` * Grantee: `@Subject.objectId Any_of @Resource.grantee` - does not exist in MS Graph, but we use it to express permissions on shared resources. The following is an example of a role permission with a condition that the principal be the owner of the target resource. ```json \"rolePermissions\": [ { \"allowedResourceActions\": [ \"libre.graph/applications/basic/update\", \"libre.graph/applications/credentials/update\" ], \"condition\": \"@Subject.objectId Any_of @Resource.owners\" } ] ``` Conditions aren't supported for custom roles.
Condition *string `json:"condition,omitempty"`