Skip to content

Commit

Permalink
add tenantsUsersCreateHandler
Browse files Browse the repository at this point in the history
  • Loading branch information
briskt committed Nov 27, 2023
1 parent ec71df7 commit a66c52a
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 13 deletions.
4 changes: 2 additions & 2 deletions app/tenant.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func (tu *TenantUpdateInput) Validate() error {
return nil
}

// TenantUserCreateInput is a set of fields to define a new tenant user for CreateTenantUser()
// TenantUserCreateInput is a set of fields to define a new tenant user for tenantsUsersCreateHandler
type TenantUserCreateInput struct {
Name string
Email string
}
1 change: 1 addition & 0 deletions app/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type UserCreateInput struct {
Email string
AvatarURL string
Role string
TenantID string
}

// Validate returns an error if the struct contains invalid information
Expand Down
10 changes: 7 additions & 3 deletions db/tenant.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,13 @@ func DeleteTenant(ctx echo.Context, id string) error {
return nil
}

// CreateTenantUser permanently deletes a tenant and all child objects
func CreateTenantUser(ctx echo.Context, input app.TenantUserCreateInput) error {
return nil
// CreateTenantUser creates a new user for a tenant
func CreateTenantUser(ctx echo.Context, tenantID string, input app.TenantUserCreateInput) (User, error) {
user, err := CreateUser(ctx, app.UserCreateInput{Email: input.Email, TenantID: tenantID})
if err != nil {
return User{}, err
}
return user, nil
}

// FindTenantByID is a function to fetch a tenant by ID.
Expand Down
4 changes: 4 additions & 0 deletions db/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ func CreateUser(ctx echo.Context, userCreate app.UserCreateInput) (User, error)
Role: userCreate.Role,
}

if userCreate.TenantID != "" {
user.TenantID = &userCreate.TenantID
}

// TODO: remove this when ready
user.Role = app.UserRoleAdmin

Expand Down
6 changes: 5 additions & 1 deletion server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,13 @@ func (s *Server) registerRoutes() {
api.GET("/auth/login", s.authLogin)
api.GET("/auth/callback", s.authCallback)
api.GET("/auth/logout", s.authLogout)

api.POST("/tenants", s.tenantsCreateHandler)
api.GET("/tenants", s.tenantsListHandler)
api.GET("/tenants/:id", s.tenantHandler)
api.GET("/tenants/:id", s.tenantsGetHandler)

api.POST("/tenants/:id/users", s.tenantsUsersCreateHandler)

api.GET("/users", s.usersListHandler)
api.GET("/users/:id", s.userHandler)

Expand Down
25 changes: 24 additions & 1 deletion server/tenant.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func (s *Server) tenantsListHandler(c echo.Context) error {
return c.JSON(http.StatusOK, tenants)
}

func (s *Server) tenantHandler(c echo.Context) error {
func (s *Server) tenantsGetHandler(c echo.Context) error {
user := app.CurrentUser(c)

if user.Role != app.UserRoleAdmin {
Expand All @@ -67,3 +67,26 @@ func (s *Server) tenantHandler(c echo.Context) error {

return c.JSON(http.StatusOK, t)
}

func (s *Server) tenantsUsersCreateHandler(c echo.Context) error {
user := app.CurrentUser(c)
if user.Role != app.UserRoleAdmin {
return echo.NewHTTPError(http.StatusUnauthorized, AuthError{Error: "not an authorized user"})
}

var input app.TenantUserCreateInput
err := (&echo.DefaultBinder{}).BindBody(c, &input)
if err != nil {
return echo.NewHTTPError(http.StatusBadRequest, "bad request")
}

tenantID := c.Param("id")
tenantUser, err := db.CreateTenantUser(c, tenantID, input)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
}

s.Logger.Infof("created tenant user (email %q, id %q)", tenantUser.Email, tenantUser.ID)

return c.JSON(http.StatusOK, tenantUser)
}
39 changes: 33 additions & 6 deletions server/tenant_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func (ts *TestSuite) Test_tenantsCreateHandler() {
// TODO: test error response
}

func (ts *TestSuite) Test_GetTenant() {
func (ts *TestSuite) Test_tenantsGetHandler() {
f := ts.createUserFixture()
token := f.Tokens[0]
tenant := ts.createTenantFixture().Tenants[0]
Expand All @@ -66,7 +66,7 @@ func (ts *TestSuite) Test_GetTenant() {
// TODO: test error response
}

func (ts *TestSuite) Test_GetTenantList() {
func (ts *TestSuite) Test_tenantsListHandler() {
f := ts.createUserFixture()
token := f.Tokens[0]
tenant := ts.createTenantFixture().Tenants[0]
Expand All @@ -83,10 +83,37 @@ func (ts *TestSuite) Test_GetTenantList() {
// Assertions
ts.Equal(http.StatusOK, res.Code, "incorrect http status, body: \n%s", body)

var Tenants []app.Tenant
ts.NoError(json.Unmarshal(body, &Tenants))
ts.Len(Tenants, 1)
ts.Equal(tenant.ID, Tenants[0].ID, "incorrect Tenant ID, body: \n%s", body)
var tenants []app.Tenant
ts.NoError(json.Unmarshal(body, &tenants))
ts.Len(tenants, 1)
ts.Equal(tenant.ID, tenants[0].ID, "incorrect Tenant ID, body: \n%s", body)

// TODO: test error response
}

func (ts *TestSuite) Test_tenantsUsersCreateHandler() {
f := ts.createUserFixture()
token := f.Tokens[0]
tenant := ts.createTenantFixture().Tenants[0]

input := app.TenantUserCreateInput{Email: "[email protected]"}
j, _ := json.Marshal(&input)
req := httptest.NewRequest(http.MethodPost, "/api/tenants/"+tenant.ID+"/users", bytes.NewReader((j)))
req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
req.Header.Set(echo.HeaderAuthorization, "Bearer "+token.PlainText)

res := httptest.NewRecorder()
ts.server.ServeHTTP(res, req)
body, err := io.ReadAll(res.Body)
ts.NoError(err)

// Assertions
ts.Equal(http.StatusOK, res.Code, "incorrect http status, body: \n%s", body)

var user db.User
ts.NoError(json.Unmarshal(body, &user))
ts.Equal(input.Email, user.Email, "incorrect user Email, body: \n%s", body)
ts.Equal(tenant.ID, *user.TenantID, "incorrect user TenantID, body: \n%s", body)

// TODO: test error response
}

0 comments on commit a66c52a

Please sign in to comment.