From 6e772fb58df6caefeea8bffe0b64dbda692d3977 Mon Sep 17 00:00:00 2001 From: Karan Balani <29383381+balanikaran@users.noreply.github.com> Date: Mon, 16 Mar 2026 20:05:56 +0530 Subject: [PATCH] refactor: add usertypes package and move user related files there for consistency --- ee/modules/dashboard/impldashboard/module.go | 2 +- ee/query-service/app/api/cloudIntegrations.go | 9 +- pkg/apiserver/signozapiserver/provider.go | 2 +- pkg/apiserver/signozapiserver/user.go | 41 ++--- pkg/authn/authnstore/sqlauthnstore/store.go | 14 +- .../passwordauthn/emailpasswordauthn/authn.go | 4 +- pkg/modules/dashboard/dashboard.go | 2 +- pkg/modules/dashboard/impldashboard/module.go | 2 +- pkg/modules/session/implsession/module.go | 5 +- .../tracefunnel/impltracefunnel/module.go | 3 +- pkg/modules/user/config.go | 4 +- pkg/modules/user/impluser/getter.go | 22 +-- pkg/modules/user/impluser/handler.go | 34 ++-- pkg/modules/user/impluser/module.go | 99 ++++++------ pkg/modules/user/impluser/service.go | 13 +- pkg/modules/user/impluser/store.go | 153 +++++++++--------- pkg/modules/user/option.go | 6 +- pkg/modules/user/user.go | 45 +++--- pkg/query-service/app/http_handler.go | 3 +- pkg/sqlmigration/037_add_trace_funnels.go | 14 +- .../analyticsstatsreporter/provider.go | 4 +- pkg/tokenizer/jwttokenizer/claims.go | 8 +- .../tokenizerstore/sqltokenizerstore/store.go | 7 +- pkg/types/authtypes/authn.go | 15 +- pkg/types/authtypes/claims.go | 6 +- pkg/types/authtypes/mapping.go | 6 +- pkg/types/dashboardtypes/dashboard.go | 4 +- pkg/types/role.go | 16 +- pkg/types/roletypes/role.go | 4 +- pkg/types/tracefunneltypes/tracefunnel.go | 13 +- pkg/types/tracefunneltypes/utils_test.go | 3 +- pkg/types/{ => usertypes}/factor_api_key.go | 65 ++++---- pkg/types/{ => usertypes}/factor_password.go | 15 +- .../{ => usertypes}/factor_password_test.go | 2 +- pkg/types/{ => usertypes}/invite.go | 31 ++-- pkg/types/{ => usertypes}/user.go | 39 ++--- 36 files changed, 367 insertions(+), 348 deletions(-) rename pkg/types/{ => usertypes}/factor_api_key.go (63%) rename pkg/types/{ => usertypes}/factor_password.go (96%) rename pkg/types/{ => usertypes}/factor_password_test.go (93%) rename pkg/types/{ => usertypes}/invite.go (75%) rename pkg/types/{ => usertypes}/user.go (89%) diff --git a/ee/modules/dashboard/impldashboard/module.go b/ee/modules/dashboard/impldashboard/module.go index 06a5759a44..a0969553f5 100644 --- a/ee/modules/dashboard/impldashboard/module.go +++ b/ee/modules/dashboard/impldashboard/module.go @@ -214,7 +214,7 @@ func (module *module) Update(ctx context.Context, orgID valuer.UUID, id valuer.U return module.pkgDashboardModule.Update(ctx, orgID, id, updatedBy, data, diff) } -func (module *module) LockUnlock(ctx context.Context, orgID valuer.UUID, id valuer.UUID, updatedBy string, role types.Role, lock bool) error { +func (module *module) LockUnlock(ctx context.Context, orgID valuer.UUID, id valuer.UUID, updatedBy string, role types.LegacyRole, lock bool) error { return module.pkgDashboardModule.LockUnlock(ctx, orgID, id, updatedBy, role, lock) } diff --git a/ee/query-service/app/api/cloudIntegrations.go b/ee/query-service/app/api/cloudIntegrations.go index d773841d76..0a4e1c0382 100644 --- a/ee/query-service/app/api/cloudIntegrations.go +++ b/ee/query-service/app/api/cloudIntegrations.go @@ -16,6 +16,7 @@ import ( basemodel "github.com/SigNoz/signoz/pkg/query-service/model" "github.com/SigNoz/signoz/pkg/types" "github.com/SigNoz/signoz/pkg/types/authtypes" + "github.com/SigNoz/signoz/pkg/types/usertypes" "github.com/SigNoz/signoz/pkg/valuer" "github.com/gorilla/mux" "log/slog" @@ -142,7 +143,7 @@ func (ah *APIHandler) getOrCreateCloudIntegrationPAT(ctx context.Context, orgId "cloud_provider", cloudProvider, ) - newPAT, err := types.NewStorableAPIKey( + newPAT, err := usertypes.NewStorableAPIKey( integrationPATName, integrationUser.ID, types.RoleViewer, @@ -165,16 +166,16 @@ func (ah *APIHandler) getOrCreateCloudIntegrationPAT(ctx context.Context, orgId func (ah *APIHandler) getOrCreateCloudIntegrationUser( ctx context.Context, orgId string, cloudProvider string, -) (*types.User, *basemodel.ApiError) { +) (*usertypes.User, *basemodel.ApiError) { cloudIntegrationUserName := fmt.Sprintf("%s-integration", cloudProvider) email := valuer.MustNewEmail(fmt.Sprintf("%s@signoz.io", cloudIntegrationUserName)) - cloudIntegrationUser, err := types.NewUser(cloudIntegrationUserName, email, types.RoleViewer, valuer.MustNewUUID(orgId), types.UserStatusActive) + cloudIntegrationUser, err := usertypes.NewUser(cloudIntegrationUserName, email, types.RoleViewer, valuer.MustNewUUID(orgId), usertypes.UserStatusActive) if err != nil { return nil, basemodel.InternalError(fmt.Errorf("couldn't create cloud integration user: %w", err)) } - password := types.MustGenerateFactorPassword(cloudIntegrationUser.ID.StringValue()) + password := usertypes.MustGenerateFactorPassword(cloudIntegrationUser.ID.StringValue()) cloudIntegrationUser, err = ah.Signoz.Modules.User.GetOrCreateUser(ctx, cloudIntegrationUser, user.WithFactorPassword(password)) if err != nil { diff --git a/pkg/apiserver/signozapiserver/provider.go b/pkg/apiserver/signozapiserver/provider.go index da6229e425..260443a9a6 100644 --- a/pkg/apiserver/signozapiserver/provider.go +++ b/pkg/apiserver/signozapiserver/provider.go @@ -236,7 +236,7 @@ func (provider *provider) AddToRouter(router *mux.Router) error { return nil } -func newSecuritySchemes(role types.Role) []handler.OpenAPISecurityScheme { +func newSecuritySchemes(role types.LegacyRole) []handler.OpenAPISecurityScheme { return []handler.OpenAPISecurityScheme{ {Name: authtypes.IdentNProviderAPIkey.StringValue(), Scopes: []string{role.String()}}, {Name: authtypes.IdentNProviderTokenizer.StringValue(), Scopes: []string{role.String()}}, diff --git a/pkg/apiserver/signozapiserver/user.go b/pkg/apiserver/signozapiserver/user.go index f533fa16ff..ec540ec866 100644 --- a/pkg/apiserver/signozapiserver/user.go +++ b/pkg/apiserver/signozapiserver/user.go @@ -6,6 +6,7 @@ import ( "github.com/SigNoz/signoz/pkg/http/handler" "github.com/SigNoz/signoz/pkg/types" "github.com/SigNoz/signoz/pkg/types/authtypes" + "github.com/SigNoz/signoz/pkg/types/usertypes" "github.com/gorilla/mux" ) @@ -15,9 +16,9 @@ func (provider *provider) addUserRoutes(router *mux.Router) error { Tags: []string{"users"}, Summary: "Create invite", Description: "This endpoint creates an invite for a user", - Request: new(types.PostableInvite), + Request: new(usertypes.PostableInvite), RequestContentType: "application/json", - Response: new(types.Invite), + Response: new(usertypes.Invite), ResponseContentType: "application/json", SuccessStatusCode: http.StatusCreated, ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusConflict}, @@ -32,7 +33,7 @@ func (provider *provider) addUserRoutes(router *mux.Router) error { Tags: []string{"users"}, Summary: "Create bulk invite", Description: "This endpoint creates a bulk invite for a user", - Request: new(types.PostableBulkInviteRequest), + Request: new(usertypes.PostableBulkInviteRequest), RequestContentType: "application/json", Response: nil, SuccessStatusCode: http.StatusCreated, @@ -50,7 +51,7 @@ func (provider *provider) addUserRoutes(router *mux.Router) error { Description: "This endpoint gets an invite by token", Request: nil, RequestContentType: "", - Response: new(types.Invite), + Response: new(usertypes.Invite), ResponseContentType: "application/json", SuccessStatusCode: http.StatusOK, ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusNotFound}, @@ -84,7 +85,7 @@ func (provider *provider) addUserRoutes(router *mux.Router) error { Description: "This endpoint lists all invites", Request: nil, RequestContentType: "", - Response: make([]*types.Invite, 0), + Response: make([]*usertypes.Invite, 0), ResponseContentType: "application/json", SuccessStatusCode: http.StatusOK, ErrorStatusCodes: []int{}, @@ -99,9 +100,9 @@ func (provider *provider) addUserRoutes(router *mux.Router) error { Tags: []string{"users"}, Summary: "Accept invite", Description: "This endpoint accepts an invite by token", - Request: new(types.PostableAcceptInvite), + Request: new(usertypes.PostableAcceptInvite), RequestContentType: "application/json", - Response: new(types.User), + Response: new(usertypes.User), ResponseContentType: "application/json", SuccessStatusCode: http.StatusCreated, ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusNotFound}, @@ -116,9 +117,9 @@ func (provider *provider) addUserRoutes(router *mux.Router) error { Tags: []string{"users"}, Summary: "Create api key", Description: "This endpoint creates an api key", - Request: new(types.PostableAPIKey), + Request: new(usertypes.PostableAPIKey), RequestContentType: "application/json", - Response: new(types.GettableAPIKey), + Response: new(usertypes.GettableAPIKey), ResponseContentType: "application/json", SuccessStatusCode: http.StatusCreated, ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusConflict}, @@ -135,7 +136,7 @@ func (provider *provider) addUserRoutes(router *mux.Router) error { Description: "This endpoint lists all api keys", Request: nil, RequestContentType: "", - Response: make([]*types.GettableAPIKey, 0), + Response: make([]*usertypes.GettableAPIKey, 0), ResponseContentType: "application/json", SuccessStatusCode: http.StatusOK, ErrorStatusCodes: []int{}, @@ -150,7 +151,7 @@ func (provider *provider) addUserRoutes(router *mux.Router) error { Tags: []string{"users"}, Summary: "Update api key", Description: "This endpoint updates an api key", - Request: new(types.StorableAPIKey), + Request: new(usertypes.StorableAPIKey), RequestContentType: "application/json", Response: nil, ResponseContentType: "application/json", @@ -186,7 +187,7 @@ func (provider *provider) addUserRoutes(router *mux.Router) error { Description: "This endpoint lists all users", Request: nil, RequestContentType: "", - Response: make([]*types.GettableUser, 0), + Response: make([]*usertypes.GettableUser, 0), ResponseContentType: "application/json", SuccessStatusCode: http.StatusOK, ErrorStatusCodes: []int{}, @@ -203,7 +204,7 @@ func (provider *provider) addUserRoutes(router *mux.Router) error { Description: "This endpoint returns the user I belong to", Request: nil, RequestContentType: "", - Response: new(types.GettableUser), + Response: new(usertypes.GettableUser), ResponseContentType: "application/json", SuccessStatusCode: http.StatusOK, ErrorStatusCodes: []int{}, @@ -220,7 +221,7 @@ func (provider *provider) addUserRoutes(router *mux.Router) error { Description: "This endpoint returns the user by id", Request: nil, RequestContentType: "", - Response: new(types.GettableUser), + Response: new(usertypes.GettableUser), ResponseContentType: "application/json", SuccessStatusCode: http.StatusOK, ErrorStatusCodes: []int{http.StatusNotFound}, @@ -235,9 +236,9 @@ func (provider *provider) addUserRoutes(router *mux.Router) error { Tags: []string{"users"}, Summary: "Update user", Description: "This endpoint updates the user by id", - Request: new(types.User), + Request: new(usertypes.User), RequestContentType: "application/json", - Response: new(types.GettableUser), + Response: new(usertypes.GettableUser), ResponseContentType: "application/json", SuccessStatusCode: http.StatusOK, ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusNotFound}, @@ -271,7 +272,7 @@ func (provider *provider) addUserRoutes(router *mux.Router) error { Description: "This endpoint returns the reset password token by id", Request: nil, RequestContentType: "", - Response: new(types.ResetPasswordToken), + Response: new(usertypes.ResetPasswordToken), ResponseContentType: "application/json", SuccessStatusCode: http.StatusOK, ErrorStatusCodes: []int{http.StatusBadRequest, http.StatusNotFound}, @@ -286,7 +287,7 @@ func (provider *provider) addUserRoutes(router *mux.Router) error { Tags: []string{"users"}, Summary: "Reset password", Description: "This endpoint resets the password by token", - Request: new(types.PostableResetPassword), + Request: new(usertypes.PostableResetPassword), RequestContentType: "application/json", Response: nil, ResponseContentType: "", @@ -303,7 +304,7 @@ func (provider *provider) addUserRoutes(router *mux.Router) error { Tags: []string{"users"}, Summary: "Change password", Description: "This endpoint changes the password by id", - Request: new(types.ChangePasswordRequest), + Request: new(usertypes.ChangePasswordRequest), RequestContentType: "application/json", Response: nil, ResponseContentType: "", @@ -320,7 +321,7 @@ func (provider *provider) addUserRoutes(router *mux.Router) error { Tags: []string{"users"}, Summary: "Forgot password", Description: "This endpoint initiates the forgot password flow by sending a reset password email", - Request: new(types.PostableForgotPassword), + Request: new(usertypes.PostableForgotPassword), RequestContentType: "application/json", Response: nil, ResponseContentType: "", diff --git a/pkg/authn/authnstore/sqlauthnstore/store.go b/pkg/authn/authnstore/sqlauthnstore/store.go index 975e61c1ef..f201bce0f3 100644 --- a/pkg/authn/authnstore/sqlauthnstore/store.go +++ b/pkg/authn/authnstore/sqlauthnstore/store.go @@ -4,8 +4,8 @@ import ( "context" "github.com/SigNoz/signoz/pkg/sqlstore" - "github.com/SigNoz/signoz/pkg/types" "github.com/SigNoz/signoz/pkg/types/authtypes" + "github.com/SigNoz/signoz/pkg/types/usertypes" "github.com/SigNoz/signoz/pkg/valuer" ) @@ -17,9 +17,9 @@ func NewStore(sqlstore sqlstore.SQLStore) authtypes.AuthNStore { return &store{sqlstore: sqlstore} } -func (store *store) GetActiveUserAndFactorPasswordByEmailAndOrgID(ctx context.Context, email string, orgID valuer.UUID) (*types.User, *types.FactorPassword, error) { - user := new(types.User) - factorPassword := new(types.FactorPassword) +func (store *store) GetActiveUserAndFactorPasswordByEmailAndOrgID(ctx context.Context, email string, orgID valuer.UUID) (*usertypes.User, *usertypes.FactorPassword, error) { + user := new(usertypes.User) + factorPassword := new(usertypes.FactorPassword) err := store. sqlstore. @@ -28,10 +28,10 @@ func (store *store) GetActiveUserAndFactorPasswordByEmailAndOrgID(ctx context.Co Model(user). Where("email = ?", email). Where("org_id = ?", orgID). - Where("status = ?", types.UserStatusActive.StringValue()). + Where("status = ?", usertypes.UserStatusActive.StringValue()). Scan(ctx) if err != nil { - return nil, nil, store.sqlstore.WrapNotFoundErrf(err, types.ErrCodeUserNotFound, "user with email %s in org %s not found", email, orgID) + return nil, nil, store.sqlstore.WrapNotFoundErrf(err, usertypes.ErrCodeUserNotFound, "user with email %s in org %s not found", email, orgID) } err = store. @@ -42,7 +42,7 @@ func (store *store) GetActiveUserAndFactorPasswordByEmailAndOrgID(ctx context.Co Where("user_id = ?", user.ID). Scan(ctx) if err != nil { - return nil, nil, store.sqlstore.WrapNotFoundErrf(err, types.ErrCodePasswordNotFound, "user with email %s in org %s does not have password", email, orgID) + return nil, nil, store.sqlstore.WrapNotFoundErrf(err, usertypes.ErrCodePasswordNotFound, "user with email %s in org %s does not have password", email, orgID) } return user, factorPassword, nil diff --git a/pkg/authn/passwordauthn/emailpasswordauthn/authn.go b/pkg/authn/passwordauthn/emailpasswordauthn/authn.go index 1f0df7876c..ca4850beec 100644 --- a/pkg/authn/passwordauthn/emailpasswordauthn/authn.go +++ b/pkg/authn/passwordauthn/emailpasswordauthn/authn.go @@ -5,8 +5,8 @@ import ( "github.com/SigNoz/signoz/pkg/authn" "github.com/SigNoz/signoz/pkg/errors" - "github.com/SigNoz/signoz/pkg/types" "github.com/SigNoz/signoz/pkg/types/authtypes" + "github.com/SigNoz/signoz/pkg/types/usertypes" "github.com/SigNoz/signoz/pkg/valuer" ) @@ -27,7 +27,7 @@ func (a *AuthN) Authenticate(ctx context.Context, email string, password string, } if !factorPassword.Equals(password) { - return nil, errors.New(errors.TypeUnauthenticated, types.ErrCodeIncorrectPassword, "invalid email or password") + return nil, errors.New(errors.TypeUnauthenticated, usertypes.ErrCodeIncorrectPassword, "invalid email or password") } return authtypes.NewIdentity(user.ID, orgID, user.Email, user.Role, authtypes.IdentNProviderTokenizer), nil diff --git a/pkg/modules/dashboard/dashboard.go b/pkg/modules/dashboard/dashboard.go index 78ef10d970..58bde6f8ca 100644 --- a/pkg/modules/dashboard/dashboard.go +++ b/pkg/modules/dashboard/dashboard.go @@ -43,7 +43,7 @@ type Module interface { Update(ctx context.Context, orgID valuer.UUID, id valuer.UUID, updatedBy string, data dashboardtypes.UpdatableDashboard, diff int) (*dashboardtypes.Dashboard, error) - LockUnlock(ctx context.Context, orgID valuer.UUID, id valuer.UUID, updatedBy string, role types.Role, lock bool) error + LockUnlock(ctx context.Context, orgID valuer.UUID, id valuer.UUID, updatedBy string, role types.LegacyRole, lock bool) error Delete(ctx context.Context, orgID valuer.UUID, id valuer.UUID) error diff --git a/pkg/modules/dashboard/impldashboard/module.go b/pkg/modules/dashboard/impldashboard/module.go index b393570c30..fe081ec8b3 100644 --- a/pkg/modules/dashboard/impldashboard/module.go +++ b/pkg/modules/dashboard/impldashboard/module.go @@ -99,7 +99,7 @@ func (module *module) Update(ctx context.Context, orgID valuer.UUID, id valuer.U return dashboard, nil } -func (module *module) LockUnlock(ctx context.Context, orgID valuer.UUID, id valuer.UUID, updatedBy string, role types.Role, lock bool) error { +func (module *module) LockUnlock(ctx context.Context, orgID valuer.UUID, id valuer.UUID, updatedBy string, role types.LegacyRole, lock bool) error { dashboard, err := module.Get(ctx, orgID, id) if err != nil { return err diff --git a/pkg/modules/session/implsession/module.go b/pkg/modules/session/implsession/module.go index 9dabcf7f00..b420cb50ad 100644 --- a/pkg/modules/session/implsession/module.go +++ b/pkg/modules/session/implsession/module.go @@ -17,6 +17,7 @@ import ( "github.com/SigNoz/signoz/pkg/tokenizer" "github.com/SigNoz/signoz/pkg/types" "github.com/SigNoz/signoz/pkg/types/authtypes" + "github.com/SigNoz/signoz/pkg/types/usertypes" "github.com/SigNoz/signoz/pkg/valuer" ) @@ -66,7 +67,7 @@ func (module *module) GetSessionContext(ctx context.Context, email valuer.Email, } // filter out deleted users - users = slices.DeleteFunc(users, func(user *types.User) bool { return user.ErrIfDeleted() != nil }) + users = slices.DeleteFunc(users, func(user *usertypes.User) bool { return user.ErrIfDeleted() != nil }) // Since email is a valuer, we can be sure that it is a valid email and we can split it to get the domain name. name := strings.Split(email.String(), "@")[1] @@ -144,7 +145,7 @@ func (module *module) CreateCallbackAuthNSession(ctx context.Context, authNProvi roleMapping := authDomain.AuthDomainConfig().RoleMapping role := roleMapping.NewRoleFromCallbackIdentity(callbackIdentity) - user, err := types.NewUser(callbackIdentity.Name, callbackIdentity.Email, role, callbackIdentity.OrgID, types.UserStatusActive) + user, err := usertypes.NewUser(callbackIdentity.Name, callbackIdentity.Email, role, callbackIdentity.OrgID, usertypes.UserStatusActive) if err != nil { return "", err } diff --git a/pkg/modules/tracefunnel/impltracefunnel/module.go b/pkg/modules/tracefunnel/impltracefunnel/module.go index dfb3bd4b6d..3075be1ace 100644 --- a/pkg/modules/tracefunnel/impltracefunnel/module.go +++ b/pkg/modules/tracefunnel/impltracefunnel/module.go @@ -8,6 +8,7 @@ import ( "github.com/SigNoz/signoz/pkg/modules/tracefunnel" "github.com/SigNoz/signoz/pkg/types" traceFunnels "github.com/SigNoz/signoz/pkg/types/tracefunneltypes" + "github.com/SigNoz/signoz/pkg/types/usertypes" "github.com/SigNoz/signoz/pkg/valuer" ) @@ -30,7 +31,7 @@ func (module *module) Create(ctx context.Context, timestamp int64, name string, funnel.CreatedBy = userID.String() // Set up the user relationship - funnel.CreatedByUser = &types.User{ + funnel.CreatedByUser = &usertypes.User{ Identifiable: types.Identifiable{ ID: userID, }, diff --git a/pkg/modules/user/config.go b/pkg/modules/user/config.go index 487ae5e687..4188fb51e1 100644 --- a/pkg/modules/user/config.go +++ b/pkg/modules/user/config.go @@ -5,7 +5,7 @@ import ( "github.com/SigNoz/signoz/pkg/errors" "github.com/SigNoz/signoz/pkg/factory" - "github.com/SigNoz/signoz/pkg/types" + "github.com/SigNoz/signoz/pkg/types/usertypes" "github.com/SigNoz/signoz/pkg/valuer" ) @@ -68,7 +68,7 @@ func (c Config) Validate() error { if c.Root.Password == "" { return errors.New(errors.TypeInvalidInput, errors.CodeInvalidInput, "user::root::password is required when root user is enabled") } - if !types.IsPasswordValid(c.Root.Password) { + if !usertypes.IsPasswordValid(c.Root.Password) { return errors.New(errors.TypeInvalidInput, errors.CodeInvalidInput, "user::root::password does not meet password requirements") } } diff --git a/pkg/modules/user/impluser/getter.go b/pkg/modules/user/impluser/getter.go index 807cbea33e..aa577a4b92 100644 --- a/pkg/modules/user/impluser/getter.go +++ b/pkg/modules/user/impluser/getter.go @@ -6,25 +6,25 @@ import ( "github.com/SigNoz/signoz/pkg/flagger" "github.com/SigNoz/signoz/pkg/modules/user" - "github.com/SigNoz/signoz/pkg/types" "github.com/SigNoz/signoz/pkg/types/featuretypes" + "github.com/SigNoz/signoz/pkg/types/usertypes" "github.com/SigNoz/signoz/pkg/valuer" ) type getter struct { - store types.UserStore + store usertypes.UserStore flagger flagger.Flagger } -func NewGetter(store types.UserStore, flagger flagger.Flagger) user.Getter { +func NewGetter(store usertypes.UserStore, flagger flagger.Flagger) user.Getter { return &getter{store: store, flagger: flagger} } -func (module *getter) GetRootUserByOrgID(ctx context.Context, orgID valuer.UUID) (*types.User, error) { +func (module *getter) GetRootUserByOrgID(ctx context.Context, orgID valuer.UUID) (*usertypes.User, error) { return module.store.GetRootUserByOrgID(ctx, orgID) } -func (module *getter) ListByOrgID(ctx context.Context, orgID valuer.UUID) ([]*types.User, error) { +func (module *getter) ListByOrgID(ctx context.Context, orgID valuer.UUID) ([]*usertypes.User, error) { users, err := module.store.ListUsersByOrgID(ctx, orgID) if err != nil { return nil, err @@ -35,13 +35,13 @@ func (module *getter) ListByOrgID(ctx context.Context, orgID valuer.UUID) ([]*ty hideRootUsers := module.flagger.BooleanOrEmpty(ctx, flagger.FeatureHideRootUser, evalCtx) if hideRootUsers { - users = slices.DeleteFunc(users, func(user *types.User) bool { return user.IsRoot }) + users = slices.DeleteFunc(users, func(user *usertypes.User) bool { return user.IsRoot }) } return users, nil } -func (module *getter) GetUsersByEmail(ctx context.Context, email valuer.Email) ([]*types.User, error) { +func (module *getter) GetUsersByEmail(ctx context.Context, email valuer.Email) ([]*usertypes.User, error) { users, err := module.store.GetUsersByEmail(ctx, email) if err != nil { return nil, err @@ -50,7 +50,7 @@ func (module *getter) GetUsersByEmail(ctx context.Context, email valuer.Email) ( return users, nil } -func (module *getter) GetByOrgIDAndID(ctx context.Context, orgID valuer.UUID, id valuer.UUID) (*types.User, error) { +func (module *getter) GetByOrgIDAndID(ctx context.Context, orgID valuer.UUID, id valuer.UUID) (*usertypes.User, error) { user, err := module.store.GetByOrgIDAndID(ctx, orgID, id) if err != nil { return nil, err @@ -59,7 +59,7 @@ func (module *getter) GetByOrgIDAndID(ctx context.Context, orgID valuer.UUID, id return user, nil } -func (module *getter) Get(ctx context.Context, id valuer.UUID) (*types.User, error) { +func (module *getter) Get(ctx context.Context, id valuer.UUID) (*usertypes.User, error) { user, err := module.store.GetUser(ctx, id) if err != nil { return nil, err @@ -68,7 +68,7 @@ func (module *getter) Get(ctx context.Context, id valuer.UUID) (*types.User, err return user, nil } -func (module *getter) ListUsersByEmailAndOrgIDs(ctx context.Context, email valuer.Email, orgIDs []valuer.UUID) ([]*types.User, error) { +func (module *getter) ListUsersByEmailAndOrgIDs(ctx context.Context, email valuer.Email, orgIDs []valuer.UUID) ([]*usertypes.User, error) { users, err := module.store.ListUsersByEmailAndOrgIDs(ctx, email, orgIDs) if err != nil { return nil, err @@ -95,7 +95,7 @@ func (module *getter) CountByOrgIDAndStatuses(ctx context.Context, orgID valuer. return counts, nil } -func (module *getter) GetFactorPasswordByUserID(ctx context.Context, userID valuer.UUID) (*types.FactorPassword, error) { +func (module *getter) GetFactorPasswordByUserID(ctx context.Context, userID valuer.UUID) (*usertypes.FactorPassword, error) { factorPassword, err := module.store.GetPasswordByUserID(ctx, userID) if err != nil { return nil, err diff --git a/pkg/modules/user/impluser/handler.go b/pkg/modules/user/impluser/handler.go index 17b4bff20c..ed4d8017f7 100644 --- a/pkg/modules/user/impluser/handler.go +++ b/pkg/modules/user/impluser/handler.go @@ -11,9 +11,9 @@ import ( "github.com/SigNoz/signoz/pkg/http/binding" "github.com/SigNoz/signoz/pkg/http/render" root "github.com/SigNoz/signoz/pkg/modules/user" - "github.com/SigNoz/signoz/pkg/types" "github.com/SigNoz/signoz/pkg/types/authtypes" "github.com/SigNoz/signoz/pkg/types/integrationtypes" + "github.com/SigNoz/signoz/pkg/types/usertypes" "github.com/SigNoz/signoz/pkg/valuer" "github.com/gorilla/mux" ) @@ -31,7 +31,7 @@ func (h *handler) AcceptInvite(w http.ResponseWriter, r *http.Request) { ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second) defer cancel() - req := new(types.PostableAcceptInvite) + req := new(usertypes.PostableAcceptInvite) if err := binding.JSON.BindBody(r.Body, req); err != nil { render.Error(w, err) return @@ -56,14 +56,14 @@ func (h *handler) CreateInvite(rw http.ResponseWriter, r *http.Request) { return } - var req types.PostableInvite + var req usertypes.PostableInvite if err := json.NewDecoder(r.Body).Decode(&req); err != nil { render.Error(rw, err) return } - invites, err := h.module.CreateBulkInvite(ctx, valuer.MustNewUUID(claims.OrgID), valuer.MustNewUUID(claims.UserID), &types.PostableBulkInviteRequest{ - Invites: []types.PostableInvite{req}, + invites, err := h.module.CreateBulkInvite(ctx, valuer.MustNewUUID(claims.OrgID), valuer.MustNewUUID(claims.UserID), &usertypes.PostableBulkInviteRequest{ + Invites: []usertypes.PostableInvite{req}, }) if err != nil { render.Error(rw, err) @@ -83,7 +83,7 @@ func (h *handler) CreateBulkInvite(rw http.ResponseWriter, r *http.Request) { return } - var req types.PostableBulkInviteRequest + var req usertypes.PostableBulkInviteRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { render.Error(rw, err) return @@ -214,7 +214,7 @@ func (h *handler) ListUsers(w http.ResponseWriter, r *http.Request) { } // temp code - show only active users - users = slices.DeleteFunc(users, func(user *types.User) bool { return user.Status != types.UserStatusActive }) + users = slices.DeleteFunc(users, func(user *usertypes.User) bool { return user.Status != usertypes.UserStatusActive }) render.Success(w, http.StatusOK, users) } @@ -231,7 +231,7 @@ func (h *handler) UpdateUser(w http.ResponseWriter, r *http.Request) { return } - var user types.User + var user usertypes.User if err := json.NewDecoder(r.Body).Decode(&user); err != nil { render.Error(w, err) return @@ -297,7 +297,7 @@ func (handler *handler) ResetPassword(w http.ResponseWriter, r *http.Request) { ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second) defer cancel() - req := new(types.PostableResetPassword) + req := new(usertypes.PostableResetPassword) if err := json.NewDecoder(r.Body).Decode(req); err != nil { render.Error(w, err) return @@ -316,7 +316,7 @@ func (handler *handler) ChangePassword(w http.ResponseWriter, r *http.Request) { ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second) defer cancel() - var req types.ChangePasswordRequest + var req usertypes.ChangePasswordRequest if err := json.NewDecoder(r.Body).Decode(&req); err != nil { render.Error(w, err) return @@ -335,7 +335,7 @@ func (h *handler) ForgotPassword(w http.ResponseWriter, r *http.Request) { ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second) defer cancel() - req := new(types.PostableForgotPassword) + req := new(usertypes.PostableForgotPassword) if err := binding.JSON.BindBody(r.Body, req); err != nil { render.Error(w, err) return @@ -360,13 +360,13 @@ func (h *handler) CreateAPIKey(w http.ResponseWriter, r *http.Request) { return } - req := new(types.PostableAPIKey) + req := new(usertypes.PostableAPIKey) if err := json.NewDecoder(r.Body).Decode(req); err != nil { render.Error(w, errors.Wrapf(err, errors.TypeInvalidInput, errors.CodeInvalidInput, "failed to decode api key")) return } - apiKey, err := types.NewStorableAPIKey( + apiKey, err := usertypes.NewStorableAPIKey( req.Name, valuer.MustNewUUID(claims.UserID), req.Role, @@ -411,13 +411,13 @@ func (h *handler) ListAPIKeys(w http.ResponseWriter, r *http.Request) { // for backward compatibility if len(apiKeys) == 0 { - render.Success(w, http.StatusOK, []types.GettableAPIKey{}) + render.Success(w, http.StatusOK, []usertypes.GettableAPIKey{}) return } - result := make([]*types.GettableAPIKey, len(apiKeys)) + result := make([]*usertypes.GettableAPIKey, len(apiKeys)) for i, apiKey := range apiKeys { - result[i] = types.NewGettableAPIKeyFromStorableAPIKey(apiKey) + result[i] = usertypes.NewGettableAPIKeyFromStorableAPIKey(apiKey) } render.Success(w, http.StatusOK, result) @@ -434,7 +434,7 @@ func (h *handler) UpdateAPIKey(w http.ResponseWriter, r *http.Request) { return } - req := types.StorableAPIKey{} + req := usertypes.StorableAPIKey{} if err := json.NewDecoder(r.Body).Decode(&req); err != nil { render.Error(w, errors.Wrapf(err, errors.TypeInvalidInput, errors.CodeInvalidInput, "failed to decode api key")) return diff --git a/pkg/modules/user/impluser/module.go b/pkg/modules/user/impluser/module.go index b328f41351..92bb618d61 100644 --- a/pkg/modules/user/impluser/module.go +++ b/pkg/modules/user/impluser/module.go @@ -20,12 +20,13 @@ import ( "github.com/SigNoz/signoz/pkg/types/emailtypes" "github.com/SigNoz/signoz/pkg/types/integrationtypes" "github.com/SigNoz/signoz/pkg/types/roletypes" + "github.com/SigNoz/signoz/pkg/types/usertypes" "github.com/SigNoz/signoz/pkg/valuer" "github.com/dustin/go-humanize" ) type Module struct { - store types.UserStore + store usertypes.UserStore tokenizer tokenizer.Tokenizer emailing emailing.Emailing settings factory.ScopedProviderSettings @@ -36,7 +37,7 @@ type Module struct { } // This module is a WIP, don't take inspiration from this. -func NewModule(store types.UserStore, tokenizer tokenizer.Tokenizer, emailing emailing.Emailing, providerSettings factory.ProviderSettings, orgSetter organization.Setter, authz authz.AuthZ, analytics analytics.Analytics, config user.Config) root.Module { +func NewModule(store usertypes.UserStore, tokenizer tokenizer.Tokenizer, emailing emailing.Emailing, providerSettings factory.ProviderSettings, orgSetter organization.Setter, authz authz.AuthZ, analytics analytics.Analytics, config user.Config) root.Module { settings := factory.NewScopedProviderSettings(providerSettings, "github.com/SigNoz/signoz/pkg/modules/user/impluser") return &Module{ store: store, @@ -50,7 +51,7 @@ func NewModule(store types.UserStore, tokenizer tokenizer.Tokenizer, emailing em } } -func (m *Module) AcceptInvite(ctx context.Context, token string, password string) (*types.User, error) { +func (m *Module) AcceptInvite(ctx context.Context, token string, password string) (*usertypes.User, error) { // get the user by reset password token user, err := m.store.GetUserByResetPasswordToken(ctx, token) if err != nil { @@ -72,7 +73,7 @@ func (m *Module) AcceptInvite(ctx context.Context, token string, password string return user, nil } -func (m *Module) GetInviteByToken(ctx context.Context, token string) (*types.Invite, error) { +func (m *Module) GetInviteByToken(ctx context.Context, token string) (*usertypes.Invite, error) { // get the user user, err := m.store.GetUserByResetPasswordToken(ctx, token) if err != nil { @@ -80,7 +81,7 @@ func (m *Module) GetInviteByToken(ctx context.Context, token string) (*types.Inv } // create a dummy invite obj for backward compatibility - invite := &types.Invite{ + invite := &usertypes.Invite{ Identifiable: types.Identifiable{ ID: user.ID, }, @@ -99,7 +100,7 @@ func (m *Module) GetInviteByToken(ctx context.Context, token string) (*types.Inv } // CreateBulk implements invite.Module. -func (m *Module) CreateBulkInvite(ctx context.Context, orgID valuer.UUID, userID valuer.UUID, bulkInvites *types.PostableBulkInviteRequest) ([]*types.Invite, error) { +func (m *Module) CreateBulkInvite(ctx context.Context, orgID valuer.UUID, userID valuer.UUID, bulkInvites *usertypes.PostableBulkInviteRequest) ([]*usertypes.Invite, error) { creator, err := m.store.GetUser(ctx, userID) if err != nil { return nil, err @@ -110,7 +111,7 @@ func (m *Module) CreateBulkInvite(ctx context.Context, orgID valuer.UUID, userID for idx, invite := range bulkInvites.Invites { emails[idx] = invite.Email.StringValue() } - users, err := m.store.GetUsersByEmailsOrgIDAndStatuses(ctx, orgID, emails, []string{types.UserStatusActive.StringValue(), types.UserStatusPendingInvite.StringValue()}) + users, err := m.store.GetUsersByEmailsOrgIDAndStatuses(ctx, orgID, emails, []string{usertypes.UserStatusActive.StringValue(), usertypes.UserStatusPendingInvite.StringValue()}) if err != nil { return nil, err } @@ -120,7 +121,7 @@ func (m *Module) CreateBulkInvite(ctx context.Context, orgID valuer.UUID, userID return nil, errors.WithAdditionalf(err, "Cannot send invite to root user") } - if users[0].Status == types.UserStatusPendingInvite { + if users[0].Status == usertypes.UserStatusPendingInvite { return nil, errors.Newf(errors.TypeAlreadyExists, errors.CodeAlreadyExists, "An invite already exists for this email: %s", users[0].Email.StringValue()) } @@ -128,8 +129,8 @@ func (m *Module) CreateBulkInvite(ctx context.Context, orgID valuer.UUID, userID } type userWithResetToken struct { - User *types.User - ResetPasswordToken *types.ResetPasswordToken + User *usertypes.User + ResetPasswordToken *usertypes.ResetPasswordToken } newUsersWithResetToken := make([]*userWithResetToken, len(bulkInvites.Invites)) @@ -142,7 +143,7 @@ func (m *Module) CreateBulkInvite(ctx context.Context, orgID valuer.UUID, userID } // create a new user with pending invite status - newUser, err := types.NewUser(invite.Name, invite.Email, role, orgID, types.UserStatusPendingInvite) + newUser, err := usertypes.NewUser(invite.Name, invite.Email, role, orgID, usertypes.UserStatusPendingInvite) if err != nil { return err } @@ -170,7 +171,7 @@ func (m *Module) CreateBulkInvite(ctx context.Context, orgID valuer.UUID, userID return nil, err } - invites := make([]*types.Invite, len(bulkInvites.Invites)) + invites := make([]*usertypes.Invite, len(bulkInvites.Invites)) // send password reset emails to all the invited users for idx, userWithToken := range newUsersWithResetToken { @@ -179,7 +180,7 @@ func (m *Module) CreateBulkInvite(ctx context.Context, orgID valuer.UUID, userID "invitee_role": userWithToken.User.Role, }) - invite := &types.Invite{ + invite := &usertypes.Invite{ Identifiable: types.Identifiable{ ID: userWithToken.User.ID, }, @@ -219,16 +220,16 @@ func (m *Module) CreateBulkInvite(ctx context.Context, orgID valuer.UUID, userID return invites, nil } -func (m *Module) ListInvite(ctx context.Context, orgID string) ([]*types.Invite, error) { +func (m *Module) ListInvite(ctx context.Context, orgID string) ([]*usertypes.Invite, error) { // find all the users with pending_invite status users, err := m.store.ListUsersByOrgID(ctx, valuer.MustNewUUID(orgID)) if err != nil { return nil, err } - pendingUsers := slices.DeleteFunc(users, func(user *types.User) bool { return user.Status != types.UserStatusPendingInvite }) + pendingUsers := slices.DeleteFunc(users, func(user *usertypes.User) bool { return user.Status != usertypes.UserStatusPendingInvite }) - var invites []*types.Invite + var invites []*usertypes.Invite for _, pUser := range pendingUsers { // get the reset password token @@ -238,7 +239,7 @@ func (m *Module) ListInvite(ctx context.Context, orgID string) ([]*types.Invite, } // create a dummy invite obj for backward compatibility - invite := &types.Invite{ + invite := &usertypes.Invite{ Identifiable: types.Identifiable{ ID: pUser.ID, }, @@ -259,7 +260,7 @@ func (m *Module) ListInvite(ctx context.Context, orgID string) ([]*types.Invite, return invites, nil } -func (module *Module) CreateUser(ctx context.Context, input *types.User, opts ...root.CreateUserOption) error { +func (module *Module) CreateUser(ctx context.Context, input *usertypes.User, opts ...root.CreateUserOption) error { createUserOpts := root.NewCreateUserOptions(opts...) // since assign is idempotant multiple calls to assign won't cause issues in case of retries. @@ -284,14 +285,14 @@ func (module *Module) CreateUser(ctx context.Context, input *types.User, opts .. return err } - traitsOrProperties := types.NewTraitsFromUser(input) + traitsOrProperties := usertypes.NewTraitsFromUser(input) module.analytics.IdentifyUser(ctx, input.OrgID.String(), input.ID.String(), traitsOrProperties) module.analytics.TrackUser(ctx, input.OrgID.String(), input.ID.String(), "User Created", traitsOrProperties) return nil } -func (m *Module) UpdateUser(ctx context.Context, orgID valuer.UUID, id string, user *types.User, updatedBy string) (*types.User, error) { +func (m *Module) UpdateUser(ctx context.Context, orgID valuer.UUID, id string, user *usertypes.User, updatedBy string) (*usertypes.User, error) { existingUser, err := m.store.GetUser(ctx, valuer.MustNewUUID(id)) if err != nil { return nil, err @@ -350,12 +351,12 @@ func (m *Module) UpdateUser(ctx context.Context, orgID valuer.UUID, id string, u return existingUser, nil } -func (module *Module) UpdateAnyUser(ctx context.Context, orgID valuer.UUID, user *types.User) error { +func (module *Module) UpdateAnyUser(ctx context.Context, orgID valuer.UUID, user *usertypes.User) error { if err := module.store.UpdateUser(ctx, orgID, user); err != nil { return err } - traits := types.NewTraitsFromUser(user) + traits := usertypes.NewTraitsFromUser(user) module.analytics.IdentifyUser(ctx, user.OrgID.String(), user.ID.String(), traits) module.analytics.TrackUser(ctx, user.OrgID.String(), user.ID.String(), "User Updated", traits) @@ -412,7 +413,7 @@ func (module *Module) DeleteUser(ctx context.Context, orgID valuer.UUID, id stri return nil } -func (module *Module) GetOrCreateResetPasswordToken(ctx context.Context, userID valuer.UUID) (*types.ResetPasswordToken, error) { +func (module *Module) GetOrCreateResetPasswordToken(ctx context.Context, userID valuer.UUID) (*usertypes.ResetPasswordToken, error) { user, err := module.store.GetUser(ctx, userID) if err != nil { return nil, err @@ -435,7 +436,7 @@ func (module *Module) GetOrCreateResetPasswordToken(ctx context.Context, userID if password == nil { // if the user does not have a password, we need to create a new one (common for SSO/SAML users) - password = types.MustGenerateFactorPassword(userID.String()) + password = usertypes.MustGenerateFactorPassword(userID.String()) if err := module.store.CreatePassword(ctx, password); err != nil { return nil, err @@ -461,7 +462,7 @@ func (module *Module) GetOrCreateResetPasswordToken(ctx context.Context, userID } // create a new token - resetPasswordToken, err := types.NewResetPasswordToken(password.ID, time.Now().Add(module.config.Password.Reset.MaxTokenLifetime)) + resetPasswordToken, err := usertypes.NewResetPasswordToken(password.ID, time.Now().Add(module.config.Password.Reset.MaxTokenLifetime)) if err != nil { return nil, err } @@ -554,7 +555,7 @@ func (module *Module) UpdatePasswordByResetPasswordToken(ctx context.Context, to } // since grant is idempotent, multiple calls won't cause issues in case of retries - if user.Status == types.UserStatusPendingInvite { + if user.Status == usertypes.UserStatusPendingInvite { if err = module.authz.Grant( ctx, user.OrgID, @@ -566,8 +567,8 @@ func (module *Module) UpdatePasswordByResetPasswordToken(ctx context.Context, to } return module.store.RunInTx(ctx, func(ctx context.Context) error { - if user.Status == types.UserStatusPendingInvite { - if err := user.UpdateStatus(types.UserStatusActive); err != nil { + if user.Status == usertypes.UserStatusPendingInvite { + if err := user.UpdateStatus(usertypes.UserStatusActive); err != nil { return err } if err := module.store.UpdateUser(ctx, user.OrgID, user); err != nil { @@ -607,7 +608,7 @@ func (module *Module) UpdatePassword(ctx context.Context, userID valuer.UUID, ol } if !password.Equals(oldpasswd) { - return errors.New(errors.TypeInvalidInput, types.ErrCodeIncorrectPassword, "old password is incorrect") + return errors.New(errors.TypeInvalidInput, usertypes.ErrCodeIncorrectPassword, "old password is incorrect") } if err := password.Update(passwd); err != nil { @@ -631,7 +632,7 @@ func (module *Module) UpdatePassword(ctx context.Context, userID valuer.UUID, ol return module.tokenizer.DeleteTokensByUserID(ctx, userID) } -func (module *Module) GetOrCreateUser(ctx context.Context, user *types.User, opts ...root.CreateUserOption) (*types.User, error) { +func (module *Module) GetOrCreateUser(ctx context.Context, user *usertypes.User, opts ...root.CreateUserOption) (*usertypes.User, error) { existingUser, err := module.GetNonDeletedUserByEmailAndOrgID(ctx, user.Email, user.OrgID) if err != nil { if !errors.Ast(err, errors.TypeNotFound) { @@ -641,7 +642,7 @@ func (module *Module) GetOrCreateUser(ctx context.Context, user *types.User, opt if existingUser != nil { // for users logging through SSO flow but are having status as pending_invite - if existingUser.Status == types.UserStatusPendingInvite { + if existingUser.Status == usertypes.UserStatusPendingInvite { // respect the role coming from the SSO existingUser.Update("", user.Role) // activate the user @@ -661,19 +662,19 @@ func (module *Module) GetOrCreateUser(ctx context.Context, user *types.User, opt return user, nil } -func (m *Module) CreateAPIKey(ctx context.Context, apiKey *types.StorableAPIKey) error { +func (m *Module) CreateAPIKey(ctx context.Context, apiKey *usertypes.StorableAPIKey) error { return m.store.CreateAPIKey(ctx, apiKey) } -func (m *Module) UpdateAPIKey(ctx context.Context, id valuer.UUID, apiKey *types.StorableAPIKey, updaterID valuer.UUID) error { +func (m *Module) UpdateAPIKey(ctx context.Context, id valuer.UUID, apiKey *usertypes.StorableAPIKey, updaterID valuer.UUID) error { return m.store.UpdateAPIKey(ctx, id, apiKey, updaterID) } -func (m *Module) ListAPIKeys(ctx context.Context, orgID valuer.UUID) ([]*types.StorableAPIKeyUser, error) { +func (m *Module) ListAPIKeys(ctx context.Context, orgID valuer.UUID) ([]*usertypes.StorableAPIKeyUser, error) { return m.store.ListAPIKeys(ctx, orgID) } -func (m *Module) GetAPIKey(ctx context.Context, orgID, id valuer.UUID) (*types.StorableAPIKeyUser, error) { +func (m *Module) GetAPIKey(ctx context.Context, orgID, id valuer.UUID) (*usertypes.StorableAPIKeyUser, error) { return m.store.GetAPIKey(ctx, orgID, id) } @@ -681,13 +682,13 @@ func (m *Module) RevokeAPIKey(ctx context.Context, id, removedByUserID valuer.UU return m.store.RevokeAPIKey(ctx, id, removedByUserID) } -func (module *Module) CreateFirstUser(ctx context.Context, organization *types.Organization, name string, email valuer.Email, passwd string) (*types.User, error) { - user, err := types.NewRootUser(name, email, organization.ID) +func (module *Module) CreateFirstUser(ctx context.Context, organization *types.Organization, name string, email valuer.Email, passwd string) (*usertypes.User, error) { + user, err := usertypes.NewRootUser(name, email, organization.ID) if err != nil { return nil, err } - password, err := types.NewFactorPassword(passwd, user.ID.StringValue()) + password, err := usertypes.NewFactorPassword(passwd, user.ID.StringValue()) if err != nil { return nil, err } @@ -726,12 +727,12 @@ func (module *Module) CreateFirstUser(ctx context.Context, organization *types.O func (module *Module) Collect(ctx context.Context, orgID valuer.UUID) (map[string]any, error) { stats := make(map[string]any) - counts, err := module.store.CountByOrgIDAndStatuses(ctx, orgID, []string{types.UserStatusActive.StringValue(), types.UserStatusDeleted.StringValue(), types.UserStatusPendingInvite.StringValue()}) + counts, err := module.store.CountByOrgIDAndStatuses(ctx, orgID, []string{usertypes.UserStatusActive.StringValue(), usertypes.UserStatusDeleted.StringValue(), usertypes.UserStatusPendingInvite.StringValue()}) if err == nil { - stats["user.count"] = counts[types.UserStatusActive] + counts[types.UserStatusDeleted] + counts[types.UserStatusPendingInvite] - stats["user.count.active"] = counts[types.UserStatusActive] - stats["user.count.deleted"] = counts[types.UserStatusDeleted] - stats["user.count.pending_invite"] = counts[types.UserStatusPendingInvite] + stats["user.count"] = counts[usertypes.UserStatusActive] + counts[usertypes.UserStatusDeleted] + counts[usertypes.UserStatusPendingInvite] + stats["user.count.active"] = counts[usertypes.UserStatusActive] + stats["user.count.deleted"] = counts[usertypes.UserStatusDeleted] + stats["user.count.pending_invite"] = counts[usertypes.UserStatusPendingInvite] } count, err := module.store.CountAPIKeyByOrgID(ctx, orgID) @@ -743,14 +744,14 @@ func (module *Module) Collect(ctx context.Context, orgID valuer.UUID) (map[strin } // this function restricts that only one non-deleted user email can exist for an org ID, if found more, it throws an error -func (module *Module) GetNonDeletedUserByEmailAndOrgID(ctx context.Context, email valuer.Email, orgID valuer.UUID) (*types.User, error) { +func (module *Module) GetNonDeletedUserByEmailAndOrgID(ctx context.Context, email valuer.Email, orgID valuer.UUID) (*usertypes.User, error) { existingUsers, err := module.store.GetUsersByEmailAndOrgID(ctx, email, orgID) if err != nil { return nil, err } // filter out the deleted users - existingUsers = slices.DeleteFunc(existingUsers, func(user *types.User) bool { return user.ErrIfDeleted() != nil }) + existingUsers = slices.DeleteFunc(existingUsers, func(user *usertypes.User) bool { return user.ErrIfDeleted() != nil }) if len(existingUsers) > 1 { return nil, errors.Newf(errors.TypeInternal, errors.CodeInternal, "Multiple non-deleted users found for email %s in org_id: %s", email.StringValue(), orgID.StringValue()) @@ -764,7 +765,7 @@ func (module *Module) GetNonDeletedUserByEmailAndOrgID(ctx context.Context, emai } -func (module *Module) createUserWithoutGrant(ctx context.Context, input *types.User, opts ...root.CreateUserOption) error { +func (module *Module) createUserWithoutGrant(ctx context.Context, input *usertypes.User, opts ...root.CreateUserOption) error { createUserOpts := root.NewCreateUserOptions(opts...) if err := module.store.RunInTx(ctx, func(ctx context.Context) error { if err := module.store.CreateUser(ctx, input); err != nil { @@ -782,14 +783,14 @@ func (module *Module) createUserWithoutGrant(ctx context.Context, input *types.U return err } - traitsOrProperties := types.NewTraitsFromUser(input) + traitsOrProperties := usertypes.NewTraitsFromUser(input) module.analytics.IdentifyUser(ctx, input.OrgID.String(), input.ID.String(), traitsOrProperties) module.analytics.TrackUser(ctx, input.OrgID.String(), input.ID.String(), "User Created", traitsOrProperties) return nil } -func (module *Module) activatePendingUser(ctx context.Context, user *types.User) error { +func (module *Module) activatePendingUser(ctx context.Context, user *usertypes.User) error { err := module.authz.Grant( ctx, user.OrgID, @@ -800,7 +801,7 @@ func (module *Module) activatePendingUser(ctx context.Context, user *types.User) return err } - if err := user.UpdateStatus(types.UserStatusActive); err != nil { + if err := user.UpdateStatus(usertypes.UserStatusActive); err != nil { return err } err = module.store.UpdateUser(ctx, user.OrgID, user) diff --git a/pkg/modules/user/impluser/service.go b/pkg/modules/user/impluser/service.go index 064cf617c8..5f51a191f2 100644 --- a/pkg/modules/user/impluser/service.go +++ b/pkg/modules/user/impluser/service.go @@ -12,12 +12,13 @@ import ( "github.com/SigNoz/signoz/pkg/types" "github.com/SigNoz/signoz/pkg/types/authtypes" "github.com/SigNoz/signoz/pkg/types/roletypes" + "github.com/SigNoz/signoz/pkg/types/usertypes" "github.com/SigNoz/signoz/pkg/valuer" ) type service struct { settings factory.ScopedProviderSettings - store types.UserStore + store usertypes.UserStore module user.Module orgGetter organization.Getter authz authz.AuthZ @@ -27,7 +28,7 @@ type service struct { func NewService( providerSettings factory.ProviderSettings, - store types.UserStore, + store usertypes.UserStore, module user.Module, orgGetter organization.Getter, authz authz.AuthZ, @@ -171,12 +172,12 @@ func (s *service) createOrPromoteRootUser(ctx context.Context, orgID valuer.UUID } // Create new root user - newUser, err := types.NewRootUser(s.config.Email.String(), s.config.Email, orgID) + newUser, err := usertypes.NewRootUser(s.config.Email.String(), s.config.Email, orgID) if err != nil { return err } - factorPassword, err := types.NewFactorPassword(s.config.Password, newUser.ID.StringValue()) + factorPassword, err := usertypes.NewFactorPassword(s.config.Password, newUser.ID.StringValue()) if err != nil { return err } @@ -184,7 +185,7 @@ func (s *service) createOrPromoteRootUser(ctx context.Context, orgID valuer.UUID return s.module.CreateUser(ctx, newUser, user.WithFactorPassword(factorPassword)) } -func (s *service) updateExistingRootUser(ctx context.Context, orgID valuer.UUID, existingRoot *types.User) error { +func (s *service) updateExistingRootUser(ctx context.Context, orgID valuer.UUID, existingRoot *usertypes.User) error { existingRoot.PromoteToRoot() if existingRoot.Email != s.config.Email { @@ -204,7 +205,7 @@ func (s *service) setPassword(ctx context.Context, userID valuer.UUID) error { return err } - factorPassword, err := types.NewFactorPassword(s.config.Password, userID.StringValue()) + factorPassword, err := usertypes.NewFactorPassword(s.config.Password, userID.StringValue()) if err != nil { return err } diff --git a/pkg/modules/user/impluser/store.go b/pkg/modules/user/impluser/store.go index 6dd242dae7..c25d5bdbe3 100644 --- a/pkg/modules/user/impluser/store.go +++ b/pkg/modules/user/impluser/store.go @@ -12,6 +12,7 @@ import ( "github.com/SigNoz/signoz/pkg/types" "github.com/SigNoz/signoz/pkg/types/authtypes" "github.com/SigNoz/signoz/pkg/types/preferencetypes" + "github.com/SigNoz/signoz/pkg/types/usertypes" "github.com/SigNoz/signoz/pkg/valuer" "github.com/uptrace/bun" ) @@ -21,11 +22,11 @@ type store struct { settings factory.ProviderSettings } -func NewStore(sqlstore sqlstore.SQLStore, settings factory.ProviderSettings) types.UserStore { +func NewStore(sqlstore sqlstore.SQLStore, settings factory.ProviderSettings) usertypes.UserStore { return &store{sqlstore: sqlstore, settings: settings} } -func (store *store) CreatePassword(ctx context.Context, password *types.FactorPassword) error { +func (store *store) CreatePassword(ctx context.Context, password *usertypes.FactorPassword) error { _, err := store. sqlstore. BunDBCtx(ctx). @@ -33,13 +34,13 @@ func (store *store) CreatePassword(ctx context.Context, password *types.FactorPa Model(password). Exec(ctx) if err != nil { - return store.sqlstore.WrapAlreadyExistsErrf(err, types.ErrPasswordAlreadyExists, "password for user %s already exists", password.UserID) + return store.sqlstore.WrapAlreadyExistsErrf(err, usertypes.ErrPasswordAlreadyExists, "password for user %s already exists", password.UserID) } return nil } -func (store *store) CreateUser(ctx context.Context, user *types.User) error { +func (store *store) CreateUser(ctx context.Context, user *usertypes.User) error { _, err := store. sqlstore. BunDBCtx(ctx). @@ -47,13 +48,13 @@ func (store *store) CreateUser(ctx context.Context, user *types.User) error { Model(user). Exec(ctx) if err != nil { - return store.sqlstore.WrapAlreadyExistsErrf(err, types.ErrUserAlreadyExists, "user with email %s already exists in org %s", user.Email, user.OrgID) + return store.sqlstore.WrapAlreadyExistsErrf(err, usertypes.ErrUserAlreadyExists, "user with email %s already exists in org %s", user.Email, user.OrgID) } return nil } -func (store *store) GetUsersByEmail(ctx context.Context, email valuer.Email) ([]*types.User, error) { - var users []*types.User +func (store *store) GetUsersByEmail(ctx context.Context, email valuer.Email) ([]*usertypes.User, error) { + var users []*usertypes.User err := store. sqlstore. @@ -69,8 +70,8 @@ func (store *store) GetUsersByEmail(ctx context.Context, email valuer.Email) ([] return users, nil } -func (store *store) GetUser(ctx context.Context, id valuer.UUID) (*types.User, error) { - user := new(types.User) +func (store *store) GetUser(ctx context.Context, id valuer.UUID) (*usertypes.User, error) { + user := new(usertypes.User) err := store. sqlstore. @@ -80,14 +81,14 @@ func (store *store) GetUser(ctx context.Context, id valuer.UUID) (*types.User, e Where("id = ?", id). Scan(ctx) if err != nil { - return nil, store.sqlstore.WrapNotFoundErrf(err, types.ErrCodeUserNotFound, "user with id %s does not exist", id) + return nil, store.sqlstore.WrapNotFoundErrf(err, usertypes.ErrCodeUserNotFound, "user with id %s does not exist", id) } return user, nil } -func (store *store) GetByOrgIDAndID(ctx context.Context, orgID valuer.UUID, id valuer.UUID) (*types.User, error) { - user := new(types.User) +func (store *store) GetByOrgIDAndID(ctx context.Context, orgID valuer.UUID, id valuer.UUID) (*usertypes.User, error) { + user := new(usertypes.User) err := store. sqlstore. @@ -98,14 +99,14 @@ func (store *store) GetByOrgIDAndID(ctx context.Context, orgID valuer.UUID, id v Where("id = ?", id). Scan(ctx) if err != nil { - return nil, store.sqlstore.WrapNotFoundErrf(err, types.ErrCodeUserNotFound, "user with id %s does not exist", id) + return nil, store.sqlstore.WrapNotFoundErrf(err, usertypes.ErrCodeUserNotFound, "user with id %s does not exist", id) } return user, nil } -func (store *store) GetUsersByEmailAndOrgID(ctx context.Context, email valuer.Email, orgID valuer.UUID) ([]*types.User, error) { - var users []*types.User +func (store *store) GetUsersByEmailAndOrgID(ctx context.Context, email valuer.Email, orgID valuer.UUID) ([]*usertypes.User, error) { + var users []*usertypes.User err := store. sqlstore. @@ -122,8 +123,8 @@ func (store *store) GetUsersByEmailAndOrgID(ctx context.Context, email valuer.Em return users, nil } -func (store *store) GetActiveUsersByRoleAndOrgID(ctx context.Context, role types.Role, orgID valuer.UUID) ([]*types.User, error) { - var users []*types.User +func (store *store) GetActiveUsersByRoleAndOrgID(ctx context.Context, role types.LegacyRole, orgID valuer.UUID) ([]*usertypes.User, error) { + var users []*usertypes.User err := store. sqlstore. @@ -132,7 +133,7 @@ func (store *store) GetActiveUsersByRoleAndOrgID(ctx context.Context, role types Model(&users). Where("org_id = ?", orgID). Where("role = ?", role). - Where("status = ?", types.UserStatusActive.StringValue()). + Where("status = ?", usertypes.UserStatusActive.StringValue()). Scan(ctx) if err != nil { return nil, err @@ -141,7 +142,7 @@ func (store *store) GetActiveUsersByRoleAndOrgID(ctx context.Context, role types return users, nil } -func (store *store) UpdateUser(ctx context.Context, orgID valuer.UUID, user *types.User) error { +func (store *store) UpdateUser(ctx context.Context, orgID valuer.UUID, user *usertypes.User) error { _, err := store. sqlstore. BunDBCtx(ctx). @@ -157,13 +158,13 @@ func (store *store) UpdateUser(ctx context.Context, orgID valuer.UUID, user *typ Where("id = ?", user.ID). Exec(ctx) if err != nil { - return store.sqlstore.WrapNotFoundErrf(err, types.ErrCodeUserNotFound, "user does not exist in org: %s", orgID) + return store.sqlstore.WrapNotFoundErrf(err, usertypes.ErrCodeUserNotFound, "user does not exist in org: %s", orgID) } return nil } -func (store *store) ListUsersByOrgID(ctx context.Context, orgID valuer.UUID) ([]*types.GettableUser, error) { - users := []*types.User{} +func (store *store) ListUsersByOrgID(ctx context.Context, orgID valuer.UUID) ([]*usertypes.GettableUser, error) { + users := []*usertypes.User{} err := store. sqlstore. @@ -191,7 +192,7 @@ func (store *store) DeleteUser(ctx context.Context, orgID string, id string) err // get the password id - var password types.FactorPassword + var password usertypes.FactorPassword err = tx.NewSelect(). Model(&password). Where("user_id = ?", id). @@ -202,7 +203,7 @@ func (store *store) DeleteUser(ctx context.Context, orgID string, id string) err // delete reset password request _, err = tx.NewDelete(). - Model(new(types.ResetPasswordToken)). + Model(new(usertypes.ResetPasswordToken)). Where("password_id = ?", password.ID.String()). Exec(ctx) if err != nil { @@ -211,7 +212,7 @@ func (store *store) DeleteUser(ctx context.Context, orgID string, id string) err // delete factor password _, err = tx.NewDelete(). - Model(new(types.FactorPassword)). + Model(new(usertypes.FactorPassword)). Where("user_id = ?", id). Exec(ctx) if err != nil { @@ -220,7 +221,7 @@ func (store *store) DeleteUser(ctx context.Context, orgID string, id string) err // delete api keys _, err = tx.NewDelete(). - Model(&types.StorableAPIKey{}). + Model(&usertypes.StorableAPIKey{}). Where("user_id = ?", id). Exec(ctx) if err != nil { @@ -247,7 +248,7 @@ func (store *store) DeleteUser(ctx context.Context, orgID string, id string) err // delete user _, err = tx.NewDelete(). - Model(new(types.User)). + Model(new(usertypes.User)). Where("org_id = ?", orgID). Where("id = ?", id). Exec(ctx) @@ -275,7 +276,7 @@ func (store *store) SoftDeleteUser(ctx context.Context, orgID string, id string) // get the password id - var password types.FactorPassword + var password usertypes.FactorPassword err = tx.NewSelect(). Model(&password). Where("user_id = ?", id). @@ -286,7 +287,7 @@ func (store *store) SoftDeleteUser(ctx context.Context, orgID string, id string) // delete reset password request _, err = tx.NewDelete(). - Model(new(types.ResetPasswordToken)). + Model(new(usertypes.ResetPasswordToken)). Where("password_id = ?", password.ID.String()). Exec(ctx) if err != nil { @@ -295,7 +296,7 @@ func (store *store) SoftDeleteUser(ctx context.Context, orgID string, id string) // delete factor password _, err = tx.NewDelete(). - Model(new(types.FactorPassword)). + Model(new(usertypes.FactorPassword)). Where("user_id = ?", id). Exec(ctx) if err != nil { @@ -304,7 +305,7 @@ func (store *store) SoftDeleteUser(ctx context.Context, orgID string, id string) // delete api keys _, err = tx.NewDelete(). - Model(&types.StorableAPIKey{}). + Model(&usertypes.StorableAPIKey{}). Where("user_id = ?", id). Exec(ctx) if err != nil { @@ -332,8 +333,8 @@ func (store *store) SoftDeleteUser(ctx context.Context, orgID string, id string) // soft delete user now := time.Now() _, err = tx.NewUpdate(). - Model(new(types.User)). - Set("status = ?", types.UserStatusDeleted). + Model(new(usertypes.User)). + Set("status = ?", usertypes.UserStatusDeleted). Set("deleted_at = ?", now). Set("updated_at = ?", now). Where("org_id = ?", orgID). @@ -351,7 +352,7 @@ func (store *store) SoftDeleteUser(ctx context.Context, orgID string, id string) return nil } -func (store *store) CreateResetPasswordToken(ctx context.Context, resetPasswordToken *types.ResetPasswordToken) error { +func (store *store) CreateResetPasswordToken(ctx context.Context, resetPasswordToken *usertypes.ResetPasswordToken) error { _, err := store. sqlstore. BunDBCtx(ctx). @@ -359,14 +360,14 @@ func (store *store) CreateResetPasswordToken(ctx context.Context, resetPasswordT Model(resetPasswordToken). Exec(ctx) if err != nil { - return store.sqlstore.WrapAlreadyExistsErrf(err, types.ErrResetPasswordTokenAlreadyExists, "reset password token for password %s already exists", resetPasswordToken.PasswordID) + return store.sqlstore.WrapAlreadyExistsErrf(err, usertypes.ErrResetPasswordTokenAlreadyExists, "reset password token for password %s already exists", resetPasswordToken.PasswordID) } return nil } -func (store *store) GetPassword(ctx context.Context, id valuer.UUID) (*types.FactorPassword, error) { - password := new(types.FactorPassword) +func (store *store) GetPassword(ctx context.Context, id valuer.UUID) (*usertypes.FactorPassword, error) { + password := new(usertypes.FactorPassword) err := store. sqlstore. @@ -376,14 +377,14 @@ func (store *store) GetPassword(ctx context.Context, id valuer.UUID) (*types.Fac Where("id = ?", id). Scan(ctx) if err != nil { - return nil, store.sqlstore.WrapNotFoundErrf(err, types.ErrPasswordNotFound, "password with id: %s does not exist", id) + return nil, store.sqlstore.WrapNotFoundErrf(err, usertypes.ErrPasswordNotFound, "password with id: %s does not exist", id) } return password, nil } -func (store *store) GetPasswordByUserID(ctx context.Context, userID valuer.UUID) (*types.FactorPassword, error) { - password := new(types.FactorPassword) +func (store *store) GetPasswordByUserID(ctx context.Context, userID valuer.UUID) (*usertypes.FactorPassword, error) { + password := new(usertypes.FactorPassword) err := store. sqlstore. @@ -393,13 +394,13 @@ func (store *store) GetPasswordByUserID(ctx context.Context, userID valuer.UUID) Where("user_id = ?", userID). Scan(ctx) if err != nil { - return nil, store.sqlstore.WrapNotFoundErrf(err, types.ErrPasswordNotFound, "password for user %s does not exist", userID) + return nil, store.sqlstore.WrapNotFoundErrf(err, usertypes.ErrPasswordNotFound, "password for user %s does not exist", userID) } return password, nil } -func (store *store) GetResetPasswordTokenByPasswordID(ctx context.Context, passwordID valuer.UUID) (*types.ResetPasswordToken, error) { - resetPasswordToken := new(types.ResetPasswordToken) +func (store *store) GetResetPasswordTokenByPasswordID(ctx context.Context, passwordID valuer.UUID) (*usertypes.ResetPasswordToken, error) { + resetPasswordToken := new(usertypes.ResetPasswordToken) err := store. sqlstore. @@ -409,7 +410,7 @@ func (store *store) GetResetPasswordTokenByPasswordID(ctx context.Context, passw Where("password_id = ?", passwordID). Scan(ctx) if err != nil { - return nil, store.sqlstore.WrapNotFoundErrf(err, types.ErrResetPasswordTokenNotFound, "reset password token for password %s does not exist", passwordID) + return nil, store.sqlstore.WrapNotFoundErrf(err, usertypes.ErrResetPasswordTokenNotFound, "reset password token for password %s does not exist", passwordID) } return resetPasswordToken, nil @@ -417,7 +418,7 @@ func (store *store) GetResetPasswordTokenByPasswordID(ctx context.Context, passw func (store *store) DeleteResetPasswordTokenByPasswordID(ctx context.Context, passwordID valuer.UUID) error { _, err := store.sqlstore.BunDBCtx(ctx).NewDelete(). - Model(&types.ResetPasswordToken{}). + Model(&usertypes.ResetPasswordToken{}). Where("password_id = ?", passwordID). Exec(ctx) if err != nil { @@ -427,8 +428,8 @@ func (store *store) DeleteResetPasswordTokenByPasswordID(ctx context.Context, pa return nil } -func (store *store) GetResetPasswordToken(ctx context.Context, token string) (*types.ResetPasswordToken, error) { - resetPasswordRequest := new(types.ResetPasswordToken) +func (store *store) GetResetPasswordToken(ctx context.Context, token string) (*usertypes.ResetPasswordToken, error) { + resetPasswordRequest := new(usertypes.ResetPasswordToken) err := store. sqlstore. @@ -438,38 +439,38 @@ func (store *store) GetResetPasswordToken(ctx context.Context, token string) (*t Where("token = ?", token). Scan(ctx) if err != nil { - return nil, store.sqlstore.WrapNotFoundErrf(err, types.ErrResetPasswordTokenNotFound, "reset password token does not exist") + return nil, store.sqlstore.WrapNotFoundErrf(err, usertypes.ErrResetPasswordTokenNotFound, "reset password token does not exist") } return resetPasswordRequest, nil } -func (store *store) UpdatePassword(ctx context.Context, factorPassword *types.FactorPassword) error { +func (store *store) UpdatePassword(ctx context.Context, factorPassword *usertypes.FactorPassword) error { _, err := store.sqlstore.BunDBCtx(ctx). NewUpdate(). Model(factorPassword). Where("user_id = ?", factorPassword.UserID). Exec(ctx) if err != nil { - return store.sqlstore.WrapNotFoundErrf(err, types.ErrPasswordNotFound, "password for user %s does not exist", factorPassword.UserID) + return store.sqlstore.WrapNotFoundErrf(err, usertypes.ErrPasswordNotFound, "password for user %s does not exist", factorPassword.UserID) } return nil } // --- API KEY --- -func (store *store) CreateAPIKey(ctx context.Context, apiKey *types.StorableAPIKey) error { +func (store *store) CreateAPIKey(ctx context.Context, apiKey *usertypes.StorableAPIKey) error { _, err := store.sqlstore.BunDB().NewInsert(). Model(apiKey). Exec(ctx) if err != nil { - return store.sqlstore.WrapAlreadyExistsErrf(err, types.ErrAPIKeyAlreadyExists, "API key with token: %s already exists", apiKey.Token) + return store.sqlstore.WrapAlreadyExistsErrf(err, usertypes.ErrAPIKeyAlreadyExists, "API key with token: %s already exists", apiKey.Token) } return nil } -func (store *store) UpdateAPIKey(ctx context.Context, id valuer.UUID, apiKey *types.StorableAPIKey, updaterID valuer.UUID) error { +func (store *store) UpdateAPIKey(ctx context.Context, id valuer.UUID, apiKey *usertypes.StorableAPIKey, updaterID valuer.UUID) error { apiKey.UpdatedBy = updaterID.String() apiKey.UpdatedAt = time.Now() _, err := store.sqlstore.BunDB().NewUpdate(). @@ -479,13 +480,13 @@ func (store *store) UpdateAPIKey(ctx context.Context, id valuer.UUID, apiKey *ty Where("revoked = false"). Exec(ctx) if err != nil { - return store.sqlstore.WrapNotFoundErrf(err, types.ErrAPIKeyNotFound, "API key with id: %s does not exist", id) + return store.sqlstore.WrapNotFoundErrf(err, usertypes.ErrAPIKeyNotFound, "API key with id: %s does not exist", id) } return nil } -func (store *store) ListAPIKeys(ctx context.Context, orgID valuer.UUID) ([]*types.StorableAPIKeyUser, error) { - orgUserAPIKeys := new(types.OrgUserAPIKey) +func (store *store) ListAPIKeys(ctx context.Context, orgID valuer.UUID) ([]*usertypes.StorableAPIKeyUser, error) { + orgUserAPIKeys := new(usertypes.OrgUserAPIKey) if err := store.sqlstore.BunDB().NewSelect(). Model(orgUserAPIKeys). @@ -502,7 +503,7 @@ func (store *store) ListAPIKeys(ctx context.Context, orgID valuer.UUID) ([]*type } // Flatten the API keys from all users - var allAPIKeys []*types.StorableAPIKeyUser + var allAPIKeys []*usertypes.StorableAPIKeyUser for _, user := range orgUserAPIKeys.Users { if user.APIKeys != nil { allAPIKeys = append(allAPIKeys, user.APIKeys...) @@ -520,7 +521,7 @@ func (store *store) ListAPIKeys(ctx context.Context, orgID valuer.UUID) ([]*type func (store *store) RevokeAPIKey(ctx context.Context, id, revokedByUserID valuer.UUID) error { updatedAt := time.Now().Unix() _, err := store.sqlstore.BunDB().NewUpdate(). - Model(&types.StorableAPIKey{}). + Model(&usertypes.StorableAPIKey{}). Set("revoked = ?", true). Set("updated_by = ?", revokedByUserID). Set("updated_at = ?", updatedAt). @@ -532,8 +533,8 @@ func (store *store) RevokeAPIKey(ctx context.Context, id, revokedByUserID valuer return nil } -func (store *store) GetAPIKey(ctx context.Context, orgID, id valuer.UUID) (*types.StorableAPIKeyUser, error) { - apiKey := new(types.OrgUserAPIKey) +func (store *store) GetAPIKey(ctx context.Context, orgID, id valuer.UUID) (*usertypes.StorableAPIKeyUser, error) { + apiKey := new(usertypes.OrgUserAPIKey) if err := store.sqlstore.BunDB().NewSelect(). Model(apiKey). Relation("Users"). @@ -545,25 +546,25 @@ func (store *store) GetAPIKey(ctx context.Context, orgID, id valuer.UUID) (*type Relation("Users.APIKeys.CreatedByUser"). Relation("Users.APIKeys.UpdatedByUser"). Scan(ctx); err != nil { - return nil, store.sqlstore.WrapNotFoundErrf(err, types.ErrAPIKeyNotFound, "API key with id: %s does not exist", id) + return nil, store.sqlstore.WrapNotFoundErrf(err, usertypes.ErrAPIKeyNotFound, "API key with id: %s does not exist", id) } // flatten the API keys - flattenedAPIKeys := []*types.StorableAPIKeyUser{} + flattenedAPIKeys := []*usertypes.StorableAPIKeyUser{} for _, user := range apiKey.Users { if user.APIKeys != nil { flattenedAPIKeys = append(flattenedAPIKeys, user.APIKeys...) } } if len(flattenedAPIKeys) == 0 { - return nil, store.sqlstore.WrapNotFoundErrf(errors.New(errors.TypeNotFound, errors.CodeNotFound, "API key with id: %s does not exist"), types.ErrAPIKeyNotFound, "API key with id: %s does not exist", id) + return nil, store.sqlstore.WrapNotFoundErrf(errors.New(errors.TypeNotFound, errors.CodeNotFound, "API key with id: %s does not exist"), usertypes.ErrAPIKeyNotFound, "API key with id: %s does not exist", id) } return flattenedAPIKeys[0], nil } func (store *store) CountByOrgID(ctx context.Context, orgID valuer.UUID) (int64, error) { - user := new(types.User) + user := new(usertypes.User) count, err := store. sqlstore. @@ -580,7 +581,7 @@ func (store *store) CountByOrgID(ctx context.Context, orgID valuer.UUID) (int64, } func (store *store) CountByOrgIDAndStatuses(ctx context.Context, orgID valuer.UUID, statuses []string) (map[valuer.String]int64, error) { - user := new(types.User) + user := new(usertypes.User) var results []struct { Status valuer.String `bun:"status"` Count int64 `bun:"count"` @@ -610,7 +611,7 @@ func (store *store) CountByOrgIDAndStatuses(ctx context.Context, orgID valuer.UU } func (store *store) CountAPIKeyByOrgID(ctx context.Context, orgID valuer.UUID) (int64, error) { - apiKey := new(types.StorableAPIKey) + apiKey := new(usertypes.StorableAPIKey) count, err := store. sqlstore. @@ -633,8 +634,8 @@ func (store *store) RunInTx(ctx context.Context, cb func(ctx context.Context) er }) } -func (store *store) GetRootUserByOrgID(ctx context.Context, orgID valuer.UUID) (*types.User, error) { - user := new(types.User) +func (store *store) GetRootUserByOrgID(ctx context.Context, orgID valuer.UUID) (*usertypes.User, error) { + user := new(usertypes.User) err := store. sqlstore. BunDBCtx(ctx). @@ -644,13 +645,13 @@ func (store *store) GetRootUserByOrgID(ctx context.Context, orgID valuer.UUID) ( Where("is_root = ?", true). Scan(ctx) if err != nil { - return nil, store.sqlstore.WrapNotFoundErrf(err, types.ErrCodeUserNotFound, "root user for org %s not found", orgID) + return nil, store.sqlstore.WrapNotFoundErrf(err, usertypes.ErrCodeUserNotFound, "root user for org %s not found", orgID) } return user, nil } -func (store *store) ListUsersByEmailAndOrgIDs(ctx context.Context, email valuer.Email, orgIDs []valuer.UUID) ([]*types.User, error) { - users := []*types.User{} +func (store *store) ListUsersByEmailAndOrgIDs(ctx context.Context, email valuer.Email, orgIDs []valuer.UUID) ([]*usertypes.User, error) { + users := []*usertypes.User{} err := store. sqlstore. BunDB(). @@ -666,8 +667,8 @@ func (store *store) ListUsersByEmailAndOrgIDs(ctx context.Context, email valuer. return users, nil } -func (store *store) GetUserByResetPasswordToken(ctx context.Context, token string) (*types.User, error) { - user := new(types.User) +func (store *store) GetUserByResetPasswordToken(ctx context.Context, token string) (*usertypes.User, error) { + user := new(usertypes.User) err := store. sqlstore. @@ -679,14 +680,14 @@ func (store *store) GetUserByResetPasswordToken(ctx context.Context, token strin Where("reset_password_token.token = ?", token). Scan(ctx) if err != nil { - return nil, store.sqlstore.WrapNotFoundErrf(err, types.ErrCodeUserNotFound, "user not found for reset password token") + return nil, store.sqlstore.WrapNotFoundErrf(err, usertypes.ErrCodeUserNotFound, "user not found for reset password token") } return user, nil } -func (store *store) GetUsersByEmailsOrgIDAndStatuses(ctx context.Context, orgID valuer.UUID, emails []string, statuses []string) ([]*types.User, error) { - users := []*types.User{} +func (store *store) GetUsersByEmailsOrgIDAndStatuses(ctx context.Context, orgID valuer.UUID, emails []string, statuses []string) ([]*usertypes.User, error) { + users := []*usertypes.User{} err := store. sqlstore. diff --git a/pkg/modules/user/option.go b/pkg/modules/user/option.go index 3d17146fb9..b44ef41138 100644 --- a/pkg/modules/user/option.go +++ b/pkg/modules/user/option.go @@ -1,17 +1,17 @@ package user import ( - "github.com/SigNoz/signoz/pkg/types" + "github.com/SigNoz/signoz/pkg/types/usertypes" "github.com/SigNoz/signoz/pkg/valuer" ) type createUserOptions struct { - FactorPassword *types.FactorPassword + FactorPassword *usertypes.FactorPassword } type CreateUserOption func(*createUserOptions) -func WithFactorPassword(factorPassword *types.FactorPassword) CreateUserOption { +func WithFactorPassword(factorPassword *usertypes.FactorPassword) CreateUserOption { return func(o *createUserOptions) { o.FactorPassword = factorPassword } diff --git a/pkg/modules/user/user.go b/pkg/modules/user/user.go index 820b7fd319..6f65fc9086 100644 --- a/pkg/modules/user/user.go +++ b/pkg/modules/user/user.go @@ -6,22 +6,23 @@ import ( "github.com/SigNoz/signoz/pkg/statsreporter" "github.com/SigNoz/signoz/pkg/types" + "github.com/SigNoz/signoz/pkg/types/usertypes" "github.com/SigNoz/signoz/pkg/valuer" ) type Module interface { // Creates the organization and the first user of that organization. - CreateFirstUser(ctx context.Context, organization *types.Organization, name string, email valuer.Email, password string) (*types.User, error) + CreateFirstUser(ctx context.Context, organization *types.Organization, name string, email valuer.Email, password string) (*usertypes.User, error) // Creates a user and sends an analytics event. - CreateUser(ctx context.Context, user *types.User, opts ...CreateUserOption) error + CreateUser(ctx context.Context, user *usertypes.User, opts ...CreateUserOption) error // Get or create a user. If a user with the same email and orgID already exists, it returns the existing user. - GetOrCreateUser(ctx context.Context, user *types.User, opts ...CreateUserOption) (*types.User, error) + GetOrCreateUser(ctx context.Context, user *usertypes.User, opts ...CreateUserOption) (*usertypes.User, error) // Get or Create a reset password token for a user. If the password does not exist, a new one is randomly generated and inserted. The function // is idempotent and can be called multiple times. - GetOrCreateResetPasswordToken(ctx context.Context, userID valuer.UUID) (*types.ResetPasswordToken, error) + GetOrCreateResetPasswordToken(ctx context.Context, userID valuer.UUID) (*usertypes.ResetPasswordToken, error) // Updates password of a user using a reset password token. It also deletes all reset password tokens for the user. // This is used to reset the password of a user when they forget their password. @@ -33,48 +34,48 @@ type Module interface { // Initiate forgot password flow for a user ForgotPassword(ctx context.Context, orgID valuer.UUID, email valuer.Email, frontendBaseURL string) error - UpdateUser(ctx context.Context, orgID valuer.UUID, id string, user *types.User, updatedBy string) (*types.User, error) + UpdateUser(ctx context.Context, orgID valuer.UUID, id string, user *usertypes.User, updatedBy string) (*usertypes.User, error) // UpdateAnyUser updates a user and persists the changes to the database along with the analytics and identity deletion. - UpdateAnyUser(ctx context.Context, orgID valuer.UUID, user *types.User) error + UpdateAnyUser(ctx context.Context, orgID valuer.UUID, user *usertypes.User) error DeleteUser(ctx context.Context, orgID valuer.UUID, id string, deletedBy string) error // invite - CreateBulkInvite(ctx context.Context, orgID valuer.UUID, userID valuer.UUID, bulkInvites *types.PostableBulkInviteRequest) ([]*types.Invite, error) - ListInvite(ctx context.Context, orgID string) ([]*types.Invite, error) - AcceptInvite(ctx context.Context, token string, password string) (*types.User, error) - GetInviteByToken(ctx context.Context, token string) (*types.Invite, error) + CreateBulkInvite(ctx context.Context, orgID valuer.UUID, userID valuer.UUID, bulkInvites *usertypes.PostableBulkInviteRequest) ([]*usertypes.Invite, error) + ListInvite(ctx context.Context, orgID string) ([]*usertypes.Invite, error) + AcceptInvite(ctx context.Context, token string, password string) (*usertypes.User, error) + GetInviteByToken(ctx context.Context, token string) (*usertypes.Invite, error) // API KEY - CreateAPIKey(ctx context.Context, apiKey *types.StorableAPIKey) error - UpdateAPIKey(ctx context.Context, id valuer.UUID, apiKey *types.StorableAPIKey, updaterID valuer.UUID) error - ListAPIKeys(ctx context.Context, orgID valuer.UUID) ([]*types.StorableAPIKeyUser, error) + CreateAPIKey(ctx context.Context, apiKey *usertypes.StorableAPIKey) error + UpdateAPIKey(ctx context.Context, id valuer.UUID, apiKey *usertypes.StorableAPIKey, updaterID valuer.UUID) error + ListAPIKeys(ctx context.Context, orgID valuer.UUID) ([]*usertypes.StorableAPIKeyUser, error) RevokeAPIKey(ctx context.Context, id, removedByUserID valuer.UUID) error - GetAPIKey(ctx context.Context, orgID valuer.UUID, id valuer.UUID) (*types.StorableAPIKeyUser, error) + GetAPIKey(ctx context.Context, orgID valuer.UUID, id valuer.UUID) (*usertypes.StorableAPIKeyUser, error) - GetNonDeletedUserByEmailAndOrgID(ctx context.Context, email valuer.Email, orgID valuer.UUID) (*types.User, error) + GetNonDeletedUserByEmailAndOrgID(ctx context.Context, email valuer.Email, orgID valuer.UUID) (*usertypes.User, error) statsreporter.StatsCollector } type Getter interface { // Get root user by org id. - GetRootUserByOrgID(context.Context, valuer.UUID) (*types.User, error) + GetRootUserByOrgID(context.Context, valuer.UUID) (*usertypes.User, error) // Get gets the users based on the given id - ListByOrgID(context.Context, valuer.UUID) ([]*types.User, error) + ListByOrgID(context.Context, valuer.UUID) ([]*usertypes.User, error) // Get users by email. - GetUsersByEmail(context.Context, valuer.Email) ([]*types.User, error) + GetUsersByEmail(context.Context, valuer.Email) ([]*usertypes.User, error) // Get user by orgID and id. - GetByOrgIDAndID(context.Context, valuer.UUID, valuer.UUID) (*types.User, error) + GetByOrgIDAndID(context.Context, valuer.UUID, valuer.UUID) (*usertypes.User, error) // Get user by id. - Get(context.Context, valuer.UUID) (*types.User, error) + Get(context.Context, valuer.UUID) (*usertypes.User, error) // List users by email and org ids. - ListUsersByEmailAndOrgIDs(context.Context, valuer.Email, []valuer.UUID) ([]*types.User, error) + ListUsersByEmailAndOrgIDs(context.Context, valuer.Email, []valuer.UUID) ([]*usertypes.User, error) // Count users by org id. CountByOrgID(context.Context, valuer.UUID) (int64, error) @@ -83,7 +84,7 @@ type Getter interface { CountByOrgIDAndStatuses(context.Context, valuer.UUID, []string) (map[valuer.String]int64, error) // Get factor password by user id. - GetFactorPasswordByUserID(context.Context, valuer.UUID) (*types.FactorPassword, error) + GetFactorPasswordByUserID(context.Context, valuer.UUID) (*usertypes.FactorPassword, error) } type Handler interface { diff --git a/pkg/query-service/app/http_handler.go b/pkg/query-service/app/http_handler.go index 7f4b04a2b5..33eb41f794 100644 --- a/pkg/query-service/app/http_handler.go +++ b/pkg/query-service/app/http_handler.go @@ -73,6 +73,7 @@ import ( qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5" "github.com/SigNoz/signoz/pkg/types/ruletypes" traceFunnels "github.com/SigNoz/signoz/pkg/types/tracefunneltypes" + "github.com/SigNoz/signoz/pkg/types/usertypes" "github.com/SigNoz/signoz/pkg/query-service/app/integrations/messagingQueues/kafka" "github.com/SigNoz/signoz/pkg/query-service/app/logparsingpipeline" @@ -2034,7 +2035,7 @@ func (aH *APIHandler) registerUser(w http.ResponseWriter, r *http.Request) { return } - var req types.PostableRegisterOrgAndAdmin + var req usertypes.PostableRegisterOrgAndAdmin if err := json.NewDecoder(r.Body).Decode(&req); err != nil { render.Error(w, err) return diff --git a/pkg/sqlmigration/037_add_trace_funnels.go b/pkg/sqlmigration/037_add_trace_funnels.go index 99a885b1cf..5beb8a8a7c 100644 --- a/pkg/sqlmigration/037_add_trace_funnels.go +++ b/pkg/sqlmigration/037_add_trace_funnels.go @@ -2,9 +2,11 @@ package sqlmigration import ( "context" + "github.com/SigNoz/signoz/pkg/factory" "github.com/SigNoz/signoz/pkg/sqlstore" "github.com/SigNoz/signoz/pkg/types" + "github.com/SigNoz/signoz/pkg/types/usertypes" "github.com/SigNoz/signoz/pkg/valuer" "github.com/uptrace/bun" "github.com/uptrace/bun/migrate" @@ -16,12 +18,12 @@ type funnel struct { types.Identifiable // funnel id types.TimeAuditable types.UserAuditable - Name string `json:"funnel_name" bun:"name,type:text,notnull"` // funnel name - Description string `json:"description" bun:"description,type:text"` // funnel description - OrgID valuer.UUID `json:"org_id" bun:"org_id,type:varchar,notnull"` - Steps []funnelStep `json:"steps" bun:"steps,type:text,notnull"` - Tags string `json:"tags" bun:"tags,type:text"` - CreatedByUser *types.User `json:"user" bun:"rel:belongs-to,join:created_by=id"` + Name string `json:"funnel_name" bun:"name,type:text,notnull"` // funnel name + Description string `json:"description" bun:"description,type:text"` // funnel description + OrgID valuer.UUID `json:"org_id" bun:"org_id,type:varchar,notnull"` + Steps []funnelStep `json:"steps" bun:"steps,type:text,notnull"` + Tags string `json:"tags" bun:"tags,type:text"` + CreatedByUser *usertypes.User `json:"user" bun:"rel:belongs-to,join:created_by=id"` } type funnelStep struct { diff --git a/pkg/statsreporter/analyticsstatsreporter/provider.go b/pkg/statsreporter/analyticsstatsreporter/provider.go index 69395b1302..8c8987962f 100644 --- a/pkg/statsreporter/analyticsstatsreporter/provider.go +++ b/pkg/statsreporter/analyticsstatsreporter/provider.go @@ -13,9 +13,9 @@ import ( "github.com/SigNoz/signoz/pkg/statsreporter" "github.com/SigNoz/signoz/pkg/telemetrystore" "github.com/SigNoz/signoz/pkg/tokenizer" - "github.com/SigNoz/signoz/pkg/types" "github.com/SigNoz/signoz/pkg/types/ctxtypes" "github.com/SigNoz/signoz/pkg/types/instrumentationtypes" + "github.com/SigNoz/signoz/pkg/types/usertypes" "github.com/SigNoz/signoz/pkg/valuer" "github.com/SigNoz/signoz/pkg/version" "go.opentelemetry.io/otel/attribute" @@ -175,7 +175,7 @@ func (provider *provider) Report(ctx context.Context) error { } for _, user := range users { - traits := types.NewTraitsFromUser(user) + traits := usertypes.NewTraitsFromUser(user) if maxLastObservedAt, ok := maxLastObservedAtPerUserID[user.ID]; ok { traits["auth_token.last_observed_at.max.time"] = maxLastObservedAt.UTC() traits["auth_token.last_observed_at.max.time_unix"] = maxLastObservedAt.Unix() diff --git a/pkg/tokenizer/jwttokenizer/claims.go b/pkg/tokenizer/jwttokenizer/claims.go index dfa39959cb..2bf37e9eb7 100644 --- a/pkg/tokenizer/jwttokenizer/claims.go +++ b/pkg/tokenizer/jwttokenizer/claims.go @@ -10,10 +10,10 @@ var _ jwt.ClaimsValidator = (*Claims)(nil) type Claims struct { jwt.RegisteredClaims - UserID string `json:"id"` - Email string `json:"email"` - Role types.Role `json:"role"` - OrgID string `json:"orgId"` + UserID string `json:"id"` + Email string `json:"email"` + Role types.LegacyRole `json:"role"` + OrgID string `json:"orgId"` } func (c *Claims) Validate() error { diff --git a/pkg/tokenizer/tokenizerstore/sqltokenizerstore/store.go b/pkg/tokenizer/tokenizerstore/sqltokenizerstore/store.go index 802f45ada1..a647977b37 100644 --- a/pkg/tokenizer/tokenizerstore/sqltokenizerstore/store.go +++ b/pkg/tokenizer/tokenizerstore/sqltokenizerstore/store.go @@ -6,6 +6,7 @@ import ( "github.com/SigNoz/signoz/pkg/sqlstore" "github.com/SigNoz/signoz/pkg/types" "github.com/SigNoz/signoz/pkg/types/authtypes" + "github.com/SigNoz/signoz/pkg/types/usertypes" "github.com/SigNoz/signoz/pkg/valuer" "github.com/uptrace/bun" "github.com/uptrace/bun/dialect" @@ -34,7 +35,7 @@ func (store *store) Create(ctx context.Context, token *authtypes.StorableToken) } func (store *store) GetIdentityByUserID(ctx context.Context, userID valuer.UUID) (*authtypes.Identity, error) { - user := new(types.User) + user := new(usertypes.User) err := store. sqlstore. @@ -44,10 +45,10 @@ func (store *store) GetIdentityByUserID(ctx context.Context, userID valuer.UUID) Where("id = ?", userID). Scan(ctx) if err != nil { - return nil, store.sqlstore.WrapNotFoundErrf(err, types.ErrCodeUserNotFound, "user with id: %s does not exist", userID) + return nil, store.sqlstore.WrapNotFoundErrf(err, usertypes.ErrCodeUserNotFound, "user with id: %s does not exist", userID) } - return authtypes.NewIdentity(userID, user.OrgID, user.Email, types.Role(user.Role), authtypes.IdentNProviderTokenizer), nil + return authtypes.NewIdentity(userID, user.OrgID, user.Email, types.LegacyRole(user.Role), authtypes.IdentNProviderTokenizer), nil } func (store *store) GetByAccessToken(ctx context.Context, accessToken string) (*authtypes.StorableToken, error) { diff --git a/pkg/types/authtypes/authn.go b/pkg/types/authtypes/authn.go index da3e9576a2..9f0c6cc85f 100644 --- a/pkg/types/authtypes/authn.go +++ b/pkg/types/authtypes/authn.go @@ -8,6 +8,7 @@ import ( "github.com/SigNoz/signoz/pkg/errors" "github.com/SigNoz/signoz/pkg/types" + "github.com/SigNoz/signoz/pkg/types/usertypes" "github.com/SigNoz/signoz/pkg/valuer" ) @@ -25,11 +26,11 @@ var ( type AuthNProvider struct{ valuer.String } type Identity struct { - UserID valuer.UUID `json:"userId"` - OrgID valuer.UUID `json:"orgId"` - IdenNProvider IdentNProvider `json:"identNProvider"` - Email valuer.Email `json:"email"` - Role types.Role `json:"role"` + UserID valuer.UUID `json:"userId"` + OrgID valuer.UUID `json:"orgId"` + IdenNProvider IdentNProvider `json:"identNProvider"` + Email valuer.Email `json:"email"` + Role types.LegacyRole `json:"role"` } type CallbackIdentity struct { @@ -79,7 +80,7 @@ func NewStateFromString(state string) (State, error) { }, nil } -func NewIdentity(userID valuer.UUID, orgID valuer.UUID, email valuer.Email, role types.Role, identNProvider IdentNProvider) *Identity { +func NewIdentity(userID valuer.UUID, orgID valuer.UUID, email valuer.Email, role types.LegacyRole, identNProvider IdentNProvider) *Identity { return &Identity{ UserID: userID, OrgID: orgID, @@ -128,7 +129,7 @@ func (typ *Identity) ToClaims() Claims { type AuthNStore interface { // Get user and factor password by email and orgID. - GetActiveUserAndFactorPasswordByEmailAndOrgID(ctx context.Context, email string, orgID valuer.UUID) (*types.User, *types.FactorPassword, error) + GetActiveUserAndFactorPasswordByEmailAndOrgID(ctx context.Context, email string, orgID valuer.UUID) (*usertypes.User, *usertypes.FactorPassword, error) // Get org domain from id. GetAuthDomainFromID(ctx context.Context, domainID valuer.UUID) (*AuthDomain, error) diff --git a/pkg/types/authtypes/claims.go b/pkg/types/authtypes/claims.go index bd06b64dcb..72942f3f71 100644 --- a/pkg/types/authtypes/claims.go +++ b/pkg/types/authtypes/claims.go @@ -15,7 +15,7 @@ type accessTokenKey struct{} type Claims struct { UserID string Email string - Role types.Role + Role types.LegacyRole OrgID string IdentNProvider string } @@ -59,7 +59,7 @@ func (c *Claims) LogValue() slog.Value { } func (c *Claims) IsViewer() error { - if slices.Contains([]types.Role{types.RoleViewer, types.RoleEditor, types.RoleAdmin}, c.Role) { + if slices.Contains([]types.LegacyRole{types.RoleViewer, types.RoleEditor, types.RoleAdmin}, c.Role) { return nil } @@ -67,7 +67,7 @@ func (c *Claims) IsViewer() error { } func (c *Claims) IsEditor() error { - if slices.Contains([]types.Role{types.RoleEditor, types.RoleAdmin}, c.Role) { + if slices.Contains([]types.LegacyRole{types.RoleEditor, types.RoleAdmin}, c.Role) { return nil } diff --git a/pkg/types/authtypes/mapping.go b/pkg/types/authtypes/mapping.go index 1702eb7894..747068f9bb 100644 --- a/pkg/types/authtypes/mapping.go +++ b/pkg/types/authtypes/mapping.go @@ -83,7 +83,7 @@ func (typ *RoleMapping) UnmarshalJSON(data []byte) error { return nil } -func (roleMapping *RoleMapping) NewRoleFromCallbackIdentity(callbackIdentity *CallbackIdentity) types.Role { +func (roleMapping *RoleMapping) NewRoleFromCallbackIdentity(callbackIdentity *CallbackIdentity) types.LegacyRole { if roleMapping == nil { return types.RoleViewer } @@ -123,8 +123,8 @@ func (roleMapping *RoleMapping) NewRoleFromCallbackIdentity(callbackIdentity *Ca return types.RoleViewer } -func compareRoles(a, b types.Role) int { - order := map[types.Role]int{ +func compareRoles(a, b types.LegacyRole) int { + order := map[types.LegacyRole]int{ types.RoleViewer: 0, types.RoleEditor: 1, types.RoleAdmin: 2, diff --git a/pkg/types/dashboardtypes/dashboard.go b/pkg/types/dashboardtypes/dashboard.go index fb60d7681b..835309ea66 100644 --- a/pkg/types/dashboardtypes/dashboard.go +++ b/pkg/types/dashboardtypes/dashboard.go @@ -284,14 +284,14 @@ func (dashboard *Dashboard) Update(ctx context.Context, updatableDashboard Updat return nil } -func (dashboard *Dashboard) CanLockUnlock(role types.Role, updatedBy string) error { +func (dashboard *Dashboard) CanLockUnlock(role types.LegacyRole, updatedBy string) error { if dashboard.CreatedBy != updatedBy && role != types.RoleAdmin { return errors.Newf(errors.TypeForbidden, errors.CodeForbidden, "you are not authorized to lock/unlock this dashboard") } return nil } -func (dashboard *Dashboard) LockUnlock(lock bool, role types.Role, updatedBy string) error { +func (dashboard *Dashboard) LockUnlock(lock bool, role types.LegacyRole, updatedBy string) error { err := dashboard.CanLockUnlock(role, updatedBy) if err != nil { return err diff --git a/pkg/types/role.go b/pkg/types/role.go index 959939bb7c..4795198a60 100644 --- a/pkg/types/role.go +++ b/pkg/types/role.go @@ -7,15 +7,15 @@ import ( ) // Do not take inspiration from this. This is a hack to avoid using valuer.String and use upper case strings. -type Role string +type LegacyRole string const ( - RoleAdmin Role = "ADMIN" - RoleEditor Role = "EDITOR" - RoleViewer Role = "VIEWER" + RoleAdmin LegacyRole = "ADMIN" + RoleEditor LegacyRole = "EDITOR" + RoleViewer LegacyRole = "VIEWER" ) -func NewRole(role string) (Role, error) { +func NewRole(role string) (LegacyRole, error) { switch role { case "ADMIN": return RoleAdmin, nil @@ -28,11 +28,11 @@ func NewRole(role string) (Role, error) { return "", errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "invalid role: %s", role) } -func (r Role) String() string { +func (r LegacyRole) String() string { return string(r) } -func (r *Role) UnmarshalJSON(data []byte) error { +func (r *LegacyRole) UnmarshalJSON(data []byte) error { var s string if err := json.Unmarshal(data, &s); err != nil { return err @@ -47,6 +47,6 @@ func (r *Role) UnmarshalJSON(data []byte) error { return nil } -func (r Role) MarshalJSON() ([]byte, error) { +func (r LegacyRole) MarshalJSON() ([]byte, error) { return json.Marshal(r.String()) } diff --git a/pkg/types/roletypes/role.go b/pkg/types/roletypes/role.go index 10b4c6ae67..7aed95d698 100644 --- a/pkg/types/roletypes/role.go +++ b/pkg/types/roletypes/role.go @@ -43,7 +43,7 @@ var ( ) var ( - ExistingRoleToSigNozManagedRoleMap = map[types.Role]string{ + ExistingRoleToSigNozManagedRoleMap = map[types.LegacyRole]string{ types.RoleAdmin: SigNozAdminRoleName, types.RoleEditor: SigNozEditorRoleName, types.RoleViewer: SigNozViewerRoleName, @@ -246,7 +246,7 @@ func GetDeletionTuples(name string, orgID valuer.UUID, relation authtypes.Relati return tuples, nil } -func MustGetSigNozManagedRoleFromExistingRole(role types.Role) string { +func MustGetSigNozManagedRoleFromExistingRole(role types.LegacyRole) string { managedRole, ok := ExistingRoleToSigNozManagedRoleMap[role] if !ok { panic(errors.Newf(errors.TypeInternal, errors.CodeInternal, "invalid role: %s", role.String())) diff --git a/pkg/types/tracefunneltypes/tracefunnel.go b/pkg/types/tracefunneltypes/tracefunnel.go index 4eb725e379..ec5fb72b36 100644 --- a/pkg/types/tracefunneltypes/tracefunnel.go +++ b/pkg/types/tracefunneltypes/tracefunnel.go @@ -4,6 +4,7 @@ import ( "github.com/SigNoz/signoz/pkg/errors" v3 "github.com/SigNoz/signoz/pkg/query-service/model/v3" "github.com/SigNoz/signoz/pkg/types" + "github.com/SigNoz/signoz/pkg/types/usertypes" "github.com/SigNoz/signoz/pkg/valuer" "github.com/uptrace/bun" ) @@ -18,12 +19,12 @@ type StorableFunnel struct { types.TimeAuditable types.UserAuditable bun.BaseModel `bun:"table:trace_funnel"` - Name string `json:"funnel_name" bun:"name,type:text,notnull"` - Description string `json:"description" bun:"description,type:text"` - OrgID valuer.UUID `json:"org_id" bun:"org_id,type:varchar,notnull"` - Steps []*FunnelStep `json:"steps" bun:"steps,type:text,notnull"` - Tags string `json:"tags" bun:"tags,type:text"` - CreatedByUser *types.User `json:"user" bun:"rel:belongs-to,join:created_by=id"` + Name string `json:"funnel_name" bun:"name,type:text,notnull"` + Description string `json:"description" bun:"description,type:text"` + OrgID valuer.UUID `json:"org_id" bun:"org_id,type:varchar,notnull"` + Steps []*FunnelStep `json:"steps" bun:"steps,type:text,notnull"` + Tags string `json:"tags" bun:"tags,type:text"` + CreatedByUser *usertypes.User `json:"user" bun:"rel:belongs-to,join:created_by=id"` } type FunnelStep struct { diff --git a/pkg/types/tracefunneltypes/utils_test.go b/pkg/types/tracefunneltypes/utils_test.go index 44cac5b259..7b698a5bcb 100644 --- a/pkg/types/tracefunneltypes/utils_test.go +++ b/pkg/types/tracefunneltypes/utils_test.go @@ -6,6 +6,7 @@ import ( "github.com/SigNoz/signoz/pkg/types" "github.com/SigNoz/signoz/pkg/types/authtypes" + "github.com/SigNoz/signoz/pkg/types/usertypes" "github.com/SigNoz/signoz/pkg/valuer" "github.com/stretchr/testify/assert" ) @@ -443,7 +444,7 @@ func TestConstructFunnelResponse(t *testing.T) { }, Name: "test-funnel", OrgID: orgID, - CreatedByUser: &types.User{ + CreatedByUser: &usertypes.User{ Identifiable: types.Identifiable{ ID: userID, }, diff --git a/pkg/types/factor_api_key.go b/pkg/types/usertypes/factor_api_key.go similarity index 63% rename from pkg/types/factor_api_key.go rename to pkg/types/usertypes/factor_api_key.go index e1eb05db69..11158333f4 100644 --- a/pkg/types/factor_api_key.go +++ b/pkg/types/usertypes/factor_api_key.go @@ -1,4 +1,4 @@ -package types +package usertypes import ( "crypto/rand" @@ -6,6 +6,7 @@ import ( "time" "github.com/SigNoz/signoz/pkg/errors" + "github.com/SigNoz/signoz/pkg/types" "github.com/SigNoz/signoz/pkg/valuer" "github.com/uptrace/bun" ) @@ -13,29 +14,29 @@ import ( var NEVER_EXPIRES = time.Unix(0, 0) type PostableAPIKey struct { - Name string `json:"name"` - Role Role `json:"role"` - ExpiresInDays int64 `json:"expiresInDays"` + Name string `json:"name"` + Role types.LegacyRole `json:"role"` + ExpiresInDays int64 `json:"expiresInDays"` } type GettableAPIKey struct { - Identifiable - TimeAuditable - UserAuditable - Token string `json:"token"` - Role Role `json:"role"` - Name string `json:"name"` - ExpiresAt int64 `json:"expiresAt"` - LastUsed int64 `json:"lastUsed"` - Revoked bool `json:"revoked"` - UserID string `json:"userId"` - CreatedByUser *User `json:"createdByUser"` - UpdatedByUser *User `json:"updatedByUser"` + types.Identifiable + types.TimeAuditable + types.UserAuditable + Token string `json:"token"` + Role types.LegacyRole `json:"role"` + Name string `json:"name"` + ExpiresAt int64 `json:"expiresAt"` + LastUsed int64 `json:"lastUsed"` + Revoked bool `json:"revoked"` + UserID string `json:"userId"` + CreatedByUser *User `json:"createdByUser"` + UpdatedByUser *User `json:"updatedByUser"` } type OrgUserAPIKey struct { - *Organization `bun:",extend"` - Users []*UserWithAPIKey `bun:"rel:has-many,join:id=org_id"` + *types.Organization `bun:",extend"` + Users []*UserWithAPIKey `bun:"rel:has-many,join:id=org_id"` } type UserWithAPIKey struct { @@ -53,19 +54,19 @@ type StorableAPIKeyUser struct { type StorableAPIKey struct { bun.BaseModel `bun:"table:factor_api_key"` - Identifiable - TimeAuditable - UserAuditable - Token string `json:"token" bun:"token,type:text,notnull,unique"` - Role Role `json:"role" bun:"role,type:text,notnull,default:'ADMIN'"` - Name string `json:"name" bun:"name,type:text,notnull"` - ExpiresAt time.Time `json:"-" bun:"expires_at,notnull,nullzero,type:timestamptz"` - LastUsed time.Time `json:"-" bun:"last_used,notnull,nullzero,type:timestamptz"` - Revoked bool `json:"revoked" bun:"revoked,notnull,default:false"` - UserID valuer.UUID `json:"userId" bun:"user_id,type:text,notnull"` + types.Identifiable + types.TimeAuditable + types.UserAuditable + Token string `json:"token" bun:"token,type:text,notnull,unique"` + Role types.LegacyRole `json:"role" bun:"role,type:text,notnull,default:'ADMIN'"` + Name string `json:"name" bun:"name,type:text,notnull"` + ExpiresAt time.Time `json:"-" bun:"expires_at,notnull,nullzero,type:timestamptz"` + LastUsed time.Time `json:"-" bun:"last_used,notnull,nullzero,type:timestamptz"` + Revoked bool `json:"revoked" bun:"revoked,notnull,default:false"` + UserID valuer.UUID `json:"userId" bun:"user_id,type:text,notnull"` } -func NewStorableAPIKey(name string, userID valuer.UUID, role Role, expiresAt int64) (*StorableAPIKey, error) { +func NewStorableAPIKey(name string, userID valuer.UUID, role types.LegacyRole, expiresAt int64) (*StorableAPIKey, error) { // validate // we allow the APIKey if expiresAt is not set, which means it never expires @@ -101,14 +102,14 @@ func NewStorableAPIKey(name string, userID valuer.UUID, role Role, expiresAt int encodedToken := base64.StdEncoding.EncodeToString(token) return &StorableAPIKey{ - Identifiable: Identifiable{ + Identifiable: types.Identifiable{ ID: valuer.GenerateUUID(), }, - TimeAuditable: TimeAuditable{ + TimeAuditable: types.TimeAuditable{ CreatedAt: now, UpdatedAt: now, }, - UserAuditable: UserAuditable{ + UserAuditable: types.UserAuditable{ CreatedBy: userID.String(), UpdatedBy: userID.String(), }, diff --git a/pkg/types/factor_password.go b/pkg/types/usertypes/factor_password.go similarity index 96% rename from pkg/types/factor_password.go rename to pkg/types/usertypes/factor_password.go index a960339d63..56d1494eb0 100644 --- a/pkg/types/factor_password.go +++ b/pkg/types/usertypes/factor_password.go @@ -1,4 +1,4 @@ -package types +package usertypes import ( "encoding/json" @@ -8,6 +8,7 @@ import ( "unicode" "github.com/SigNoz/signoz/pkg/errors" + "github.com/SigNoz/signoz/pkg/types" "github.com/SigNoz/signoz/pkg/valuer" "github.com/sethvargo/go-password/password" "github.com/uptrace/bun" @@ -45,7 +46,7 @@ type PostableForgotPassword struct { type ResetPasswordToken struct { bun.BaseModel `bun:"table:reset_password_token"` - Identifiable + types.Identifiable Token string `bun:"token,type:text,notnull" json:"token"` PasswordID valuer.UUID `bun:"password_id,type:text,notnull,unique" json:"passwordId"` ExpiresAt time.Time `bun:"expires_at,type:timestamptz,nullzero" json:"expiresAt"` @@ -54,11 +55,11 @@ type ResetPasswordToken struct { type FactorPassword struct { bun.BaseModel `bun:"table:factor_password"` - Identifiable + types.Identifiable Password string `bun:"password,type:text,notnull" json:"password"` Temporary bool `bun:"temporary,type:boolean,notnull" json:"temporary"` UserID string `bun:"user_id,type:text,notnull,unique" json:"userId"` - TimeAuditable + types.TimeAuditable } func (request *ChangePasswordRequest) UnmarshalJSON(data []byte) error { @@ -104,13 +105,13 @@ func NewFactorPassword(password string, userID string) (*FactorPassword, error) } return &FactorPassword{ - Identifiable: Identifiable{ + Identifiable: types.Identifiable{ ID: valuer.GenerateUUID(), }, Password: string(hashedPassword), Temporary: false, UserID: userID, - TimeAuditable: TimeAuditable{ + TimeAuditable: types.TimeAuditable{ CreatedAt: time.Now(), UpdatedAt: time.Now(), }, @@ -146,7 +147,7 @@ func NewHashedPassword(password string) (string, error) { func NewResetPasswordToken(passwordID valuer.UUID, expiresAt time.Time) (*ResetPasswordToken, error) { return &ResetPasswordToken{ - Identifiable: Identifiable{ + Identifiable: types.Identifiable{ ID: valuer.GenerateUUID(), }, Token: valuer.GenerateUUID().String(), diff --git a/pkg/types/factor_password_test.go b/pkg/types/usertypes/factor_password_test.go similarity index 93% rename from pkg/types/factor_password_test.go rename to pkg/types/usertypes/factor_password_test.go index 5aad7ae649..f3d7aee114 100644 --- a/pkg/types/factor_password_test.go +++ b/pkg/types/usertypes/factor_password_test.go @@ -1,4 +1,4 @@ -package types +package usertypes import ( "testing" diff --git a/pkg/types/invite.go b/pkg/types/usertypes/invite.go similarity index 75% rename from pkg/types/invite.go rename to pkg/types/usertypes/invite.go index ce4179aa71..a83004a2b7 100644 --- a/pkg/types/invite.go +++ b/pkg/types/usertypes/invite.go @@ -1,10 +1,11 @@ -package types +package usertypes import ( "encoding/json" "time" "github.com/SigNoz/signoz/pkg/errors" + "github.com/SigNoz/signoz/pkg/types" "github.com/SigNoz/signoz/pkg/valuer" "github.com/uptrace/bun" ) @@ -19,13 +20,13 @@ type GettableInvite = Invite type Invite struct { bun.BaseModel `bun:"table:user_invite"` - Identifiable - TimeAuditable - Name string `bun:"name,type:text" json:"name"` - Email valuer.Email `bun:"email,type:text" json:"email"` - Token string `bun:"token,type:text" json:"token"` - Role Role `bun:"role,type:text" json:"role"` - OrgID valuer.UUID `bun:"org_id,type:text" json:"orgId"` + types.Identifiable + types.TimeAuditable + Name string `bun:"name,type:text" json:"name"` + Email valuer.Email `bun:"email,type:text" json:"email"` + Token string `bun:"token,type:text" json:"token"` + Role types.LegacyRole `bun:"role,type:text" json:"role"` + OrgID valuer.UUID `bun:"org_id,type:text" json:"orgId"` InviteLink string `bun:"-" json:"inviteLink"` } @@ -47,10 +48,10 @@ type PostableAcceptInvite struct { } type PostableInvite struct { - Name string `json:"name"` - Email valuer.Email `json:"email"` - Role Role `json:"role"` - FrontendBaseUrl string `json:"frontendBaseUrl"` + Name string `json:"name"` + Email valuer.Email `json:"email"` + Role types.LegacyRole `json:"role"` + FrontendBaseUrl string `json:"frontendBaseUrl"` } type PostableBulkInviteRequest struct { @@ -83,9 +84,9 @@ type GettableCreateInviteResponse struct { InviteToken string `json:"token"` } -func NewInvite(name string, role Role, orgID valuer.UUID, email valuer.Email) (*Invite, error) { +func NewInvite(name string, role types.LegacyRole, orgID valuer.UUID, email valuer.Email) (*Invite, error) { invite := &Invite{ - Identifiable: Identifiable{ + Identifiable: types.Identifiable{ ID: valuer.GenerateUUID(), }, Name: name, @@ -93,7 +94,7 @@ func NewInvite(name string, role Role, orgID valuer.UUID, email valuer.Email) (* Token: valuer.GenerateUUID().String(), Role: role, OrgID: orgID, - TimeAuditable: TimeAuditable{ + TimeAuditable: types.TimeAuditable{ CreatedAt: time.Now(), UpdatedAt: time.Now(), }, diff --git a/pkg/types/user.go b/pkg/types/usertypes/user.go similarity index 89% rename from pkg/types/user.go rename to pkg/types/usertypes/user.go index 4f8d53b66e..a3205b13d3 100644 --- a/pkg/types/user.go +++ b/pkg/types/usertypes/user.go @@ -1,4 +1,4 @@ -package types +package usertypes import ( "context" @@ -7,6 +7,7 @@ import ( "time" "github.com/SigNoz/signoz/pkg/errors" + "github.com/SigNoz/signoz/pkg/types" "github.com/SigNoz/signoz/pkg/valuer" "github.com/uptrace/bun" ) @@ -38,15 +39,15 @@ type GettableUser = User type User struct { bun.BaseModel `bun:"table:users"` - Identifiable - DisplayName string `bun:"display_name" json:"displayName"` - Email valuer.Email `bun:"email" json:"email"` - Role Role `bun:"role" json:"role"` - OrgID valuer.UUID `bun:"org_id" json:"orgId"` - IsRoot bool `bun:"is_root" json:"isRoot"` - Status valuer.String `bun:"status" json:"status"` - DeletedAt time.Time `bun:"deleted_at" json:"-"` - TimeAuditable + types.Identifiable + DisplayName string `bun:"display_name" json:"displayName"` + Email valuer.Email `bun:"email" json:"email"` + Role types.LegacyRole `bun:"role" json:"role"` + OrgID valuer.UUID `bun:"org_id" json:"orgId"` + IsRoot bool `bun:"is_root" json:"isRoot"` + Status valuer.String `bun:"status" json:"status"` + DeletedAt time.Time `bun:"deleted_at" json:"-"` + types.TimeAuditable } type PostableRegisterOrgAndAdmin struct { @@ -57,7 +58,7 @@ type PostableRegisterOrgAndAdmin struct { OrgName string `json:"orgName"` } -func NewUser(displayName string, email valuer.Email, role Role, orgID valuer.UUID, status valuer.String) (*User, error) { +func NewUser(displayName string, email valuer.Email, role types.LegacyRole, orgID valuer.UUID, status valuer.String) (*User, error) { if email.IsZero() { return nil, errors.New(errors.TypeInvalidInput, errors.CodeInvalidInput, "email is required") } @@ -75,7 +76,7 @@ func NewUser(displayName string, email valuer.Email, role Role, orgID valuer.UUI } return &User{ - Identifiable: Identifiable{ + Identifiable: types.Identifiable{ ID: valuer.GenerateUUID(), }, DisplayName: displayName, @@ -84,7 +85,7 @@ func NewUser(displayName string, email valuer.Email, role Role, orgID valuer.UUI OrgID: orgID, IsRoot: false, Status: status, - TimeAuditable: TimeAuditable{ + TimeAuditable: types.TimeAuditable{ CreatedAt: time.Now(), UpdatedAt: time.Now(), }, @@ -101,16 +102,16 @@ func NewRootUser(displayName string, email valuer.Email, orgID valuer.UUID) (*Us } return &User{ - Identifiable: Identifiable{ + Identifiable: types.Identifiable{ ID: valuer.GenerateUUID(), }, DisplayName: displayName, Email: email, - Role: RoleAdmin, + Role: types.RoleAdmin, OrgID: orgID, IsRoot: true, Status: UserStatusActive, - TimeAuditable: TimeAuditable{ + TimeAuditable: types.TimeAuditable{ CreatedAt: time.Now(), UpdatedAt: time.Now(), }, @@ -119,7 +120,7 @@ func NewRootUser(displayName string, email valuer.Email, orgID valuer.UUID) (*Us // Update applies mutable fields from the input to the user. Immutable fields // (email, is_root, org_id, id) are preserved. Only non-zero input fields are applied. -func (u *User) Update(displayName string, role Role) { +func (u *User) Update(displayName string, role types.LegacyRole) { if displayName != "" { u.DisplayName = displayName } @@ -149,7 +150,7 @@ func (u *User) UpdateStatus(status valuer.String) error { // PromoteToRoot promotes the user to a root user with admin role. func (u *User) PromoteToRoot() { u.IsRoot = true - u.Role = RoleAdmin + u.Role = types.RoleAdmin u.UpdatedAt = time.Now() } @@ -230,7 +231,7 @@ type UserStore interface { GetUsersByEmail(ctx context.Context, email valuer.Email) ([]*User, error) // Get users by role and org. - GetActiveUsersByRoleAndOrgID(ctx context.Context, role Role, orgID valuer.UUID) ([]*User, error) + GetActiveUsersByRoleAndOrgID(ctx context.Context, role types.LegacyRole, orgID valuer.UUID) ([]*User, error) // List users by org. ListUsersByOrgID(ctx context.Context, orgID valuer.UUID) ([]*User, error)