diff --git a/pkg/services/accesscontrol/resourcepermissions/api.go b/pkg/services/accesscontrol/resourcepermissions/api.go index 9ab6cf9f1c4..e79a06a02bd 100644 --- a/pkg/services/accesscontrol/resourcepermissions/api.go +++ b/pkg/services/accesscontrol/resourcepermissions/api.go @@ -63,11 +63,26 @@ type Assignments struct { BuiltInRoles bool `json:"builtInRoles"` } +// swagger:response resourcePermissionsDescription +type DescriptionResponse struct { + // in:body + // required:true + Body Description `json:"body"` +} + type Description struct { Assignments Assignments `json:"assignments"` Permissions []string `json:"permissions"` } +// swagger:route POST /access-control/:resource/description enterprise,access_control getResourceDescription +// +// Get a description of a resource's access control properties. +// +// Responses: +// 200: resourcePermissionsDescription +// 403: forbiddenError +// 500: internalServerError func (a *api) getDescription(c *contextmodel.ReqContext) response.Response { return response.JSON(http.StatusOK, &Description{ Permissions: a.permissions, @@ -92,6 +107,17 @@ type resourcePermissionDTO struct { Permission string `json:"permission"` } +// swagger:response getResourcePermissionsResponse +type getResourcePermissionsResponse []resourcePermissionDTO + +// swagger:route POST /access-control/:resource/:resourceID enterprise,access_control getResourcePermissions +// +// Get permissions for a resource. +// +// Responses: +// 200: getResourcePermissionsResponse +// 403: forbiddenError +// 500: internalServerError func (a *api) getPermissions(c *contextmodel.ReqContext) response.Response { resourceID := web.Params(c.Req)[":resourceID"] @@ -108,7 +134,7 @@ func (a *api) getPermissions(c *contextmodel.ReqContext) response.Response { }) } - dto := make([]resourcePermissionDTO, 0, len(permissions)) + dto := make(getResourcePermissionsResponse, 0, len(permissions)) for _, p := range permissions { if permission := a.service.MapActions(p); permission != "" { teamAvatarUrl := "" @@ -146,6 +172,19 @@ type setPermissionsCommand struct { Permissions []accesscontrol.SetResourcePermissionCommand `json:"permissions"` } +// swagger:route POST /access-control/:resource/:resourceID/users/:userID enterprise,access_control setResourcePermissionsForUser +// +// Set resource permissions for a user. +// +// Assigns permissions for a resource by a given type (`:resource`) and `:resourceID` to a user or a service account. +// Allowed resources are `datasources`, `teams`, `dashboards`, `folders`, and `serviceaccounts`. +// Refer to the `/access-control/:resource/description` endpoint for allowed Permissions. +// +// Responses: +// 200: okRespoonse +// 400: badRequestError +// 403: forbiddenError +// 500: internalServerError func (a *api) setUserPermission(c *contextmodel.ReqContext) response.Response { userID, err := strconv.ParseInt(web.Params(c.Req)[":userID"], 10, 64) if err != nil { @@ -166,6 +205,19 @@ func (a *api) setUserPermission(c *contextmodel.ReqContext) response.Response { return permissionSetResponse(cmd) } +// swagger:route POST /access-control/:resource/:resourceID/teams/:teamID enterprise,access_control setResourcePermissionsForTeam +// +// Set resource permissions for a team. +// +// Assigns permissions for a resource by a given type (`:resource`) and `:resourceID` to a team. +// Allowed resources are `datasources`, `teams`, `dashboards`, `folders`, and `serviceaccounts`. +// Refer to the `/access-control/:resource/description` endpoint for allowed Permissions. +// +// Responses: +// 200: okRespoonse +// 400: badRequestError +// 403: forbiddenError +// 500: internalServerError func (a *api) setTeamPermission(c *contextmodel.ReqContext) response.Response { teamID, err := strconv.ParseInt(web.Params(c.Req)[":teamID"], 10, 64) if err != nil { @@ -186,6 +238,19 @@ func (a *api) setTeamPermission(c *contextmodel.ReqContext) response.Response { return permissionSetResponse(cmd) } +// swagger:route POST /access-control/:resource/:resourceID/builtInRoles/:builtInRole enterprise,access_control setResourcePermissionsForBuiltInRole +// +// Set resource permissions for a built-in role. +// +// Assigns permissions for a resource by a given type (`:resource`) and `:resourceID` to a built-in role. +// Allowed resources are `datasources`, `teams`, `dashboards`, `folders`, and `serviceaccounts`. +// Refer to the `/access-control/:resource/description` endpoint for allowed Permissions. +// +// Responses: +// 200: okRespoonse +// 400: badRequestError +// 403: forbiddenError +// 500: internalServerError func (a *api) setBuiltinRolePermission(c *contextmodel.ReqContext) response.Response { builtInRole := web.Params(c.Req)[":builtInRole"] resourceID := web.Params(c.Req)[":resourceID"] @@ -203,6 +268,19 @@ func (a *api) setBuiltinRolePermission(c *contextmodel.ReqContext) response.Resp return permissionSetResponse(cmd) } +// swagger:route POST /access-control/:resource/:resourceID enterprise,access_control setResourcePermissions +// +// Set resource permissions. +// +// Assigns permissions for a resource by a given type (`:resource`) and `:resourceID` to one or many +// assignment types. Allowed resources are `datasources`, `teams`, `dashboards`, `folders`, and `serviceaccounts`. +// Refer to the `/access-control/:resource/description` endpoint for allowed Permissions. +// +// Responses: +// 200: okRespoonse +// 400: badRequestError +// 403: forbiddenError +// 500: internalServerError func (a *api) setPermissions(c *contextmodel.ReqContext) response.Response { resourceID := web.Params(c.Req)[":resourceID"] diff --git a/public/api-enterprise-spec.json b/public/api-enterprise-spec.json index 7ba4241aee7..9763217df00 100644 --- a/public/api-enterprise-spec.json +++ b/public/api-enterprise-spec.json @@ -2665,6 +2665,23 @@ } } }, + "Assignments": { + "type": "object", + "properties": { + "builtInRoles": { + "type": "boolean" + }, + "serviceAccounts": { + "type": "boolean" + }, + "teams": { + "type": "boolean" + }, + "users": { + "type": "boolean" + } + } + }, "AttributeTypeAndValue": { "description": "AttributeTypeAndValue mirrors the ASN.1 structure of the same name in\nRFC 5280, Section 4.1.2.4.", "type": "object", @@ -3929,6 +3946,20 @@ "format": "int64" } }, + "Description": { + "type": "object", + "properties": { + "assignments": { + "$ref": "#/definitions/Assignments" + }, + "permissions": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, "DsAccess": { "type": "string" }, @@ -7932,6 +7963,59 @@ "format": "int64" } } + }, + "resourcePermissionDTO": { + "type": "object", + "properties": { + "actions": { + "type": "array", + "items": { + "type": "string" + } + }, + "builtInRole": { + "type": "string" + }, + "id": { + "type": "integer", + "format": "int64" + }, + "isInherited": { + "type": "boolean" + }, + "isManaged": { + "type": "boolean" + }, + "isServiceAccount": { + "type": "boolean" + }, + "permission": { + "type": "string" + }, + "roleName": { + "type": "string" + }, + "team": { + "type": "string" + }, + "teamAvatarUrl": { + "type": "string" + }, + "teamId": { + "type": "integer", + "format": "int64" + }, + "userAvatarUrl": { + "type": "string" + }, + "userId": { + "type": "integer", + "format": "int64" + }, + "userLogin": { + "type": "string" + } + } } }, "responses": { @@ -8692,6 +8776,15 @@ } } }, + "getResourcePermissionsResponse": { + "description": "", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/resourcePermissionDTO" + } + } + }, "getRoleAssignmentsResponse": { "description": "", "schema": { @@ -9101,6 +9194,12 @@ "$ref": "#/definitions/ActiveUserStats" } }, + "resourcePermissionsDescription": { + "description": "", + "schema": { + "$ref": "#/definitions/Description" + } + }, "retrieveServiceAccountResponse": { "description": "", "schema": { diff --git a/public/api-merged.json b/public/api-merged.json index 9e03dcc5a9a..997789bc407 100644 --- a/public/api-merged.json +++ b/public/api-merged.json @@ -12339,6 +12339,23 @@ } } }, + "Assignments": { + "type": "object", + "properties": { + "builtInRoles": { + "type": "boolean" + }, + "serviceAccounts": { + "type": "boolean" + }, + "teams": { + "type": "boolean" + }, + "users": { + "type": "boolean" + } + } + }, "AttributeTypeAndValue": { "description": "AttributeTypeAndValue mirrors the ASN.1 structure of the same name in\nRFC 5280, Section 4.1.2.4.", "type": "object", @@ -13751,6 +13768,20 @@ "format": "int64" } }, + "Description": { + "type": "object", + "properties": { + "assignments": { + "$ref": "#/definitions/Assignments" + }, + "permissions": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, "DiscordConfig": { "type": "object", "title": "DiscordConfig configures notifications via Discord.", @@ -21255,6 +21286,59 @@ } } }, + "resourcePermissionDTO": { + "type": "object", + "properties": { + "actions": { + "type": "array", + "items": { + "type": "string" + } + }, + "builtInRole": { + "type": "string" + }, + "id": { + "type": "integer", + "format": "int64" + }, + "isInherited": { + "type": "boolean" + }, + "isManaged": { + "type": "boolean" + }, + "isServiceAccount": { + "type": "boolean" + }, + "permission": { + "type": "string" + }, + "roleName": { + "type": "string" + }, + "team": { + "type": "string" + }, + "teamAvatarUrl": { + "type": "string" + }, + "teamId": { + "type": "integer", + "format": "int64" + }, + "userAvatarUrl": { + "type": "string" + }, + "userId": { + "type": "integer", + "format": "int64" + }, + "userLogin": { + "type": "string" + } + } + }, "silence": { "description": "Silence silence", "type": "object", @@ -22126,6 +22210,15 @@ } } }, + "getResourcePermissionsResponse": { + "description": "(empty)", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/resourcePermissionDTO" + } + } + }, "getRoleAssignmentsResponse": { "description": "(empty)", "schema": { @@ -22544,6 +22637,12 @@ "$ref": "#/definitions/ActiveUserStats" } }, + "resourcePermissionsDescription": { + "description": "(empty)", + "schema": { + "$ref": "#/definitions/Description" + } + }, "retrieveServiceAccountResponse": { "description": "(empty)", "schema": { diff --git a/public/openapi3.json b/public/openapi3.json index 40cbf3854bc..e6329c603bf 100644 --- a/public/openapi3.json +++ b/public/openapi3.json @@ -1126,6 +1126,19 @@ }, "description": "(empty)" }, + "getResourcePermissionsResponse": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/resourcePermissionDTO" + }, + "type": "array" + } + } + }, + "description": "(empty)" + }, "getRoleAssignmentsResponse": { "content": { "application/json": { @@ -1700,6 +1713,16 @@ }, "description": "(empty)" }, + "resourcePermissionsDescription": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Description" + } + } + }, + "description": "(empty)" + }, "retrieveServiceAccountResponse": { "content": { "application/json": { @@ -3191,6 +3214,23 @@ }, "type": "object" }, + "Assignments": { + "properties": { + "builtInRoles": { + "type": "boolean" + }, + "serviceAccounts": { + "type": "boolean" + }, + "teams": { + "type": "boolean" + }, + "users": { + "type": "boolean" + } + }, + "type": "object" + }, "AttributeTypeAndValue": { "description": "AttributeTypeAndValue mirrors the ASN.1 structure of the same name in\nRFC 5280, Section 4.1.2.4.", "properties": { @@ -4603,6 +4643,20 @@ }, "type": "object" }, + "Description": { + "properties": { + "assignments": { + "$ref": "#/components/schemas/Assignments" + }, + "permissions": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, "DiscordConfig": { "properties": { "http_config": { @@ -12105,6 +12159,59 @@ ], "type": "object" }, + "resourcePermissionDTO": { + "properties": { + "actions": { + "items": { + "type": "string" + }, + "type": "array" + }, + "builtInRole": { + "type": "string" + }, + "id": { + "format": "int64", + "type": "integer" + }, + "isInherited": { + "type": "boolean" + }, + "isManaged": { + "type": "boolean" + }, + "isServiceAccount": { + "type": "boolean" + }, + "permission": { + "type": "string" + }, + "roleName": { + "type": "string" + }, + "team": { + "type": "string" + }, + "teamAvatarUrl": { + "type": "string" + }, + "teamId": { + "format": "int64", + "type": "integer" + }, + "userAvatarUrl": { + "type": "string" + }, + "userId": { + "format": "int64", + "type": "integer" + }, + "userLogin": { + "type": "string" + } + }, + "type": "object" + }, "silence": { "description": "Silence silence", "properties": {