mirror of
https://github.com/coder/coder.git
synced 2025-07-18 14:17:22 +00:00
feat: Add APIs for querying workspaces (#61)
* Add SQL migration * Add query functions for workspaces * Add create routes * Add tests for codersdk * Add workspace parameter route * Add workspace query * Move workspace function * Add querying for workspace history * Fix query * Fix syntax error * Move workspace routes * Fix version * Add CLI tests * Fix syntax error * Remove error * Fix history error * Add new user test * Fix test * Lower target to 70% * Improve comments * Add comment
This commit is contained in:
@ -19,7 +19,7 @@ import (
|
||||
"github.com/coder/coder/httpmw"
|
||||
)
|
||||
|
||||
// User is the JSON representation of a Coder user.
|
||||
// User represents a user in Coder.
|
||||
type User struct {
|
||||
ID string `json:"id" validate:"required"`
|
||||
Email string `json:"email" validate:"required"`
|
||||
@ -27,7 +27,9 @@ type User struct {
|
||||
Username string `json:"username" validate:"required"`
|
||||
}
|
||||
|
||||
// CreateInitialUserRequest enables callers to create a new user.
|
||||
// CreateInitialUserRequest provides options to create the initial
|
||||
// user for a Coder deployment. The organization provided will be
|
||||
// created as well.
|
||||
type CreateInitialUserRequest struct {
|
||||
Email string `json:"email" validate:"required,email"`
|
||||
Username string `json:"username" validate:"required,username"`
|
||||
@ -35,6 +37,13 @@ type CreateInitialUserRequest struct {
|
||||
Organization string `json:"organization" validate:"required,username"`
|
||||
}
|
||||
|
||||
// CreateUserRequest provides options for creating a new user.
|
||||
type CreateUserRequest struct {
|
||||
Email string `json:"email" validate:"required,email"`
|
||||
Username string `json:"username" validate:"required,username"`
|
||||
Password string `json:"password" validate:"required"`
|
||||
}
|
||||
|
||||
// LoginWithPasswordRequest enables callers to authenticate with email and password.
|
||||
type LoginWithPasswordRequest struct {
|
||||
Email string `json:"email" validate:"required,email"`
|
||||
@ -123,7 +132,58 @@ func (users *users) createInitialUser(rw http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
render.Status(r, http.StatusCreated)
|
||||
render.JSON(rw, r, user)
|
||||
render.JSON(rw, r, convertUser(user))
|
||||
}
|
||||
|
||||
// Creates a new user.
|
||||
func (users *users) createUser(rw http.ResponseWriter, r *http.Request) {
|
||||
var createUser CreateUserRequest
|
||||
if !httpapi.Read(rw, r, &createUser) {
|
||||
return
|
||||
}
|
||||
_, err := users.Database.GetUserByEmailOrUsername(r.Context(), database.GetUserByEmailOrUsernameParams{
|
||||
Username: createUser.Username,
|
||||
Email: createUser.Email,
|
||||
})
|
||||
if err == nil {
|
||||
httpapi.Write(rw, http.StatusConflict, httpapi.Response{
|
||||
Message: "user already exists",
|
||||
})
|
||||
return
|
||||
}
|
||||
if !errors.Is(err, sql.ErrNoRows) {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get user: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
hashedPassword, err := userpassword.Hash(createUser.Password)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("hash password: %s", err.Error()),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
user, err := users.Database.InsertUser(r.Context(), database.InsertUserParams{
|
||||
ID: uuid.NewString(),
|
||||
Email: createUser.Email,
|
||||
HashedPassword: []byte(hashedPassword),
|
||||
Username: createUser.Username,
|
||||
LoginType: database.LoginTypeBuiltIn,
|
||||
CreatedAt: database.Now(),
|
||||
UpdatedAt: database.Now(),
|
||||
})
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("create user: %s", err.Error()),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
render.Status(r, http.StatusCreated)
|
||||
render.JSON(rw, r, convertUser(user))
|
||||
}
|
||||
|
||||
// Returns the parameterized user requested. All validation
|
||||
@ -131,12 +191,7 @@ func (users *users) createInitialUser(rw http.ResponseWriter, r *http.Request) {
|
||||
func (*users) user(rw http.ResponseWriter, r *http.Request) {
|
||||
user := httpmw.UserParam(r)
|
||||
|
||||
render.JSON(rw, r, User{
|
||||
ID: user.ID,
|
||||
Email: user.Email,
|
||||
CreatedAt: user.CreatedAt,
|
||||
Username: user.Username,
|
||||
})
|
||||
render.JSON(rw, r, convertUser(user))
|
||||
}
|
||||
|
||||
// Returns organizations the parameterized user has access to.
|
||||
@ -265,3 +320,12 @@ func generateAPIKeyIDSecret() (id string, secret string, err error) {
|
||||
}
|
||||
return id, secret, nil
|
||||
}
|
||||
|
||||
func convertUser(user database.User) User {
|
||||
return User{
|
||||
ID: user.ID,
|
||||
Email: user.Email,
|
||||
CreatedAt: user.CreatedAt,
|
||||
Username: user.Username,
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user