feat(site): add ability to create tokens from account tokens page (#6608)

* add token actions

* added basic token form

* removed token switch

* refined date field

* limiting lifetime days to maxTokenLifetime

* broke apart files

* added loader and error

* fixed form layout

* added some unit tests

* fixed be tests

* no authorize check
This commit is contained in:
Kira Pilot
2023-03-16 08:25:08 -07:00
committed by GitHub
parent af618477bd
commit 811a69f371
27 changed files with 737 additions and 131 deletions

42
coderd/apidoc/docs.go generated
View File

@ -3362,6 +3362,40 @@ const docTemplate = `{
}
}
},
"/users/{user}/keys/tokens/tokenconfig": {
"get": {
"security": [
{
"CoderSessionToken": []
}
],
"produces": [
"application/json"
],
"tags": [
"General"
],
"summary": "Get token config",
"operationId": "get-token-config",
"parameters": [
{
"type": "string",
"description": "User ID, name, or me",
"name": "user",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/codersdk.TokenConfig"
}
}
}
}
},
"/users/{user}/keys/tokens/{keyname}": {
"get": {
"security": [
@ -8121,6 +8155,14 @@ const docTemplate = `{
}
}
},
"codersdk.TokenConfig": {
"type": "object",
"properties": {
"max_token_lifetime": {
"type": "integer"
}
}
},
"codersdk.TraceConfig": {
"type": "object",
"properties": {

View File

@ -2952,6 +2952,36 @@
}
}
},
"/users/{user}/keys/tokens/tokenconfig": {
"get": {
"security": [
{
"CoderSessionToken": []
}
],
"produces": ["application/json"],
"tags": ["General"],
"summary": "Get token config",
"operationId": "get-token-config",
"parameters": [
{
"type": "string",
"description": "User ID, name, or me",
"name": "user",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/codersdk.TokenConfig"
}
}
}
}
},
"/users/{user}/keys/tokens/{keyname}": {
"get": {
"security": [
@ -7303,6 +7333,14 @@
}
}
},
"codersdk.TokenConfig": {
"type": "object",
"properties": {
"max_token_lifetime": {
"type": "integer"
}
}
},
"codersdk.TraceConfig": {
"type": "object",
"properties": {

View File

@ -6,6 +6,7 @@ import (
"database/sql"
"errors"
"fmt"
"math"
"net"
"net/http"
"strconv"
@ -339,6 +340,38 @@ func (api *API) deleteAPIKey(rw http.ResponseWriter, r *http.Request) {
httpapi.Write(ctx, rw, http.StatusNoContent, nil)
}
// @Summary Get token config
// @ID get-token-config
// @Security CoderSessionToken
// @Produce json
// @Tags General
// @Param user path string true "User ID, name, or me"
// @Success 200 {object} codersdk.TokenConfig
// @Router /users/{user}/keys/tokens/tokenconfig [get]
func (api *API) tokenConfig(rw http.ResponseWriter, r *http.Request) {
values, err := api.DeploymentValues.WithoutSecrets()
if err != nil {
httpapi.InternalServerError(rw, err)
return
}
var maxTokenLifetime time.Duration
// if --max-token-lifetime is unset (default value is math.MaxInt64)
// send back a falsy value
if values.MaxTokenLifetime.Value() == time.Duration(math.MaxInt64) {
maxTokenLifetime = 0
} else {
maxTokenLifetime = values.MaxTokenLifetime.Value()
}
httpapi.Write(
r.Context(), rw, http.StatusOK,
codersdk.TokenConfig{
MaxTokenLifetime: maxTokenLifetime,
},
)
}
// Generates a new ID and secret for an API key.
func GenerateAPIKeyIDSecret() (id string, secret string, err error) {
// Length of an API Key ID.

View File

@ -561,6 +561,7 @@ func New(options *Options) *API {
r.Route("/tokens", func(r chi.Router) {
r.Post("/", api.postToken)
r.Get("/", api.tokens)
r.Get("/tokenconfig", api.tokenConfig)
r.Route("/{keyname}", func(r chi.Router) {
r.Get("/", api.apiKeyByName)
})

View File

@ -99,6 +99,7 @@ func AGPLRoutes(a *AuthTester) (map[string]string, map[string]RouteCheck) {
AssertObject: rbac.ResourceAPIKey,
AssertAction: rbac.ActionRead,
},
"GET:/api/v2/users/{user}/keys/tokens/tokenconfig": {NoAuthorize: true},
"GET:/api/v2/workspacebuilds/{workspacebuild}": {
AssertAction: rbac.ActionRead,
AssertObject: workspaceRBACObj,