fix: add back missing postAPIKey route (#4406)

This commit is contained in:
Garrett Delfosse 2022-10-06 17:56:43 -04:00 committed by GitHub
parent a89d6909b2
commit 32bb1e7ce9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 62 additions and 0 deletions

View File

@ -53,6 +53,41 @@ func (api *API) postToken(rw http.ResponseWriter, r *http.Request) {
httpapi.Write(ctx, rw, http.StatusCreated, codersdk.GenerateAPIKeyResponse{Key: cookie.Value})
}
// Creates a new session key, used for logging in via the CLI.
func (api *API) postAPIKey(rw http.ResponseWriter, r *http.Request) {
ctx := r.Context()
user := httpmw.UserParam(r)
if !api.Authorize(r, rbac.ActionCreate, rbac.ResourceAPIKey.WithOwner(user.ID.String())) {
httpapi.ResourceNotFound(rw)
return
}
lifeTime := time.Hour * 24 * 7
cookie, err := api.createAPIKey(ctx, createAPIKeyParams{
UserID: user.ID,
LoginType: database.LoginTypePassword,
RemoteAddr: r.RemoteAddr,
// All api generated keys will last 1 week. Browser login tokens have
// a shorter life.
ExpiresAt: database.Now().Add(lifeTime),
LifetimeSeconds: int64(lifeTime.Seconds()),
})
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "Failed to create API key.",
Detail: err.Error(),
})
return
}
// We intentionally do not set the cookie on the response here.
// Setting the cookie will couple the browser sesion to the API
// key we return here, meaning logging out of the website would
// invalid your CLI key.
httpapi.Write(ctx, rw, http.StatusCreated, codersdk.GenerateAPIKeyResponse{Key: cookie.Value})
}
func (api *API) apiKey(rw http.ResponseWriter, r *http.Request) {
var (
ctx = r.Context()

View File

@ -39,3 +39,15 @@ func TestTokens(t *testing.T) {
require.NoError(t, err)
require.Empty(t, keys)
}
func TestAPIKey(t *testing.T) {
t.Parallel()
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
_ = coderdtest.CreateFirstUser(t, client)
res, err := client.CreateAPIKey(ctx, codersdk.Me)
require.NoError(t, err)
require.Greater(t, len(res.Key), 2)
}

View File

@ -399,6 +399,7 @@ func New(options *Options) *API {
r.Get("/roles", api.userRoles)
r.Route("/keys", func(r chi.Router) {
r.Post("/", api.postAPIKey)
r.Route("/tokens", func(r chi.Router) {
r.Post("/", api.postToken)
r.Get("/", api.tokens)

View File

@ -45,6 +45,20 @@ func (c *Client) CreateToken(ctx context.Context, userID string) (*GenerateAPIKe
return apiKey, json.NewDecoder(res.Body).Decode(apiKey)
}
// CreateAPIKey generates an API key for the user ID provided.
func (c *Client) CreateAPIKey(ctx context.Context, user string) (*GenerateAPIKeyResponse, error) {
res, err := c.Request(ctx, http.MethodPost, fmt.Sprintf("/api/v2/users/%s/keys", user), nil)
if err != nil {
return nil, err
}
defer res.Body.Close()
if res.StatusCode > http.StatusCreated {
return nil, readBodyAsError(res)
}
apiKey := &GenerateAPIKeyResponse{}
return apiKey, json.NewDecoder(res.Body).Decode(apiKey)
}
// GetTokens list machine API keys.
func (c *Client) GetTokens(ctx context.Context, userID string) ([]APIKey, error) {
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/users/%s/keys/tokens", userID), nil)