Skip to content

Commit 4194e0d

Browse files
authored
Merge branch 'main' into chart-ux
2 parents bfe2186 + d4c4a66 commit 4194e0d

File tree

8 files changed

+144
-4
lines changed

8 files changed

+144
-4
lines changed

pkg/api/authn/noauth.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ func (n *NoAuth) AuthenticateRequest(req *http.Request) (*authenticator.Response
2727
req.Context(),
2828
&types.Identity{
2929
ProviderUsername: "nobody",
30+
ProviderUserID: "nobody",
3031
},
3132
req.Header.Get("X-Obot-User-Timezone"),
3233
types2.RoleAdmin,

pkg/bootstrap/bootstrap.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ func (b *Bootstrap) AuthenticateRequest(req *http.Request) (*authenticator.Respo
152152
req.Context(),
153153
&types.Identity{
154154
ProviderUsername: "bootstrap",
155+
ProviderUserID: "bootstrap",
155156
},
156157
req.Header.Get("X-Obot-User-Timezone"),
157158
types2.RoleAdmin,

pkg/gateway/client/auth.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ func (u UserDecorator) AuthenticateRequest(req *http.Request) (*authenticator.Re
3737
AuthProviderName: firstValue(resp.User.GetExtra(), "auth_provider_name"),
3838
AuthProviderNamespace: firstValue(resp.User.GetExtra(), "auth_provider_namespace"),
3939
ProviderUsername: resp.User.GetName(),
40+
ProviderUserID: resp.User.GetUID(),
4041
}, req.Header.Get("X-Obot-User-Timezone"))
4142
if err != nil {
4243
return nil, false, err

pkg/gateway/client/identity.go

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package client
33
import (
44
"context"
55
"errors"
6+
"fmt"
67

78
types2 "github.com/obot-platform/obot/apiclient/types"
89
"github.com/obot-platform/obot/pkg/gateway/types"
@@ -37,14 +38,39 @@ func (c *Client) EnsureIdentityWithRole(ctx context.Context, id *types.Identity,
3738
func ensureIdentity(tx *gorm.DB, id *types.Identity, timezone string, role types2.Role) (*types.User, error) {
3839
email := id.Email
3940
if err := tx.First(id).Error; errors.Is(err, gorm.ErrRecordNotFound) {
40-
if err = tx.Create(id).Error; err != nil {
41+
// Before we try creating a new identity, we need to check if there is one that has not been fully migrated yet.
42+
migratedIdentity := &types.Identity{
43+
ProviderUsername: id.ProviderUsername,
44+
ProviderUserID: fmt.Sprintf("OBOT_PLACEHOLDER_%s", id.ProviderUsername),
45+
AuthProviderName: id.AuthProviderName,
46+
AuthProviderNamespace: id.AuthProviderNamespace,
47+
}
48+
if err := tx.First(migratedIdentity).Error; errors.Is(err, gorm.ErrRecordNotFound) {
49+
// If the identity does not exist, we can create it.
50+
if err = tx.Create(id).Error; err != nil {
51+
return nil, err
52+
}
53+
} else if err != nil {
4154
return nil, err
55+
} else {
56+
// The migrated identity exists. We need to update it with the right provider_user_id.
57+
if err := tx.Model(&migratedIdentity).Where("provider_user_id = ?", fmt.Sprintf("OBOT_PLACEHOLDER_%s", id.ProviderUsername)).Update("provider_user_id", id.ProviderUserID).Error; err != nil {
58+
return nil, err
59+
}
60+
61+
// Now we should be able to load the identity.
62+
if err := tx.First(id).Error; err != nil {
63+
return nil, err
64+
}
4265
}
4366
} else if err != nil {
4467
return nil, err
45-
} else if id.Email != email {
68+
}
69+
70+
// Check to see if the email got updated.
71+
if id.Email != email {
4672
id.Email = email
47-
if err = tx.Updates(id).Error; err != nil {
73+
if err := tx.Updates(id).Error; err != nil {
4874
return nil, err
4975
}
5076
}

pkg/gateway/db/db.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,57 @@ func (db *DB) AutoMigrate() (err error) {
3636
}
3737
}()
3838

39+
// Only run PostgreSQL-specific migrations if using PostgreSQL
40+
if db.gormDB.Dialector.Name() == "postgres" {
41+
// Check if the identities table exists
42+
var exists bool
43+
if err := tx.Raw(`
44+
SELECT EXISTS (
45+
SELECT 1
46+
FROM information_schema.tables
47+
WHERE table_name = 'identities'
48+
)
49+
`).Scan(&exists).Error; err != nil {
50+
return err
51+
}
52+
53+
if exists {
54+
// The identities table needs to have auth_provider_namespace,auth_provider_name,provider_user_id as a primary key.
55+
// It used to have auth_provider_namespace,auth_provider_name,provider_username as a primary key.
56+
57+
// Check if the migration is needed.
58+
var needsIdentityMigration bool
59+
if err := tx.Raw(`
60+
SELECT COUNT(*) = 0 as needs_migration
61+
FROM information_schema.key_column_usage
62+
WHERE table_name = 'identities'
63+
AND constraint_name = 'identities_pkey'
64+
AND column_name = 'provider_user_id'
65+
`).Scan(&needsIdentityMigration).Error; err != nil {
66+
return err
67+
}
68+
69+
if needsIdentityMigration {
70+
// Add provider_user_id to identities table and update primary key.
71+
if err := tx.Exec(`
72+
-- Drop existing primary key
73+
ALTER TABLE identities DROP CONSTRAINT identities_pkey;
74+
75+
-- Add provider_user_id column
76+
ALTER TABLE identities ADD COLUMN provider_user_id text NOT NULL DEFAULT '';
77+
78+
-- Set placeholder values for existing records
79+
UPDATE identities SET provider_user_id = 'OBOT_PLACEHOLDER_' || provider_username WHERE provider_user_id = '';
80+
81+
-- Add new primary key
82+
ALTER TABLE identities ADD PRIMARY KEY (auth_provider_name, auth_provider_namespace, provider_user_id);
83+
`).Error; err != nil {
84+
return err
85+
}
86+
}
87+
}
88+
}
89+
3990
return tx.AutoMigrate(
4091
types.AuthToken{},
4192
types.TokenRequest{},

pkg/gateway/types/identity.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import "time"
55
type Identity struct {
66
AuthProviderName string `json:"authProviderName" gorm:"primaryKey;index:idx_user_auth_id"`
77
AuthProviderNamespace string `json:"authProviderNamespace" gorm:"primaryKey;index:idx_user_auth_id"`
8-
ProviderUsername string `json:"providerUsername" gorm:"primaryKey"`
8+
ProviderUsername string `json:"providerUsername"`
9+
ProviderUserID string `json:"providerUserID" gorm:"primaryKey"`
910
Email string `json:"email"`
1011
UserID uint `json:"userID" gorm:"index:idx_user_auth_id"`
1112
IconURL string `json:"iconURL"`

pkg/services/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,7 @@ func New(ctx context.Context, config Config) (*Services, error) {
364364
// is enabled.
365365
if err := gatewayClient.RemoveIdentity(ctx, &types.Identity{
366366
ProviderUsername: "nobody",
367+
ProviderUserID: "nobody",
367368
}); err != nil {
368369
return nil, fmt.Errorf(`failed to remove "nobody" user and identity from database: %w`, err)
369370
}
Lines changed: 58 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)