[IAM] - Add swagger docs for resource permissions API (#79525)

* IAM: Apply swagger-go comments for generating docs on resource permissions endpoints

* Update pkg/services/accesscontrol/resourcepermissions/api.go

Clarifies swagger note on assigning to service accounts

Co-authored-by: Ieva <ieva.vasiljeva@grafana.com>

---------

Co-authored-by: Ieva <ieva.vasiljeva@grafana.com>
This commit is contained in:
Aaron Godin 2023-12-18 16:47:17 -06:00 committed by GitHub
parent 65ecde6eed
commit eb490193b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 384 additions and 1 deletions

View File

@ -63,11 +63,26 @@ type Assignments struct {
BuiltInRoles bool `json:"builtInRoles"` BuiltInRoles bool `json:"builtInRoles"`
} }
// swagger:response resourcePermissionsDescription
type DescriptionResponse struct {
// in:body
// required:true
Body Description `json:"body"`
}
type Description struct { type Description struct {
Assignments Assignments `json:"assignments"` Assignments Assignments `json:"assignments"`
Permissions []string `json:"permissions"` 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 { func (a *api) getDescription(c *contextmodel.ReqContext) response.Response {
return response.JSON(http.StatusOK, &Description{ return response.JSON(http.StatusOK, &Description{
Permissions: a.permissions, Permissions: a.permissions,
@ -92,6 +107,17 @@ type resourcePermissionDTO struct {
Permission string `json:"permission"` 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 { func (a *api) getPermissions(c *contextmodel.ReqContext) response.Response {
resourceID := web.Params(c.Req)[":resourceID"] 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 { for _, p := range permissions {
if permission := a.service.MapActions(p); permission != "" { if permission := a.service.MapActions(p); permission != "" {
teamAvatarUrl := "" teamAvatarUrl := ""
@ -146,6 +172,19 @@ type setPermissionsCommand struct {
Permissions []accesscontrol.SetResourcePermissionCommand `json:"permissions"` 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 { func (a *api) setUserPermission(c *contextmodel.ReqContext) response.Response {
userID, err := strconv.ParseInt(web.Params(c.Req)[":userID"], 10, 64) userID, err := strconv.ParseInt(web.Params(c.Req)[":userID"], 10, 64)
if err != nil { if err != nil {
@ -166,6 +205,19 @@ func (a *api) setUserPermission(c *contextmodel.ReqContext) response.Response {
return permissionSetResponse(cmd) 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 { func (a *api) setTeamPermission(c *contextmodel.ReqContext) response.Response {
teamID, err := strconv.ParseInt(web.Params(c.Req)[":teamID"], 10, 64) teamID, err := strconv.ParseInt(web.Params(c.Req)[":teamID"], 10, 64)
if err != nil { if err != nil {
@ -186,6 +238,19 @@ func (a *api) setTeamPermission(c *contextmodel.ReqContext) response.Response {
return permissionSetResponse(cmd) 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 { func (a *api) setBuiltinRolePermission(c *contextmodel.ReqContext) response.Response {
builtInRole := web.Params(c.Req)[":builtInRole"] builtInRole := web.Params(c.Req)[":builtInRole"]
resourceID := web.Params(c.Req)[":resourceID"] resourceID := web.Params(c.Req)[":resourceID"]
@ -203,6 +268,19 @@ func (a *api) setBuiltinRolePermission(c *contextmodel.ReqContext) response.Resp
return permissionSetResponse(cmd) 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 { func (a *api) setPermissions(c *contextmodel.ReqContext) response.Response {
resourceID := web.Params(c.Req)[":resourceID"] resourceID := web.Params(c.Req)[":resourceID"]

View File

@ -2665,6 +2665,23 @@
} }
} }
}, },
"Assignments": {
"type": "object",
"properties": {
"builtInRoles": {
"type": "boolean"
},
"serviceAccounts": {
"type": "boolean"
},
"teams": {
"type": "boolean"
},
"users": {
"type": "boolean"
}
}
},
"AttributeTypeAndValue": { "AttributeTypeAndValue": {
"description": "AttributeTypeAndValue mirrors the ASN.1 structure of the same name in\nRFC 5280, Section 4.1.2.4.", "description": "AttributeTypeAndValue mirrors the ASN.1 structure of the same name in\nRFC 5280, Section 4.1.2.4.",
"type": "object", "type": "object",
@ -3929,6 +3946,20 @@
"format": "int64" "format": "int64"
} }
}, },
"Description": {
"type": "object",
"properties": {
"assignments": {
"$ref": "#/definitions/Assignments"
},
"permissions": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"DsAccess": { "DsAccess": {
"type": "string" "type": "string"
}, },
@ -7932,6 +7963,59 @@
"format": "int64" "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": { "responses": {
@ -8692,6 +8776,15 @@
} }
} }
}, },
"getResourcePermissionsResponse": {
"description": "",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/resourcePermissionDTO"
}
}
},
"getRoleAssignmentsResponse": { "getRoleAssignmentsResponse": {
"description": "", "description": "",
"schema": { "schema": {
@ -9101,6 +9194,12 @@
"$ref": "#/definitions/ActiveUserStats" "$ref": "#/definitions/ActiveUserStats"
} }
}, },
"resourcePermissionsDescription": {
"description": "",
"schema": {
"$ref": "#/definitions/Description"
}
},
"retrieveServiceAccountResponse": { "retrieveServiceAccountResponse": {
"description": "", "description": "",
"schema": { "schema": {

View File

@ -12339,6 +12339,23 @@
} }
} }
}, },
"Assignments": {
"type": "object",
"properties": {
"builtInRoles": {
"type": "boolean"
},
"serviceAccounts": {
"type": "boolean"
},
"teams": {
"type": "boolean"
},
"users": {
"type": "boolean"
}
}
},
"AttributeTypeAndValue": { "AttributeTypeAndValue": {
"description": "AttributeTypeAndValue mirrors the ASN.1 structure of the same name in\nRFC 5280, Section 4.1.2.4.", "description": "AttributeTypeAndValue mirrors the ASN.1 structure of the same name in\nRFC 5280, Section 4.1.2.4.",
"type": "object", "type": "object",
@ -13751,6 +13768,20 @@
"format": "int64" "format": "int64"
} }
}, },
"Description": {
"type": "object",
"properties": {
"assignments": {
"$ref": "#/definitions/Assignments"
},
"permissions": {
"type": "array",
"items": {
"type": "string"
}
}
}
},
"DiscordConfig": { "DiscordConfig": {
"type": "object", "type": "object",
"title": "DiscordConfig configures notifications via Discord.", "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": { "silence": {
"description": "Silence silence", "description": "Silence silence",
"type": "object", "type": "object",
@ -22126,6 +22210,15 @@
} }
} }
}, },
"getResourcePermissionsResponse": {
"description": "(empty)",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/resourcePermissionDTO"
}
}
},
"getRoleAssignmentsResponse": { "getRoleAssignmentsResponse": {
"description": "(empty)", "description": "(empty)",
"schema": { "schema": {
@ -22544,6 +22637,12 @@
"$ref": "#/definitions/ActiveUserStats" "$ref": "#/definitions/ActiveUserStats"
} }
}, },
"resourcePermissionsDescription": {
"description": "(empty)",
"schema": {
"$ref": "#/definitions/Description"
}
},
"retrieveServiceAccountResponse": { "retrieveServiceAccountResponse": {
"description": "(empty)", "description": "(empty)",
"schema": { "schema": {

View File

@ -1126,6 +1126,19 @@
}, },
"description": "(empty)" "description": "(empty)"
}, },
"getResourcePermissionsResponse": {
"content": {
"application/json": {
"schema": {
"items": {
"$ref": "#/components/schemas/resourcePermissionDTO"
},
"type": "array"
}
}
},
"description": "(empty)"
},
"getRoleAssignmentsResponse": { "getRoleAssignmentsResponse": {
"content": { "content": {
"application/json": { "application/json": {
@ -1700,6 +1713,16 @@
}, },
"description": "(empty)" "description": "(empty)"
}, },
"resourcePermissionsDescription": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Description"
}
}
},
"description": "(empty)"
},
"retrieveServiceAccountResponse": { "retrieveServiceAccountResponse": {
"content": { "content": {
"application/json": { "application/json": {
@ -3191,6 +3214,23 @@
}, },
"type": "object" "type": "object"
}, },
"Assignments": {
"properties": {
"builtInRoles": {
"type": "boolean"
},
"serviceAccounts": {
"type": "boolean"
},
"teams": {
"type": "boolean"
},
"users": {
"type": "boolean"
}
},
"type": "object"
},
"AttributeTypeAndValue": { "AttributeTypeAndValue": {
"description": "AttributeTypeAndValue mirrors the ASN.1 structure of the same name in\nRFC 5280, Section 4.1.2.4.", "description": "AttributeTypeAndValue mirrors the ASN.1 structure of the same name in\nRFC 5280, Section 4.1.2.4.",
"properties": { "properties": {
@ -4603,6 +4643,20 @@
}, },
"type": "object" "type": "object"
}, },
"Description": {
"properties": {
"assignments": {
"$ref": "#/components/schemas/Assignments"
},
"permissions": {
"items": {
"type": "string"
},
"type": "array"
}
},
"type": "object"
},
"DiscordConfig": { "DiscordConfig": {
"properties": { "properties": {
"http_config": { "http_config": {
@ -12105,6 +12159,59 @@
], ],
"type": "object" "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": { "silence": {
"description": "Silence silence", "description": "Silence silence",
"properties": { "properties": {