Add GET /v3/iam/user endpoint

This commit is contained in:
Ingo Oppermann
2023-06-20 20:27:51 +02:00
parent ee45c85c29
commit 7565427f9a
6 changed files with 209 additions and 5 deletions

View File

@@ -1711,6 +1711,33 @@ const docTemplate = `{
}
},
"/api/v3/iam/user": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "List of identities in IAM",
"produces": [
"application/json"
],
"tags": [
"v16.?.?"
],
"summary": "List of identities in IAM",
"operationId": "iam-3-list-identities",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/api.IAMUser"
}
}
}
}
},
"post": {
"security": [
{
@@ -1759,6 +1786,12 @@ const docTemplate = `{
"$ref": "#/definitions/api.Error"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/api.Error"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
@@ -1806,6 +1839,12 @@ const docTemplate = `{
"$ref": "#/definitions/api.IAMUser"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/api.Error"
}
},
"404": {
"description": "Not Found",
"schema": {
@@ -1869,6 +1908,12 @@ const docTemplate = `{
"$ref": "#/definitions/api.Error"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/api.Error"
}
},
"404": {
"description": "Not Found",
"schema": {
@@ -1920,6 +1965,12 @@ const docTemplate = `{
"type": "string"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/api.Error"
}
},
"404": {
"description": "Not Found",
"schema": {
@@ -1997,6 +2048,12 @@ const docTemplate = `{
"$ref": "#/definitions/api.Error"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/api.Error"
}
},
"404": {
"description": "Not Found",
"schema": {

View File

@@ -1703,6 +1703,33 @@
}
},
"/api/v3/iam/user": {
"get": {
"security": [
{
"ApiKeyAuth": []
}
],
"description": "List of identities in IAM",
"produces": [
"application/json"
],
"tags": [
"v16.?.?"
],
"summary": "List of identities in IAM",
"operationId": "iam-3-list-identities",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/api.IAMUser"
}
}
}
}
},
"post": {
"security": [
{
@@ -1751,6 +1778,12 @@
"$ref": "#/definitions/api.Error"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/api.Error"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
@@ -1798,6 +1831,12 @@
"$ref": "#/definitions/api.IAMUser"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/api.Error"
}
},
"404": {
"description": "Not Found",
"schema": {
@@ -1861,6 +1900,12 @@
"$ref": "#/definitions/api.Error"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/api.Error"
}
},
"404": {
"description": "Not Found",
"schema": {
@@ -1912,6 +1957,12 @@
"type": "string"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/api.Error"
}
},
"404": {
"description": "Not Found",
"schema": {
@@ -1989,6 +2040,12 @@
"$ref": "#/definitions/api.Error"
}
},
"403": {
"description": "Forbidden",
"schema": {
"$ref": "#/definitions/api.Error"
}
},
"404": {
"description": "Not Found",
"schema": {

View File

@@ -3489,6 +3489,23 @@ paths:
tags:
- v16.7.2
/api/v3/iam/user:
get:
description: List of identities in IAM
operationId: iam-3-list-identities
produces:
- application/json
responses:
"200":
description: OK
schema:
items:
$ref: '#/definitions/api.IAMUser'
type: array
security:
- ApiKeyAuth: []
summary: List of identities in IAM
tags:
- v16.?.?
post:
consumes:
- application/json
@@ -3516,6 +3533,10 @@ paths:
description: Bad Request
schema:
$ref: '#/definitions/api.Error'
"403":
description: Forbidden
schema:
$ref: '#/definitions/api.Error'
"500":
description: Internal Server Error
schema:
@@ -3546,6 +3567,10 @@ paths:
description: OK
schema:
type: string
"403":
description: Forbidden
schema:
$ref: '#/definitions/api.Error'
"404":
description: Not Found
schema:
@@ -3579,6 +3604,10 @@ paths:
description: OK
schema:
$ref: '#/definitions/api.IAMUser'
"403":
description: Forbidden
schema:
$ref: '#/definitions/api.Error'
"404":
description: Not Found
schema:
@@ -3620,6 +3649,10 @@ paths:
description: Bad Request
schema:
$ref: '#/definitions/api.Error'
"403":
description: Forbidden
schema:
$ref: '#/definitions/api.Error'
"404":
description: Not Found
schema:
@@ -3670,6 +3703,10 @@ paths:
description: Bad Request
schema:
$ref: '#/definitions/api.Error'
"403":
description: Forbidden
schema:
$ref: '#/definitions/api.Error'
"404":
description: Not Found
schema:

View File

@@ -812,7 +812,7 @@ func (h *ClusterHandler) UpdateIdentityPolicies(c echo.Context) error {
err = h.cluster.SetPolicies("", name, accessPolicies)
if err != nil {
return api.Err(http.StatusInternalServerError, "", "set policies: %w", err)
return api.Err(http.StatusInternalServerError, "", "set policies: %s", err.Error())
}
return c.JSON(http.StatusOK, policies)

View File

@@ -32,6 +32,7 @@ func NewIAM(iam iam.IAM) *IAMHandler {
// @Param domain query string false "Domain of the acting user"
// @Success 200 {object} api.IAMUser
// @Failure 400 {object} api.Error
// @Failure 403 {object} api.Error
// @Failure 500 {object} api.Error
// @Security ApiKeyAuth
// @Router /api/v3/iam/user [post]
@@ -83,6 +84,7 @@ func (h *IAMHandler) AddIdentity(c echo.Context) error {
// @Param name path string true "Username"
// @Param domain query string false "Domain of the acting user"
// @Success 200 {string} string
// @Failure 403 {object} api.Error
// @Failure 404 {object} api.Error
// @Failure 500 {object} api.Error
// @Security ApiKeyAuth
@@ -130,6 +132,7 @@ func (h *IAMHandler) RemoveIdentity(c echo.Context) error {
// @Param user body api.IAMUser true "User definition"
// @Success 200 {object} api.IAMUser
// @Failure 400 {object} api.Error
// @Failure 403 {object} api.Error
// @Failure 404 {object} api.Error
// @Failure 500 {object} api.Error
// @Security ApiKeyAuth
@@ -211,6 +214,7 @@ func (h *IAMHandler) UpdateIdentity(c echo.Context) error {
// @Param user body []api.IAMPolicy true "Policy definitions"
// @Success 200 {array} api.IAMPolicy
// @Failure 400 {object} api.Error
// @Failure 403 {object} api.Error
// @Failure 404 {object} api.Error
// @Failure 500 {object} api.Error
// @Security ApiKeyAuth
@@ -271,6 +275,50 @@ func (h *IAMHandler) UpdateIdentityPolicies(c echo.Context) error {
return c.JSON(http.StatusOK, policies)
}
// ListIdentities returns the list of identities stored in IAM
// @Summary List of identities in IAM
// @Description List of identities in IAM
// @Tags v16.?.?
// @ID iam-3-list-identities
// @Produce json
// @Success 200 {array} api.IAMUser
// @Security ApiKeyAuth
// @Router /api/v3/iam/user [get]
func (h *IAMHandler) ListIdentities(c echo.Context) error {
ctxuser := util.DefaultContext(c, "user", "")
domain := util.DefaultQuery(c, "domain", "$none")
identities := h.iam.ListIdentities()
users := make([]api.IAMUser, len(identities)+1)
for i, iamuser := range identities {
if !h.iam.Enforce(ctxuser, domain, "iam:"+iamuser.Name, "read") {
continue
}
if !h.iam.Enforce(ctxuser, domain, "iam:"+iamuser.Name, "write") {
iamuser = identity.User{
Name: iamuser.Name,
}
}
policies := h.iam.ListPolicies(iamuser.Name, "", "", nil)
users[i].Marshal(iamuser, policies)
}
anon := identity.User{
Name: "$anon",
}
policies := h.iam.ListPolicies("$anon", "", "", nil)
users[len(users)-1].Marshal(anon, policies)
return c.JSON(http.StatusOK, users)
}
// GetIdentity returns the user with the given name
// @Summary List an user by its name
// @Description List aa user by its name
@@ -280,6 +328,7 @@ func (h *IAMHandler) UpdateIdentityPolicies(c echo.Context) error {
// @Param name path string true "Username"
// @Param domain query string false "Domain of the acting user"
// @Success 200 {object} api.IAMUser
// @Failure 403 {object} api.Error
// @Failure 404 {object} api.Error
// @Security ApiKeyAuth
// @Router /api/v3/iam/user/{name} [get]

View File

@@ -556,11 +556,15 @@ func (s *server) setRoutesV3(v3 *echo.Group) {
// v3 IAM
if s.v3handler.iam != nil {
v3.POST("/iam/user", s.v3handler.iam.AddIdentity)
v3.GET("/iam/user", s.v3handler.iam.ListIdentities)
v3.GET("/iam/user/:name", s.v3handler.iam.GetIdentity)
v3.PUT("/iam/user/:name", s.v3handler.iam.UpdateIdentity)
v3.PUT("/iam/user/:name/policy", s.v3handler.iam.UpdateIdentityPolicies)
v3.DELETE("/iam/user/:name", s.v3handler.iam.RemoveIdentity)
if !s.readOnly {
v3.POST("/iam/user", s.v3handler.iam.AddIdentity)
v3.PUT("/iam/user/:name", s.v3handler.iam.UpdateIdentity)
v3.PUT("/iam/user/:name/policy", s.v3handler.iam.UpdateIdentityPolicies)
v3.DELETE("/iam/user/:name", s.v3handler.iam.RemoveIdentity)
}
}
// v3 Restreamer