Rewrite the global id system to include tenant id

The API should be aware of the tenant they are working on. Many solution
is possible like passing a header, adding the tenant id in each function
call, encode the tenant id in the GID.

I consider the header as a hack it force the client to keep in mind to
pass this header, having to returns an error in case of not defined
header and add a non standard header make the API more harder to use.

Passing the tenant id everywhere will be a good option but since Relay
impose to have node(id: ID!) Node interface it is not possible or by
hacking by wrapping node(id: ID!) Node in top query who getting the
tenant_id.

I finish by simpliy encode the tenant id directly in the object id, it
what AWS do too, it allow to always have the information, and it ensure
a right data isolation.

Signed-off-by: gearnode <bryan@frimin.fr>
This commit is contained in:
gearnode
2025-03-10 13:54:55 +01:00
parent 06bab5061c
commit 58eda95d93
23 changed files with 676 additions and 299 deletions

View File

@@ -0,0 +1 @@
ALTER TABLE usrmgr_users DROP COLUMN organization_id;

View File

@@ -31,7 +31,6 @@ type (
EmailAddress string `db:"email_address"`
HashedPassword []byte `db:"hashed_password"`
FullName string `db:"fullname"`
OrganizationID gid.GID `db:"organization_id"`
CreatedAt time.Time `db:"created_at"`
UpdatedAt time.Time `db:"updated_at"`
}
@@ -52,7 +51,6 @@ SELECT
email_address,
hashed_password,
fullname,
organization_id,
created_at,
updated_at
FROM
@@ -90,7 +88,6 @@ SELECT
email_address,
hashed_password,
fullname,
organization_id,
created_at,
updated_at
FROM
@@ -123,13 +120,12 @@ func (u *User) Insert(
) error {
q := `
INSERT INTO
usrmgr_users (id, email_address, hashed_password, fullname, organization_id, created_at, updated_at)
usrmgr_users (id, email_address, hashed_password, fullname, created_at, updated_at)
VALUES (
@user_id,
@email_address,
@hashed_password,
@fullname,
@organization_id,
@created_at,
@updated_at
)
@@ -140,7 +136,6 @@ VALUES (
"email_address": u.EmailAddress,
"hashed_password": u.HashedPassword,
"fullname": u.FullName,
"organization_id": "AZSfP_xAcAC5IAAAAAAltA",
"created_at": u.CreatedAt,
"updated_at": u.UpdatedAt,
}

View File

@@ -109,7 +109,7 @@ func (s Service) RegisterUser(
now := time.Now()
user := &coredata.User{
ID: gid.New(),
ID: gid.New(gid.NilTenant, 0),
EmailAddress: params.Email,
HashedPassword: hashedPassword,
FullName: params.FullName,
@@ -151,8 +151,8 @@ func (s Service) Login(
now := time.Now()
user := &coredata.User{}
session := &coredata.Session{
ID: gid.New(),
UserID: gid.GID{}, // Will be set after user is loaded
ID: gid.New(gid.NilTenant, 0),
UserID: gid.Nil,
ExpiredAt: now.Add(24 * time.Hour),
CreatedAt: now,
UpdatedAt: now,
@@ -310,19 +310,6 @@ func (s Service) GetUserBySession(
return s.GetUserByID(ctx, session.UserID)
}
// GetUserOrganization gets the organization ID for a user
func (s Service) GetUserOrganization(
ctx context.Context,
userID gid.GID,
) (gid.GID, error) {
user, err := s.GetUserByID(ctx, userID)
if err != nil {
return gid.GID{}, err
}
return user.OrganizationID, nil
}
// GetUserOrganizations gets all organizations for a user
func (s Service) GetUserOrganizations(
ctx context.Context,