feat: Add organizations endpoint for users (#50)

* feat: Add organizations endpoint for users

This moves the /user endpoint to /users/me instead. This
will reduce code duplication.

This adds /users/<name>/organizations to list organizations
a user has access to. It doesn't contain the permissions a
user has over the organizations, but that will come in a future
contribution.

* Fix requested changes

* Fix tests

* Fix timeout

* Add test for UserOrgs

* Add test for userparam getting

* Add test for NoUser
This commit is contained in:
Kyle Carberry
2022-01-22 23:58:10 -06:00
committed by GitHub
parent 50d8151995
commit 8be245616a
20 changed files with 597 additions and 244 deletions

View File

@ -3,6 +3,7 @@ package codersdk
import (
"context"
"encoding/json"
"fmt"
"net/http"
"github.com/coder/coder/coderd"
@ -11,8 +12,8 @@ import (
// CreateInitialUser attempts to create the first user on a Coder deployment.
// This initial user has superadmin privileges. If >0 users exist, this request
// will fail.
func (c *Client) CreateInitialUser(ctx context.Context, req coderd.CreateUserRequest) (coderd.User, error) {
res, err := c.request(ctx, http.MethodPost, "/api/v2/user", req)
func (c *Client) CreateInitialUser(ctx context.Context, req coderd.CreateInitialUserRequest) (coderd.User, error) {
res, err := c.request(ctx, http.MethodPost, "/api/v2/users", req)
if err != nil {
return coderd.User{}, err
}
@ -24,21 +25,6 @@ func (c *Client) CreateInitialUser(ctx context.Context, req coderd.CreateUserReq
return user, json.NewDecoder(res.Body).Decode(&user)
}
// User returns a user for the ID provided.
// If the ID string is empty, the current user will be returned.
func (c *Client) User(ctx context.Context, _ string) (coderd.User, error) {
res, err := c.request(ctx, http.MethodGet, "/api/v2/user", nil)
if err != nil {
return coderd.User{}, err
}
defer res.Body.Close()
if res.StatusCode > http.StatusOK {
return coderd.User{}, readBodyAsError(res)
}
var user coderd.User
return user, json.NewDecoder(res.Body).Decode(&user)
}
// LoginWithPassword creates a session token authenticating with an email and password.
// Call `SetSessionToken()` to apply the newly acquired token to the client.
func (c *Client) LoginWithPassword(ctx context.Context, req coderd.LoginWithPasswordRequest) (coderd.LoginWithPasswordResponse, error) {
@ -57,3 +43,38 @@ func (c *Client) LoginWithPassword(ctx context.Context, req coderd.LoginWithPass
}
return resp, nil
}
// User returns a user for the ID provided.
// If the ID string is empty, the current user will be returned.
func (c *Client) User(ctx context.Context, id string) (coderd.User, error) {
if id == "" {
id = "me"
}
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/users/%s", id), nil)
if err != nil {
return coderd.User{}, err
}
defer res.Body.Close()
if res.StatusCode > http.StatusOK {
return coderd.User{}, readBodyAsError(res)
}
var user coderd.User
return user, json.NewDecoder(res.Body).Decode(&user)
}
// UserOrganizations fetches organizations a user is part of.
func (c *Client) UserOrganizations(ctx context.Context, id string) ([]coderd.Organization, error) {
if id == "" {
id = "me"
}
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/users/%s/organizations", id), nil)
if err != nil {
return nil, err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return nil, readBodyAsError(res)
}
var orgs []coderd.Organization
return orgs, json.NewDecoder(res.Body).Decode(&orgs)
}