Add route "/users/:uid/keys/current"
This commit is contained in:
parent
0b7fb533da
commit
189c3ab273
@ -56,6 +56,55 @@ func (h APIHandler) ListUserKeys(g *gin.Context) ginresp.HTTPResponse {
|
|||||||
return ctx.FinishSuccess(ginresp.JSON(http.StatusOK, response{Keys: res}))
|
return ctx.FinishSuccess(ginresp.JSON(http.StatusOK, response{Keys: res}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetCurrentUserKey swaggerdoc
|
||||||
|
//
|
||||||
|
// @Summary Get the key currently used by this request
|
||||||
|
// @Description Can be done with keys of any permission - the returned key does not include its token.
|
||||||
|
// @ID api-tokenkeys-get-current
|
||||||
|
// @Tags API-v2
|
||||||
|
//
|
||||||
|
// @Param uid path string true "UserID"
|
||||||
|
// @Param kid path string true "TokenKeyID"
|
||||||
|
//
|
||||||
|
// @Success 200 {object} models.KeyTokenWithTokenJSON
|
||||||
|
// @Failure 400 {object} ginresp.apiError "supplied values/parameters cannot be parsed / are invalid"
|
||||||
|
// @Failure 401 {object} ginresp.apiError "user is not authorized / has missing permissions"
|
||||||
|
// @Failure 404 {object} ginresp.apiError "message not found"
|
||||||
|
// @Failure 500 {object} ginresp.apiError "internal server error"
|
||||||
|
//
|
||||||
|
// @Router /api/v2/users/{uid}/keys/current [GET]
|
||||||
|
func (h APIHandler) GetCurrentUserKey(g *gin.Context) ginresp.HTTPResponse {
|
||||||
|
type uri struct {
|
||||||
|
UserID models.UserID `uri:"uid" binding:"entityid"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var u uri
|
||||||
|
ctx, errResp := h.app.StartRequest(g, &u, nil, nil, nil)
|
||||||
|
if errResp != nil {
|
||||||
|
return *errResp
|
||||||
|
}
|
||||||
|
defer ctx.Cancel()
|
||||||
|
|
||||||
|
if permResp := ctx.CheckPermissionAny(); permResp != nil {
|
||||||
|
return *permResp
|
||||||
|
}
|
||||||
|
|
||||||
|
tokid := ctx.GetPermissionKeyTokenID()
|
||||||
|
if tokid == nil {
|
||||||
|
return ginresp.APIError(g, 400, apierr.USER_AUTH_FAILED, "Missing KeyTokenID in context", nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
keytoken, err := h.database.GetKeyToken(ctx, u.UserID, *tokid)
|
||||||
|
if errors.Is(err, sql.ErrNoRows) {
|
||||||
|
return ginresp.APIError(g, 404, apierr.KEY_NOT_FOUND, "Key not found", err)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return ginresp.APIError(g, 500, apierr.DATABASE_ERROR, "Failed to query client", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx.FinishSuccess(ginresp.JSON(http.StatusOK, keytoken.JSON().WithToken(keytoken.Token)))
|
||||||
|
}
|
||||||
|
|
||||||
// GetUserKey swaggerdoc
|
// GetUserKey swaggerdoc
|
||||||
//
|
//
|
||||||
// @Summary Get a single key
|
// @Summary Get a single key
|
||||||
|
@ -130,6 +130,7 @@ func (r *Router) Init(e *gin.Engine) error {
|
|||||||
|
|
||||||
apiv2.GET("/users/:uid/keys", r.Wrap(r.apiHandler.ListUserKeys))
|
apiv2.GET("/users/:uid/keys", r.Wrap(r.apiHandler.ListUserKeys))
|
||||||
apiv2.POST("/users/:uid/keys", r.Wrap(r.apiHandler.CreateUserKey))
|
apiv2.POST("/users/:uid/keys", r.Wrap(r.apiHandler.CreateUserKey))
|
||||||
|
apiv2.GET("/users/:uid/keys/current", r.Wrap(r.apiHandler.GetCurrentUserKey))
|
||||||
apiv2.GET("/users/:uid/keys/:kid", r.Wrap(r.apiHandler.GetUserKey))
|
apiv2.GET("/users/:uid/keys/:kid", r.Wrap(r.apiHandler.GetUserKey))
|
||||||
apiv2.PATCH("/users/:uid/keys/:kid", r.Wrap(r.apiHandler.UpdateUserKey))
|
apiv2.PATCH("/users/:uid/keys/:kid", r.Wrap(r.apiHandler.UpdateUserKey))
|
||||||
apiv2.DELETE("/users/:uid/keys/:kid", r.Wrap(r.apiHandler.DeleteUserKey))
|
apiv2.DELETE("/users/:uid/keys/:kid", r.Wrap(r.apiHandler.DeleteUserKey))
|
||||||
|
@ -109,7 +109,7 @@ type KeyTokenWithTokenJSON struct {
|
|||||||
Token string `json:"token"`
|
Token string `json:"token"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (j KeyTokenJSON) WithToken(tok string) any {
|
func (j KeyTokenJSON) WithToken(tok string) KeyTokenWithTokenJSON {
|
||||||
return KeyTokenWithTokenJSON{
|
return KeyTokenWithTokenJSON{
|
||||||
KeyTokenJSON: j,
|
KeyTokenJSON: j,
|
||||||
Token: tok,
|
Token: tok,
|
||||||
|
@ -672,3 +672,53 @@ func TestTokenKeysCreateDefaultParam(t *testing.T) {
|
|||||||
tt.AssertEqual(t, "Channels.Len", 0, len(key2.Channels))
|
tt.AssertEqual(t, "Channels.Len", 0, len(key2.Channels))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTokenKeysGetCurrent(t *testing.T) {
|
||||||
|
ws, baseUrl, stop := tt.StartSimpleWebserver(t)
|
||||||
|
defer stop()
|
||||||
|
|
||||||
|
data := tt.InitSingleData(t, ws)
|
||||||
|
|
||||||
|
type keyobj struct {
|
||||||
|
AllChannels bool `json:"all_channels"`
|
||||||
|
Channels []string `json:"channels"`
|
||||||
|
KeytokenId string `json:"keytoken_id"`
|
||||||
|
MessagesSent int `json:"messages_sent"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
OwnerUserId string `json:"owner_user_id"`
|
||||||
|
Permissions string `json:"permissions"`
|
||||||
|
Token string `json:"token"` // only in create
|
||||||
|
}
|
||||||
|
type keylist struct {
|
||||||
|
Keys []keyobj `json:"keys"`
|
||||||
|
}
|
||||||
|
|
||||||
|
klist := tt.RequestAuthGet[keylist](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys", data.UID))
|
||||||
|
tt.AssertEqual(t, "len(keys)", 3, len(klist.Keys))
|
||||||
|
|
||||||
|
keyAdmin := *langext.ArrFirstOrNil(klist.Keys, func(v keyobj) bool { return v.Permissions == "A" })
|
||||||
|
keySend := *langext.ArrFirstOrNil(klist.Keys, func(v keyobj) bool { return v.Permissions == "CS" })
|
||||||
|
keyRead := *langext.ArrFirstOrNil(klist.Keys, func(v keyobj) bool { return v.Permissions == "UR;CR" })
|
||||||
|
|
||||||
|
{
|
||||||
|
currKey := tt.RequestAuthGet[keyobj](t, data.AdminKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/current", data.UID))
|
||||||
|
tt.AssertEqual(t, "currKey.KeytokenId", keyAdmin.KeytokenId, currKey.KeytokenId)
|
||||||
|
tt.AssertEqual(t, "currKey.Permissions", "A", currKey.Permissions)
|
||||||
|
tt.AssertEqual(t, "currKey.Token", data.AdminKey, currKey.Token)
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
currKey := tt.RequestAuthGet[keyobj](t, data.SendKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/current", data.UID))
|
||||||
|
tt.AssertEqual(t, "currKey.KeytokenId", keySend.KeytokenId, currKey.KeytokenId)
|
||||||
|
tt.AssertEqual(t, "currKey.Permissions", "CS", currKey.Permissions)
|
||||||
|
tt.AssertEqual(t, "currKey.Token", data.SendKey, currKey.Token)
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
currKey := tt.RequestAuthGet[keyobj](t, data.ReadKey, baseUrl, fmt.Sprintf("/api/v2/users/%s/keys/current", data.UID))
|
||||||
|
tt.AssertEqual(t, "currKey.KeytokenId", keyRead.KeytokenId, currKey.KeytokenId)
|
||||||
|
tt.AssertEqual(t, "currKey.Permissions", "UR;CR", currKey.Permissions)
|
||||||
|
tt.AssertEqual(t, "currKey.Token", data.ReadKey, currKey.Token)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user