From b0a0e734e0c46384499cdc1f08f2673b6a28ff98 Mon Sep 17 00:00:00 2001 From: William Baker Date: Mon, 20 Dec 2021 15:17:18 -0500 Subject: [PATCH] chore: remove unused user http code (#23011) * chore: remove unused user http code * fix: resolve circular dep * fix: copy newUserResponse function --- http/middleware.go | 6 +- http/user_resource_mapping_service.go | 12 +- http/user_service.go | 641 -------------------------- http/user_test.go | 94 ---- tenant/http_client_user.go | 6 +- tenant/http_handler_urm.go | 2 +- tenant/http_server_onboarding.go | 8 +- tenant/http_server_user.go | 16 +- user.go | 6 + 9 files changed, 33 insertions(+), 758 deletions(-) delete mode 100644 http/user_service.go delete mode 100644 http/user_test.go diff --git a/http/middleware.go b/http/middleware.go index 941b269ea4..fe87060c34 100644 --- a/http/middleware.go +++ b/http/middleware.go @@ -135,9 +135,9 @@ const ( var blacklistEndpoints = map[string]isValidMethodFn{ "/api/v2/signin": ignoreMethod(), "/api/v2/signout": ignoreMethod(), - prefixMe: ignoreMethod(), - mePasswordPath: ignoreMethod(), - usersPasswordPath: ignoreMethod(), + "/api/v2/me": ignoreMethod(), + "/api/v2/me/password": ignoreMethod(), + "/api/v2/users/:id/password": ignoreMethod(), "/api/v2/packages/apply": ignoreMethod(), prefixWrite: ignoreMethod("POST"), "/write": ignoreMethod("POST"), diff --git a/http/user_resource_mapping_service.go b/http/user_resource_mapping_service.go index 5150a7aba9..e2b478b433 100644 --- a/http/user_resource_mapping_service.go +++ b/http/user_resource_mapping_service.go @@ -17,7 +17,17 @@ import ( type resourceUserResponse struct { Role influxdb.UserType `json:"role"` - *UserResponse + *influxdb.UserResponse +} + +func newUserResponse(u *influxdb.User) *influxdb.UserResponse { + return &influxdb.UserResponse{ + Links: map[string]string{ + "self": fmt.Sprintf("/api/v2/users/%s", u.ID), + "logs": fmt.Sprintf("/api/v2/users/%s/logs", u.ID), + }, + User: *u, + } } func newResourceUserResponse(u *influxdb.User, userType influxdb.UserType) *resourceUserResponse { diff --git a/http/user_service.go b/http/user_service.go deleted file mode 100644 index e285e8e471..0000000000 --- a/http/user_service.go +++ /dev/null @@ -1,641 +0,0 @@ -package http - -import ( - "context" - "encoding/json" - "fmt" - "net/http" - - "github.com/influxdata/httprouter" - "github.com/influxdata/influxdb/v2" - icontext "github.com/influxdata/influxdb/v2/context" - "github.com/influxdata/influxdb/v2/kit/platform" - "github.com/influxdata/influxdb/v2/kit/platform/errors" - "github.com/influxdata/influxdb/v2/pkg/httpc" - "go.uber.org/zap" -) - -// UserBackend is all services and associated parameters required to construct -// the UserHandler. -type UserBackend struct { - errors.HTTPErrorHandler - log *zap.Logger - UserService influxdb.UserService - UserOperationLogService influxdb.UserOperationLogService - PasswordsService influxdb.PasswordsService -} - -// NewUserBackend creates a UserBackend using information in the APIBackend. -func NewUserBackend(log *zap.Logger, b *APIBackend) *UserBackend { - return &UserBackend{ - HTTPErrorHandler: b.HTTPErrorHandler, - log: log, - UserService: b.UserService, - UserOperationLogService: b.UserOperationLogService, - PasswordsService: b.PasswordsService, - } -} - -// UserHandler represents an HTTP API handler for users. -type UserHandler struct { - *httprouter.Router - errors.HTTPErrorHandler - log *zap.Logger - UserService influxdb.UserService - UserOperationLogService influxdb.UserOperationLogService - PasswordsService influxdb.PasswordsService -} - -const ( - prefixUsers = "/api/v2/users" - prefixMe = "/api/v2/me" - mePasswordPath = "/api/v2/me/password" - usersIDPath = "/api/v2/users/:id" - usersPasswordPath = "/api/v2/users/:id/password" -) - -// NewUserHandler returns a new instance of UserHandler. -func NewUserHandler(log *zap.Logger, b *UserBackend) *UserHandler { - h := &UserHandler{ - Router: NewRouter(b.HTTPErrorHandler), - HTTPErrorHandler: b.HTTPErrorHandler, - log: log, - - UserService: b.UserService, - UserOperationLogService: b.UserOperationLogService, - PasswordsService: b.PasswordsService, - } - - h.HandlerFunc("POST", prefixUsers, h.handlePostUser) - h.HandlerFunc("GET", prefixUsers, h.handleGetUsers) - h.HandlerFunc("GET", usersIDPath, h.handleGetUser) - h.HandlerFunc("PATCH", usersIDPath, h.handlePatchUser) - h.HandlerFunc("DELETE", usersIDPath, h.handleDeleteUser) - // the POST doesn't need to be nested under users in this scheme - // seems worthwhile to make this a root resource in our HTTP API - // removes coupling with userid. - h.HandlerFunc("POST", usersPasswordPath, h.handlePostUserPassword) - h.HandlerFunc("PUT", usersPasswordPath, h.handlePutUserPassword) - - h.HandlerFunc("GET", prefixMe, h.handleGetMe) - h.HandlerFunc("PUT", mePasswordPath, h.handlePutUserPassword) - - return h -} - -type passwordSetRequest struct { - Password string `json:"password"` -} - -// handlePutPassword is the HTTP handler for the PUT /api/v2/users/:id/password -func (h *UserHandler) handlePostUserPassword(w http.ResponseWriter, r *http.Request) { - var body passwordSetRequest - err := json.NewDecoder(r.Body).Decode(&body) - if err != nil { - h.HandleHTTPError(r.Context(), &errors.Error{ - Code: errors.EInvalid, - Err: err, - }, w) - return - } - - params := httprouter.ParamsFromContext(r.Context()) - userID, err := platform.IDFromString(params.ByName("id")) - if err != nil { - h.HandleHTTPError(r.Context(), &errors.Error{ - Msg: "invalid user ID provided in route", - }, w) - return - } - - err = h.PasswordsService.SetPassword(r.Context(), *userID, body.Password) - if err != nil { - h.HandleHTTPError(r.Context(), err, w) - return - } - - w.WriteHeader(http.StatusNoContent) -} - -func (h *UserHandler) putPassword(ctx context.Context, w http.ResponseWriter, r *http.Request) (username string, err error) { - req, err := decodePasswordResetRequest(r) - if err != nil { - return "", err - } - - params := httprouter.ParamsFromContext(r.Context()) - userID, err := platform.IDFromString(params.ByName("id")) - if err != nil { - h.HandleHTTPError(r.Context(), &errors.Error{ - Msg: "invalid user ID provided in route", - }, w) - return - } - - err = h.PasswordsService.CompareAndSetPassword(ctx, *userID, req.PasswordOld, req.PasswordNew) - if err != nil { - return "", err - } - return req.Username, nil -} - -// handlePutPassword is the HTTP handler for the PUT /api/v2/users/:id/password -func (h *UserHandler) handlePutUserPassword(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - _, err := h.putPassword(ctx, w, r) - if err != nil { - h.HandleHTTPError(ctx, err, w) - return - } - h.log.Debug("User password updated") - w.WriteHeader(http.StatusNoContent) -} - -type passwordResetRequest struct { - Username string - PasswordOld string - PasswordNew string -} - -type passwordResetRequestBody struct { - Password string `json:"password"` -} - -func decodePasswordResetRequest(r *http.Request) (*passwordResetRequest, error) { - u, o, ok := r.BasicAuth() - if !ok { - return nil, fmt.Errorf("invalid basic auth") - } - - pr := new(passwordResetRequestBody) - err := json.NewDecoder(r.Body).Decode(pr) - if err != nil { - return nil, &errors.Error{ - Code: errors.EInvalid, - Err: err, - } - } - - return &passwordResetRequest{ - Username: u, - PasswordOld: o, - PasswordNew: pr.Password, - }, nil -} - -// handlePostUser is the HTTP handler for the POST /api/v2/users route. -func (h *UserHandler) handlePostUser(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - req, err := decodePostUserRequest(ctx, r) - if err != nil { - h.HandleHTTPError(ctx, err, w) - return - } - - if req.User.Status == "" { - req.User.Status = influxdb.Active - } - - if err := h.UserService.CreateUser(ctx, req.User); err != nil { - h.HandleHTTPError(ctx, err, w) - return - } - h.log.Debug("User created", zap.String("user", fmt.Sprint(req.User))) - - if err := encodeResponse(ctx, w, http.StatusCreated, newUserResponse(req.User)); err != nil { - h.HandleHTTPError(ctx, err, w) - return - } -} - -type postUserRequest struct { - User *influxdb.User -} - -func decodePostUserRequest(ctx context.Context, r *http.Request) (*postUserRequest, error) { - b := &influxdb.User{} - if err := json.NewDecoder(r.Body).Decode(b); err != nil { - return nil, err - } - - return &postUserRequest{ - User: b, - }, nil -} - -// handleGetMe is the HTTP handler for the GET /api/v2/me. -func (h *UserHandler) handleGetMe(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - - a, err := icontext.GetAuthorizer(ctx) - if err != nil { - h.HandleHTTPError(ctx, err, w) - return - } - - id := a.GetUserID() - user, err := h.UserService.FindUserByID(ctx, id) - - if err != nil { - h.HandleHTTPError(ctx, err, w) - return - } - - if err := encodeResponse(ctx, w, http.StatusOK, newUserResponse(user)); err != nil { - h.HandleHTTPError(ctx, err, w) - } -} - -// handleGetUser is the HTTP handler for the GET /api/v2/users/:id route. -func (h *UserHandler) handleGetUser(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - req, err := decodeGetUserRequest(ctx, r) - if err != nil { - h.HandleHTTPError(ctx, err, w) - return - } - - b, err := h.UserService.FindUserByID(ctx, req.UserID) - if err != nil { - h.HandleHTTPError(ctx, err, w) - return - } - h.log.Debug("User retrieved", zap.String("user", fmt.Sprint(b))) - - if err := encodeResponse(ctx, w, http.StatusOK, newUserResponse(b)); err != nil { - h.HandleHTTPError(ctx, err, w) - return - } -} - -type getUserRequest struct { - UserID platform.ID -} - -func decodeGetUserRequest(ctx context.Context, r *http.Request) (*getUserRequest, error) { - params := httprouter.ParamsFromContext(ctx) - id := params.ByName("id") - if id == "" { - return nil, &errors.Error{ - Code: errors.EInvalid, - Msg: "url missing id", - } - } - - var i platform.ID - if err := i.DecodeFromString(id); err != nil { - return nil, err - } - - req := &getUserRequest{ - UserID: i, - } - - return req, nil -} - -// handleDeleteUser is the HTTP handler for the DELETE /api/v2/users/:id route. -func (h *UserHandler) handleDeleteUser(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - req, err := decodeDeleteUserRequest(ctx, r) - if err != nil { - h.HandleHTTPError(ctx, err, w) - return - } - - if err := h.UserService.DeleteUser(ctx, req.UserID); err != nil { - h.HandleHTTPError(ctx, err, w) - return - } - h.log.Debug("User deleted", zap.String("userID", fmt.Sprint(req.UserID))) - - w.WriteHeader(http.StatusNoContent) -} - -type deleteUserRequest struct { - UserID platform.ID -} - -func decodeDeleteUserRequest(ctx context.Context, r *http.Request) (*deleteUserRequest, error) { - params := httprouter.ParamsFromContext(ctx) - id := params.ByName("id") - if id == "" { - return nil, &errors.Error{ - Code: errors.EInvalid, - Msg: "url missing id", - } - } - - var i platform.ID - if err := i.DecodeFromString(id); err != nil { - return nil, err - } - - return &deleteUserRequest{ - UserID: i, - }, nil -} - -type usersResponse struct { - Links map[string]string `json:"links"` - Users []*UserResponse `json:"users"` -} - -func (us usersResponse) ToInfluxdb() []*influxdb.User { - users := make([]*influxdb.User, len(us.Users)) - for i := range us.Users { - users[i] = &us.Users[i].User - } - return users -} - -func newUsersResponse(users []*influxdb.User) *usersResponse { - res := usersResponse{ - Links: map[string]string{ - "self": "/api/v2/users", - }, - Users: []*UserResponse{}, - } - for _, user := range users { - res.Users = append(res.Users, newUserResponse(user)) - } - return &res -} - -// UserResponse is the response of user -type UserResponse struct { - Links map[string]string `json:"links"` - influxdb.User -} - -func newUserResponse(u *influxdb.User) *UserResponse { - return &UserResponse{ - Links: map[string]string{ - "self": fmt.Sprintf("/api/v2/users/%s", u.ID), - "logs": fmt.Sprintf("/api/v2/users/%s/logs", u.ID), - }, - User: *u, - } -} - -// handleGetUsers is the HTTP handler for the GET /api/v2/users route. -func (h *UserHandler) handleGetUsers(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - req, err := decodeGetUsersRequest(ctx, r) - if err != nil { - h.HandleHTTPError(ctx, err, w) - return - } - - users, _, err := h.UserService.FindUsers(ctx, req.filter, req.opts) - if err != nil { - h.HandleHTTPError(ctx, err, w) - return - } - h.log.Debug("Users retrieved", zap.String("users", fmt.Sprint(users))) - - err = encodeResponse(ctx, w, http.StatusOK, newUsersResponse(users)) - if err != nil { - h.HandleHTTPError(ctx, err, w) - return - } -} - -type getUsersRequest struct { - filter influxdb.UserFilter - opts influxdb.FindOptions -} - -func decodeGetUsersRequest(ctx context.Context, r *http.Request) (*getUsersRequest, error) { - opts, err := influxdb.DecodeFindOptions(r) - if err != nil { - return nil, err - } - - qp := r.URL.Query() - req := &getUsersRequest{ - opts: *opts, - } - - if userID := qp.Get("id"); userID != "" { - id, err := platform.IDFromString(userID) - if err != nil { - return nil, err - } - req.filter.ID = id - } - - if name := qp.Get("name"); name != "" { - req.filter.Name = &name - } - - return req, nil -} - -// handlePatchUser is the HTTP handler for the PATCH /api/v2/users/:id route. -func (h *UserHandler) handlePatchUser(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - req, err := decodePatchUserRequest(ctx, r) - if err != nil { - h.HandleHTTPError(ctx, err, w) - return - } - - b, err := h.UserService.UpdateUser(ctx, req.UserID, req.Update) - if err != nil { - h.HandleHTTPError(ctx, err, w) - return - } - h.log.Debug("Users updated", zap.String("user", fmt.Sprint(b))) - - if err := encodeResponse(ctx, w, http.StatusOK, newUserResponse(b)); err != nil { - h.HandleHTTPError(ctx, err, w) - return - } -} - -type patchUserRequest struct { - Update influxdb.UserUpdate - UserID platform.ID -} - -func decodePatchUserRequest(ctx context.Context, r *http.Request) (*patchUserRequest, error) { - params := httprouter.ParamsFromContext(ctx) - id := params.ByName("id") - if id == "" { - return nil, &errors.Error{ - Code: errors.EInvalid, - Msg: "url missing id", - } - } - - var i platform.ID - if err := i.DecodeFromString(id); err != nil { - return nil, err - } - - var upd influxdb.UserUpdate - if err := json.NewDecoder(r.Body).Decode(&upd); err != nil { - return nil, err - } - - if err := upd.Valid(); err != nil { - return nil, err - } - - return &patchUserRequest{ - Update: upd, - UserID: i, - }, nil -} - -// UserService connects to Influx via HTTP using tokens to manage users -type UserService struct { - Client *httpc.Client - // OpPrefix is the ops of not found error. - OpPrefix string -} - -// FindMe returns user information about the owner of the token -func (s *UserService) FindMe(ctx context.Context, id platform.ID) (*influxdb.User, error) { - var res UserResponse - err := s.Client. - Get(prefixMe). - DecodeJSON(&res). - Do(ctx) - if err != nil { - return nil, err - } - return &res.User, nil -} - -// FindUserByID returns a single user by ID. -func (s *UserService) FindUserByID(ctx context.Context, id platform.ID) (*influxdb.User, error) { - var res UserResponse - err := s.Client. - Get(prefixUsers, id.String()). - DecodeJSON(&res). - Do(ctx) - if err != nil { - return nil, err - } - return &res.User, nil -} - -// FindUser returns the first user that matches filter. -func (s *UserService) FindUser(ctx context.Context, filter influxdb.UserFilter) (*influxdb.User, error) { - if filter.ID == nil && filter.Name == nil { - return nil, &errors.Error{ - Code: errors.ENotFound, - Msg: "user not found", - } - } - users, n, err := s.FindUsers(ctx, filter) - if err != nil { - return nil, &errors.Error{ - Op: s.OpPrefix + influxdb.OpFindUser, - Err: err, - } - } - - if n == 0 { - return nil, &errors.Error{ - Code: errors.ENotFound, - Op: s.OpPrefix + influxdb.OpFindUser, - Msg: "no results found", - } - } - - return users[0], nil -} - -// FindUsers returns a list of users that match filter and the total count of matching users. -// Additional options provide pagination & sorting. -func (s *UserService) FindUsers(ctx context.Context, filter influxdb.UserFilter, opt ...influxdb.FindOptions) ([]*influxdb.User, int, error) { - params := influxdb.FindOptionParams(opt...) - if filter.ID != nil { - params = append(params, [2]string{"id", filter.ID.String()}) - } - if filter.Name != nil { - params = append(params, [2]string{"name", *filter.Name}) - } - - var r usersResponse - err := s.Client. - Get(prefixUsers). - QueryParams(params...). - DecodeJSON(&r). - Do(ctx) - if err != nil { - return nil, 0, err - } - - us := r.ToInfluxdb() - return us, len(us), nil -} - -// CreateUser creates a new user and sets u.ID with the new identifier. -func (s *UserService) CreateUser(ctx context.Context, u *influxdb.User) error { - return s.Client. - PostJSON(u, prefixUsers). - DecodeJSON(u). - Do(ctx) -} - -// UpdateUser updates a single user with changeset. -// Returns the new user state after update. -func (s *UserService) UpdateUser(ctx context.Context, id platform.ID, upd influxdb.UserUpdate) (*influxdb.User, error) { - var res UserResponse - err := s.Client. - PatchJSON(upd, prefixUsers, id.String()). - DecodeJSON(&res). - Do(ctx) - if err != nil { - return nil, err - } - return &res.User, nil -} - -// DeleteUser removes a user by ID. -func (s *UserService) DeleteUser(ctx context.Context, id platform.ID) error { - return s.Client. - Delete(prefixUsers, id.String()). - StatusFn(func(resp *http.Response) error { - return CheckErrorStatus(http.StatusNoContent, resp) - }). - Do(ctx) -} - -func (s *UserService) FindPermissionForUser(ctx context.Context, uid platform.ID) (influxdb.PermissionSet, error) { - return nil, &errors.Error{ - Code: errors.EInternal, - Msg: "not implemented", - } -} - -// PasswordService is an http client to speak to the password service. -type PasswordService struct { - Client *httpc.Client -} - -var _ influxdb.PasswordsService = (*PasswordService)(nil) - -// SetPassword sets the user's password. -func (s *PasswordService) SetPassword(ctx context.Context, userID platform.ID, password string) error { - return s.Client. - PostJSON(passwordSetRequest{ - Password: password, - }, prefixUsers, userID.String(), "password"). - Do(ctx) -} - -// ComparePassword compares the user new password with existing. Note: is not implemented. -func (s *PasswordService) ComparePassword(ctx context.Context, userID platform.ID, password string) error { - panic("not implemented") -} - -// CompareAndSetPassword compares the old and new password and submits the new password if possible. -// Note: is not implemented. -func (s *PasswordService) CompareAndSetPassword(ctx context.Context, userID platform.ID, old string, new string) error { - panic("not implemented") -} diff --git a/http/user_test.go b/http/user_test.go deleted file mode 100644 index c8434cc4a2..0000000000 --- a/http/user_test.go +++ /dev/null @@ -1,94 +0,0 @@ -package http - -import ( - "context" - "errors" - "net/http" - "net/http/httptest" - "path" - "testing" - - platform "github.com/influxdata/influxdb/v2" - platform2 "github.com/influxdata/influxdb/v2/kit/platform" - kithttp "github.com/influxdata/influxdb/v2/kit/transport/http" - "github.com/influxdata/influxdb/v2/mock" - "github.com/influxdata/influxdb/v2/pkg/testttp" - "github.com/influxdata/influxdb/v2/tenant" - platformtesting "github.com/influxdata/influxdb/v2/testing" - "go.uber.org/zap/zaptest" -) - -// NewMockUserBackend returns a UserBackend with mock services. -func NewMockUserBackend(t *testing.T) *UserBackend { - return &UserBackend{ - log: zaptest.NewLogger(t), - UserService: mock.NewUserService(), - UserOperationLogService: mock.NewUserOperationLogService(), - PasswordsService: mock.NewPasswordsService(), - HTTPErrorHandler: kithttp.NewErrorHandler(zaptest.NewLogger(t)), - } -} - -func initUserService(f platformtesting.UserFields, t *testing.T) (platform.UserService, string, func()) { - t.Helper() - - store := platformtesting.NewTestInmemStore(t) - tenantStore := tenant.NewStore(store) - tenantStore.IDGen = f.IDGenerator - tenantService := tenant.NewService(tenantStore) - - ctx := context.Background() - for _, u := range f.Users { - if err := tenantService.CreateUser(ctx, u); err != nil { - t.Fatalf("failed to populate users") - } - } - - userBackend := NewMockUserBackend(t) - userBackend.HTTPErrorHandler = kithttp.NewErrorHandler(zaptest.NewLogger(t)) - userBackend.UserService = tenantService - handler := NewUserHandler(zaptest.NewLogger(t), userBackend) - server := httptest.NewServer(handler) - - httpClient, err := NewHTTPClient(server.URL, "", false) - if err != nil { - t.Fatal(err) - } - - client := UserService{ - Client: httpClient, - } - - return &client, "", server.Close -} - -func TestUserService(t *testing.T) { - t.Parallel() - platformtesting.UserService(initUserService, t) -} - -func TestUserHandler_SettingPassword(t *testing.T) { - be := NewMockUserBackend(t) - fakePassSVC := mock.NewPasswordsService() - - userID := platform2.ID(1) - fakePassSVC.SetPasswordFn = func(_ context.Context, id platform2.ID, newPass string) error { - if id != userID { - return errors.New("unexpected id: " + id.String()) - } - if newPass == "" { - return errors.New("no password provided") - } - return nil - } - be.PasswordsService = fakePassSVC - - h := NewUserHandler(zaptest.NewLogger(t), be) - - addr := path.Join("/api/v2/users", userID.String(), "/password") - - testttp. - PostJSON(t, addr, passwordSetRequest{Password: "newpassword"}). - Do(h). - ExpectStatus(http.StatusNoContent) -} diff --git a/tenant/http_client_user.go b/tenant/http_client_user.go index 0fe2bca6b7..2127576a53 100644 --- a/tenant/http_client_user.go +++ b/tenant/http_client_user.go @@ -20,7 +20,7 @@ type UserClientService struct { // FindMe returns user information about the owner of the token func (s *UserClientService) FindMe(ctx context.Context, id platform.ID) (*influxdb.User, error) { - var res UserResponse + var res influxdb.UserResponse err := s.Client. Get(prefixMe). DecodeJSON(&res). @@ -33,7 +33,7 @@ func (s *UserClientService) FindMe(ctx context.Context, id platform.ID) (*influx // FindUserByID returns a single user by ID. func (s *UserClientService) FindUserByID(ctx context.Context, id platform.ID) (*influxdb.User, error) { - var res UserResponse + var res influxdb.UserResponse err := s.Client. Get(prefixUsers, id.String()). DecodeJSON(&res). @@ -107,7 +107,7 @@ func (s *UserClientService) CreateUser(ctx context.Context, u *influxdb.User) er // UpdateUser updates a single user with changeset. // Returns the new user state after update. func (s *UserClientService) UpdateUser(ctx context.Context, id platform.ID, upd influxdb.UserUpdate) (*influxdb.User, error) { - var res UserResponse + var res influxdb.UserResponse err := s.Client. PatchJSON(upd, prefixUsers, id.String()). DecodeJSON(&res). diff --git a/tenant/http_handler_urm.go b/tenant/http_handler_urm.go index d43ff5c82a..aff0cb43dd 100644 --- a/tenant/http_handler_urm.go +++ b/tenant/http_handler_urm.go @@ -233,7 +233,7 @@ func (h *urmHandler) decodeDeleteRequest(ctx context.Context, r *http.Request) ( type resourceUserResponse struct { Role influxdb.UserType `json:"role"` - *UserResponse + *influxdb.UserResponse } func newResourceUserResponse(u *influxdb.User, userType influxdb.UserType) *resourceUserResponse { diff --git a/tenant/http_server_onboarding.go b/tenant/http_server_onboarding.go index ba8db11122..b6dce718d9 100644 --- a/tenant/http_server_onboarding.go +++ b/tenant/http_server_onboarding.go @@ -90,10 +90,10 @@ func (h *OnboardHandler) handleInitialOnboardRequest(w http.ResponseWriter, r *h } type onboardingResponse struct { - User *UserResponse `json:"user"` - Bucket *bucketResponse `json:"bucket"` - Organization orgResponse `json:"org"` - Auth *authResponse `json:"auth"` + User *influxdb.UserResponse `json:"user"` + Bucket *bucketResponse `json:"bucket"` + Organization orgResponse `json:"org"` + Auth *authResponse `json:"auth"` } func NewOnboardingResponse(results *influxdb.OnboardingResults) *onboardingResponse { diff --git a/tenant/http_server_user.go b/tenant/http_server_user.go index 48e279f5d0..5e124f8c8f 100644 --- a/tenant/http_server_user.go +++ b/tenant/http_server_user.go @@ -352,8 +352,8 @@ func decodeDeleteUserRequest(ctx context.Context, r *http.Request) (*deleteUserR } type usersResponse struct { - Links map[string]string `json:"links"` - Users []*UserResponse `json:"users"` + Links map[string]string `json:"links"` + Users []*influxdb.UserResponse `json:"users"` } func (us usersResponse) ToInfluxdb() []*influxdb.User { @@ -369,7 +369,7 @@ func newUsersResponse(users []*influxdb.User) *usersResponse { Links: map[string]string{ "self": "/api/v2/users", }, - Users: []*UserResponse{}, + Users: []*influxdb.UserResponse{}, } for _, user := range users { res.Users = append(res.Users, newUserResponse(user)) @@ -377,14 +377,8 @@ func newUsersResponse(users []*influxdb.User) *usersResponse { return &res } -// UserResponse is the response of user -type UserResponse struct { - Links map[string]string `json:"links"` - influxdb.User -} - -func newUserResponse(u *influxdb.User) *UserResponse { - return &UserResponse{ +func newUserResponse(u *influxdb.User) *influxdb.UserResponse { + return &influxdb.UserResponse{ Links: map[string]string{ "self": fmt.Sprintf("/api/v2/users/%s", u.ID), }, diff --git a/user.go b/user.go index 7c685b50ca..ba7c4d3cf6 100644 --- a/user.go +++ b/user.go @@ -90,3 +90,9 @@ type UserFilter struct { ID *platform.ID Name *string } + +// UserResponse is the response of user +type UserResponse struct { + Links map[string]string `json:"links"` + User +}