From 0f0fd69092675a297a51c171f1ff6dc28248a9d7 Mon Sep 17 00:00:00 2001 From: Abhishek Shroff Date: Sun, 4 Aug 2024 11:31:45 +0530 Subject: [PATCH] Add user_id --- server/internal/api/auth/auth.go | 10 ++-- server/internal/api/auth/auth_basic.go | 19 ++------ server/internal/api/auth/auth_bearer.go | 2 +- server/internal/api/routes/silos.go | 4 +- server/internal/app/auth.go | 48 +++++++++++-------- server/internal/app/core/resource.go | 8 ++-- server/internal/app/core/silo.go | 16 +++---- server/internal/app/resources.go | 4 +- server/internal/app/silos.go | 8 ++-- server/internal/app/users.go | 44 +++++++++++++++-- server/internal/command/silo.go | 4 +- server/internal/command/user.go | 2 +- server/internal/handler_webdav/handler.go | 10 ++-- server/internal/migrations/data/002_users.sql | 3 +- server/internal/migrations/data/004_silos.sql | 2 +- .../migrations/data/005_access_tokens.sql | 2 +- .../migrations/data/006_permissions.sql | 4 +- server/internal/sql/access_tokens.sql.go | 16 +++---- server/internal/sql/models.go | 13 ++--- server/internal/sql/permissions.sql.go | 8 ++-- server/internal/sql/resources.sql.go | 20 ++++---- server/internal/sql/silos.sql.go | 8 ++-- server/internal/sql/users.sql.go | 6 ++- server/sql/queries/access_tokens.sql | 4 +- server/sql/queries/permissions.sql | 4 +- server/sql/queries/resources.sql | 8 ++-- server/sql/queries/silos.sql | 2 +- 27 files changed, 158 insertions(+), 121 deletions(-) diff --git a/server/internal/api/auth/auth.go b/server/internal/api/auth/auth.go index 3f6de3c2..fb610d05 100644 --- a/server/internal/api/auth/auth.go +++ b/server/internal/api/auth/auth.go @@ -2,12 +2,12 @@ package auth import "github.com/gin-gonic/gin" -const keyUsername = "username" +const keyUserID = "userID" -func GetUsername(c *gin.Context) string { - val, ok := c.Get(keyUsername) +func GetUserID(c *gin.Context) int32 { + val, ok := c.Get(keyUserID) if !ok { - return "" + return 0 } - return val.(string) + return val.(int32) } diff --git a/server/internal/api/auth/auth_basic.go b/server/internal/api/auth/auth_basic.go index 627ef151..a5e00d15 100644 --- a/server/internal/api/auth/auth_basic.go +++ b/server/internal/api/auth/auth_basic.go @@ -6,7 +6,6 @@ import ( "github.com/gin-gonic/gin" "github.com/shroff/phylum/server/internal/app" - "github.com/shroff/phylum/server/internal/cryptutil" ) func CreateBasicAuthHandler(app *app.App) func(c *gin.Context) { @@ -17,23 +16,13 @@ func CreateBasicAuthHandler(app *app.App) func(c *gin.Context) { c.Status(http.StatusUnauthorized) return } - user, err := app.FindUser(context.Background(), username) - if err != nil { + if userID, err := app.VerifyUserPassword(context.Background(), username, pass); err != nil { + c.Header("WWW-Authenticate", "Basic realm=\"Phylum WebDAV\"") c.Status(http.StatusUnauthorized) return + } else { + c.Set(keyUserID, userID) } - ok, err = cryptutil.VerifyPassword(pass, user.PasswordHash) - if err != nil { - c.Header("WWW-Authenticate", "Basic realm=\"Phylum WebDAV\"") - c.Status(http.StatusUnauthorized) - return - } - if !ok { - c.Header("WWW-Authenticate", "Basic realm=\"Phylum WebDAV\"") - c.Status(http.StatusUnauthorized) - return - } - c.Set(keyUsername, user.Username) } } diff --git a/server/internal/api/auth/auth_bearer.go b/server/internal/api/auth/auth_bearer.go index a7493bca..122a4abe 100644 --- a/server/internal/api/auth/auth_bearer.go +++ b/server/internal/api/auth/auth_bearer.go @@ -32,6 +32,6 @@ func CreateBearerAuthHandler(a *app.App) func(c *gin.Context) { } panic(err) } - c.Set(keyUsername, username) + c.Set(keyUserID, username) } } diff --git a/server/internal/api/routes/silos.go b/server/internal/api/routes/silos.go index fe4e83aa..4fcbd4f0 100644 --- a/server/internal/api/routes/silos.go +++ b/server/internal/api/routes/silos.go @@ -12,7 +12,7 @@ import ( type siloResponse struct { ID uuid.UUID `json:"id"` Name string `json:"name"` - Owner string `json:"owner"` + Owner int32 `json:"owner"` Storage string `json:"storage"` } @@ -23,7 +23,7 @@ func SetupSiloRoutes(r *gin.RouterGroup, a *app.App) { func createSiloListRouteHandler(a *app.App) func(c *gin.Context) { return func(c *gin.Context) { - silos, err := a.SilosForUser(context.Background(), auth.GetUsername(c)) + silos, err := a.SilosForUser(context.Background(), auth.GetUserID(c)) if err != nil { panic(err) } diff --git a/server/internal/app/auth.go b/server/internal/app/auth.go index 1eb9cfd9..bc4693bd 100644 --- a/server/internal/app/auth.go +++ b/server/internal/app/auth.go @@ -25,43 +25,51 @@ var ErrCredentialsInvalid = errors.New("credentials invalid") var ErrTokenInvalid = errors.New("token invalid") var ErrTokenExpired = errors.New("token expired") -func (a App) CreateAccessToken(username, password string) (sql.AccessToken, error) { - if user, err := a.FindUser(context.Background(), username); err != nil { +func (a App) VerifyUserPassword(ctx context.Context, username, password string) (int32, error) { + if user, err := a.Db.Queries().UserByUsername(context.Background(), username); err != nil { if errors.Is(err, pgx.ErrNoRows) { - return sql.AccessToken{}, ErrCredentialsInvalid + return 0, ErrCredentialsInvalid } logrus.Info(err) - return sql.AccessToken{}, err + return 0, err } else { if b, err := cryptutil.VerifyPassword(password, user.PasswordHash); err != nil { logrus.Warn(err.Error()) - return sql.AccessToken{}, err + return 0, err } else if !b { - return sql.AccessToken{}, ErrCredentialsInvalid + return 0, ErrCredentialsInvalid } - } - if token, err := a.Db.Queries().InsertAccessToken(context.Background(), sql.InsertAccessTokenParams{ - ID: GenerateRandomString(accessTokenLength), - Validity: accessTokenValiditiy, - Username: username, - }); err != nil { - return sql.AccessToken{}, err - } else { - return token, nil + return user.ID, nil } } -func (a App) VerifyAccessToken(accessToken string) (string, error) { +func (a App) CreateAccessToken(username, password string) (sql.AccessToken, error) { + if userID, err := a.VerifyUserPassword(context.Background(), username, password); err != nil { + return sql.AccessToken{}, err + } else { + if token, err := a.Db.Queries().InsertAccessToken(context.Background(), sql.InsertAccessTokenParams{ + ID: GenerateRandomString(accessTokenLength), + Validity: accessTokenValiditiy, + UserID: userID, + }); err != nil { + return sql.AccessToken{}, err + } else { + return token, nil + } + } +} + +func (a App) VerifyAccessToken(accessToken string) (int32, error) { token, err := a.Db.Queries().AccessTokenById(context.Background(), accessToken) if errors.Is(err, pgx.ErrNoRows) { - return "", ErrTokenInvalid + return 0, ErrTokenInvalid } else if err != nil { - return "", err + return 0, err } if time.Now().After(token.Expires.Time) { - return "", ErrTokenExpired + return 0, ErrTokenExpired } - return token.Username, nil + return token.UserID, nil } const ( diff --git a/server/internal/app/core/resource.go b/server/internal/app/core/resource.go index 059a7613..0266e619 100644 --- a/server/internal/app/core/resource.go +++ b/server/internal/app/core/resource.go @@ -55,7 +55,7 @@ type resource struct { parentID *uuid.UUID name string size int64 - username string + userID int32 permission int collection bool modTime time.Time @@ -117,7 +117,7 @@ func (r resource) ReadDir(ctx context.Context) ([]Resource, error) { if r.permission < PermissionReadOnly { return nil, ErrInsufficientPermissions } - children, err := r.db.Queries().ReadDir(ctx, sql.ReadDirParams{ID: r.id, Username: r.username, IncludeRoot: false, Recursive: false}) + children, err := r.db.Queries().ReadDir(ctx, sql.ReadDirParams{ID: r.id, UserID: r.userID, IncludeRoot: false, Recursive: false}) if err != nil { return nil, err } @@ -133,7 +133,7 @@ func (r resource) ReadDir(ctx context.Context) ([]Resource, error) { db: r.db, storage: r.storage, id: c.ID, - username: r.username, + userID: r.userID, permission: permission, parentID: &r.id, name: c.Name, @@ -169,7 +169,7 @@ func (r resource) CreateMemberResource(ctx context.Context, id uuid.UUID, name s storage: r.storage, id: id, parentID: &r.id, - username: r.username, + userID: r.userID, permission: r.permission, name: result.Name, size: 0, diff --git a/server/internal/app/core/silo.go b/server/internal/app/core/silo.go index d9447166..4e5accc0 100644 --- a/server/internal/app/core/silo.go +++ b/server/internal/app/core/silo.go @@ -13,21 +13,21 @@ import ( type Silo interface { ID() uuid.UUID Name() string - Owner() string + Owner() int32 StorageName() string - ResourceByPath(ctx context.Context, path, username string) (Resource, error) + ResourceByPath(ctx context.Context, path string, userID int32) (Resource, error) Move(ctx context.Context, id uuid.UUID, parent uuid.UUID, name string) error } type silo struct { db *db.DbHandler name string - owner string + owner int32 root uuid.UUID storage Storage } -func NewSilo(db *db.DbHandler, name, owner string, root uuid.UUID, storage Storage) Silo { +func NewSilo(db *db.DbHandler, name string, owner int32, root uuid.UUID, storage Storage) Silo { return &silo{ db: db, name: name, @@ -45,7 +45,7 @@ func (s *silo) Name() string { return s.name } -func (s *silo) Owner() string { +func (s *silo) Owner() int32 { return s.owner } @@ -57,7 +57,7 @@ func (s *silo) Move(ctx context.Context, id uuid.UUID, parent uuid.UUID, name st return s.db.Queries().Rename(ctx, sql.RenameParams{ID: id, Parent: parent, Name: name}) } -func (s *silo) ResourceByPath(ctx context.Context, path, username string) (Resource, error) { +func (s *silo) ResourceByPath(ctx context.Context, path string, userID int32) (Resource, error) { path = strings.Trim(path, "/") segments := strings.Split(path, "/") if path == "" { @@ -65,7 +65,7 @@ func (s *silo) ResourceByPath(ctx context.Context, path, username string) (Resou segments = []string{} } - res, err := s.db.Queries().ResourceByPath(ctx, sql.ResourceByPathParams{Root: s.root, Search: segments, Username: username}) + res, err := s.db.Queries().ResourceByPath(ctx, sql.ResourceByPathParams{Root: s.root, Search: segments, UserID: userID}) if err != nil { return nil, fs.ErrNotExist } @@ -78,7 +78,7 @@ func (s *silo) ResourceByPath(ctx context.Context, path, username string) (Resou db: s.db, storage: s.storage, id: res.ID, - username: username, + userID: userID, permission: int(res.Permission.Int32), parentID: res.Parent, name: res.Name, diff --git a/server/internal/app/resources.go b/server/internal/app/resources.go index a4f5ffda..9bf3e92d 100644 --- a/server/internal/app/resources.go +++ b/server/internal/app/resources.go @@ -11,8 +11,8 @@ import ( var ErrResourceNotFound = errors.New("resource not found") -func (a *App) LocateResource(id uuid.UUID, username string) (uuid.UUID, int, error) { - result, err := a.Db.Queries().PermissionsForResource(context.Background(), sql.PermissionsForResourceParams{ResourceID: id, Username: username}) +func (a *App) LocateResource(id uuid.UUID, userID int32) (uuid.UUID, int, error) { + result, err := a.Db.Queries().PermissionsForResource(context.Background(), sql.PermissionsForResourceParams{ResourceID: id, UserID: userID}) if err == pgx.ErrNoRows { err = ErrResourceNotFound } diff --git a/server/internal/app/silos.go b/server/internal/app/silos.go index 6ae4b2e1..02fb10c6 100644 --- a/server/internal/app/silos.go +++ b/server/internal/app/silos.go @@ -9,7 +9,7 @@ import ( "github.com/shroff/phylum/server/internal/sql" ) -func (a App) CreateSilo(ctx context.Context, id uuid.UUID, owner, storage, name string) error { +func (a App) CreateSilo(ctx context.Context, id uuid.UUID, owner int32, storage, name string) error { return a.Db.RunInTx(ctx, func(q *sql.Queries) error { if err := q.CreateSilo(ctx, sql.CreateSiloParams{ ID: id, @@ -43,8 +43,8 @@ func (a App) AllSilos(ctx context.Context) ([]core.Silo, error) { return results, nil } -func (a App) SilosForUser(ctx context.Context, username string) ([]core.Silo, error) { - silos, err := a.Db.Queries().ListSilosForUser(ctx, username) +func (a App) SilosForUser(ctx context.Context, userID int32) ([]core.Silo, error) { + silos, err := a.Db.Queries().ListSilosForUser(ctx, userID) if err != nil { return nil, err } @@ -90,7 +90,7 @@ func (a App) DeleteSilo(ctx context.Context, id uuid.UUID) error { } silo := core.NewSilo(a.Db, result.Name, result.Owner, result.ID, storage) - resource, err := silo.ResourceByPath(ctx, "/", "admin") + resource, err := silo.ResourceByPath(ctx, "/", -1) if err != nil { return err } diff --git a/server/internal/app/users.go b/server/internal/app/users.go index 1c9c29c7..6004fd67 100644 --- a/server/internal/app/users.go +++ b/server/internal/app/users.go @@ -7,6 +7,22 @@ import ( "github.com/shroff/phylum/server/internal/sql" ) +type User interface { + ID() int32 + Username() string + DisplayName() string +} + +type user struct { + id int32 + username string + displayName string +} + +func (u user) ID() int32 { return u.id } +func (u user) Username() string { return u.username } +func (u user) DisplayName() string { return u.displayName } + func (a App) CreateUser(ctx context.Context, username, displayName, password string) error { if hash, err := cryptutil.GenerateArgon2EncodedHash(password, cryptutil.DefaultArgon2Params()); err != nil { return err @@ -16,10 +32,30 @@ func (a App) CreateUser(ctx context.Context, username, displayName, password str return nil } -func (a App) ListUsers(ctx context.Context) ([]sql.User, error) { - return a.Db.Queries().ListUsers(ctx) +func (a App) ListUsers(ctx context.Context) ([]User, error) { + results, err := a.Db.Queries().ListUsers(ctx) + if err != nil { + return nil, err + } + users := make([]User, len(results)) + for i, r := range results { + users[i] = user{ + id: r.ID, + username: r.Username, + displayName: r.DisplayName, + } + } + return users, nil } -func (a App) FindUser(ctx context.Context, username string) (sql.User, error) { - return a.Db.Queries().UserByUsername(ctx, username) +func (a App) FindUser(ctx context.Context, username string) (User, error) { + result, err := a.Db.Queries().UserByUsername(ctx, username) + if err != nil { + return nil, err + } + return user{ + id: result.ID, + username: result.Username, + displayName: result.DisplayName, + }, nil } diff --git a/server/internal/command/silo.go b/server/internal/command/silo.go index 2f635d97..4b86f799 100644 --- a/server/internal/command/silo.go +++ b/server/internal/command/silo.go @@ -43,7 +43,7 @@ func setupSiloCreateCommand() *cobra.Command { } name := args[2] - if err := app.Default.CreateSilo(context.Background(), id, user.Username, storageName, name); err != nil { + if err := app.Default.CreateSilo(context.Background(), id, user.ID(), storageName, name); err != nil { logrus.Fatal(err) } logrus.Info("Created " + id.String()) @@ -65,7 +65,7 @@ func setupSiloListCommand() *cobra.Command { for _, silo := range silos { logrus.Infof("%-16s: %s\n", silo.Name(), silo.ID().String()) // logrus.Infof(" storage: %s\n", silo.StorageName()) - logrus.Infof(" owner: %s\n", silo.Owner()) + logrus.Infof(" owner: %d\n", silo.Owner()) logrus.Info() } }, diff --git a/server/internal/command/user.go b/server/internal/command/user.go index d02caf77..56de7418 100644 --- a/server/internal/command/user.go +++ b/server/internal/command/user.go @@ -86,7 +86,7 @@ func setupUserListCommand() *cobra.Command { logrus.Fatal(err) } for _, user := range users { - logrus.Infof("%16s: %s", user.Username, user.DisplayName) + logrus.Infof("%d: %s (%s)", user.ID(), user.Username(), user.DisplayName()) } }, } diff --git a/server/internal/handler_webdav/handler.go b/server/internal/handler_webdav/handler.go index 88edbb4f..e7527e56 100644 --- a/server/internal/handler_webdav/handler.go +++ b/server/internal/handler_webdav/handler.go @@ -65,23 +65,23 @@ func (h *handler) HandleRequest(c *gin.Context) { return } - username := auth.GetUsername(c) + userID := auth.GetUserID(c) webdavHandler := webdav.Handler{ Prefix: h.prefix + "/" + identifier, - FileSystem: adapter{silo: silo, username: username}, + FileSystem: adapter{silo: silo, userID: userID}, LockSystem: webdav.NewMemLS(), } webdavHandler.ServeHTTP(c.Writer, c.Request) } type adapter struct { - silo core.Silo - username string + silo core.Silo + userID int32 } func (a adapter) Stat(ctx context.Context, name string) (core.Resource, error) { - return a.silo.ResourceByPath(ctx, name, a.username) + return a.silo.ResourceByPath(ctx, name, a.userID) } func (a adapter) OpenWrite(ctx context.Context, name string) (io.WriteCloser, error) { diff --git a/server/internal/migrations/data/002_users.sql b/server/internal/migrations/data/002_users.sql index e7bf47a1..ccff06e2 100644 --- a/server/internal/migrations/data/002_users.sql +++ b/server/internal/migrations/data/002_users.sql @@ -1,5 +1,6 @@ CREATE TABLE users( - username TEXT NOT NULL PRIMARY KEY, + id SERIAL PRIMARY KEY, + username TEXT NOT NULL UNIQUE, display_name TEXT NOT NULL, password_hash TEXT NOT NULL, deleted TIMESTAMP diff --git a/server/internal/migrations/data/004_silos.sql b/server/internal/migrations/data/004_silos.sql index a0d8acf2..2d5bc674 100644 --- a/server/internal/migrations/data/004_silos.sql +++ b/server/internal/migrations/data/004_silos.sql @@ -3,7 +3,7 @@ CREATE TABLE silos( created TIMESTAMP NOT NULL, modified TIMESTAMP NOT NULL, deleted TIMESTAMP, - owner TEXT NOT NULL REFERENCES users(username) ON UPDATE CASCADE ON DELETE CASCADE, + owner INTEGER NOT NULL REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE, name TEXT NOT NULL, storage TEXT NOT NULL REFERENCES storage_backends(name) ON UPDATE CASCADE ON DELETE CASCADE ); diff --git a/server/internal/migrations/data/005_access_tokens.sql b/server/internal/migrations/data/005_access_tokens.sql index 8e134f45..ec83ba04 100644 --- a/server/internal/migrations/data/005_access_tokens.sql +++ b/server/internal/migrations/data/005_access_tokens.sql @@ -2,7 +2,7 @@ CREATE TABLE access_tokens( id TEXT NOT NULL PRIMARY KEY, created TIMESTAMP NOT NULL, expires TIMESTAMP NOT NULL, - username TEXT NOT NULL + user_id INTEGER NOT NULL REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE ); ---- create above / drop below ---- diff --git a/server/internal/migrations/data/006_permissions.sql b/server/internal/migrations/data/006_permissions.sql index 1670e3a2..d72965b1 100644 --- a/server/internal/migrations/data/006_permissions.sql +++ b/server/internal/migrations/data/006_permissions.sql @@ -1,8 +1,8 @@ CREATE TABLE permissions( resource_id uuid NOT NULL, - username TEXT NOT NULL, + user_id INTEGER NOT NULL REFERENCES users(id) ON UPDATE CASCADE ON DELETE CASCADE, permission INT NOT NULL, - PRIMARY KEY(resource_id, username) + PRIMARY KEY(resource_id, user_id) ); ---- create above / drop below ---- diff --git a/server/internal/sql/access_tokens.sql.go b/server/internal/sql/access_tokens.sql.go index ae515168..0f954245 100644 --- a/server/internal/sql/access_tokens.sql.go +++ b/server/internal/sql/access_tokens.sql.go @@ -12,7 +12,7 @@ import ( ) const accessTokenById = `-- name: AccessTokenById :one -SELECT id, created, expires, username from access_tokens where id = $1 +SELECT id, created, expires, user_id from access_tokens where id = $1 ` func (q *Queries) AccessTokenById(ctx context.Context, id string) (AccessToken, error) { @@ -22,33 +22,33 @@ func (q *Queries) AccessTokenById(ctx context.Context, id string) (AccessToken, &i.ID, &i.Created, &i.Expires, - &i.Username, + &i.UserID, ) return i, err } const insertAccessToken = `-- name: InsertAccessToken :one INSERT INTO access_tokens( - id, created, expires, username + id, created, expires, user_id ) VALUES( - $1::text, NOW(), NOW() + $2::interval, $3::text -) RETURNING id, created, expires, username + $1::text, NOW(), NOW() + $2::interval, $3::int +) RETURNING id, created, expires, user_id ` type InsertAccessTokenParams struct { ID string Validity pgtype.Interval - Username string + UserID int32 } func (q *Queries) InsertAccessToken(ctx context.Context, arg InsertAccessTokenParams) (AccessToken, error) { - row := q.db.QueryRow(ctx, insertAccessToken, arg.ID, arg.Validity, arg.Username) + row := q.db.QueryRow(ctx, insertAccessToken, arg.ID, arg.Validity, arg.UserID) var i AccessToken err := row.Scan( &i.ID, &i.Created, &i.Expires, - &i.Username, + &i.UserID, ) return i, err } diff --git a/server/internal/sql/models.go b/server/internal/sql/models.go index 27266e9c..1318de53 100644 --- a/server/internal/sql/models.go +++ b/server/internal/sql/models.go @@ -10,15 +10,15 @@ import ( ) type AccessToken struct { - ID string - Created pgtype.Timestamp - Expires pgtype.Timestamp - Username string + ID string + Created pgtype.Timestamp + Expires pgtype.Timestamp + UserID int32 } type Permission struct { ResourceID uuid.UUID - Username string + UserID int32 Permission int32 } @@ -39,7 +39,7 @@ type Silo struct { Created pgtype.Timestamp Modified pgtype.Timestamp Deleted pgtype.Timestamp - Owner string + Owner int32 Name string Storage string } @@ -51,6 +51,7 @@ type StorageBackend struct { } type User struct { + ID int32 Username string DisplayName string PasswordHash string diff --git a/server/internal/sql/permissions.sql.go b/server/internal/sql/permissions.sql.go index a94ea754..01fe45fa 100644 --- a/server/internal/sql/permissions.sql.go +++ b/server/internal/sql/permissions.sql.go @@ -15,17 +15,17 @@ import ( const permissionsForResource = `-- name: PermissionsForResource :one WITH RECURSIVE nodes(id, parent, permission) AS ( SELECT r.id, r.parent, p.permission - FROM resources r LEFT JOIN permissions p on r.id = p.resource_id WHERE r.id = $1::uuid AND p.username = $2::text + FROM resources r LEFT JOIN permissions p on r.id = p.resource_id WHERE r.id = $1::uuid AND p.user_id = $2::int UNION ALL SELECT r.id, r.parent, CASE WHEN (n.permission IS NULL OR p.permission > n.permission) THEN p.permission ELSE n.permission END - FROM resources r JOIN nodes n ON r.id = n.parent LEFT JOIN permissions p ON r.id = p.resource_id AND p.username = $2::text + FROM resources r JOIN nodes n ON r.id = n.parent LEFT JOIN permissions p ON r.id = p.resource_id AND p.user_id = $2::int ) SELECT id, parent, permission FROM nodes WHERE parent IS NULL ` type PermissionsForResourceParams struct { ResourceID uuid.UUID - Username string + UserID int32 } type PermissionsForResourceRow struct { @@ -35,7 +35,7 @@ type PermissionsForResourceRow struct { } func (q *Queries) PermissionsForResource(ctx context.Context, arg PermissionsForResourceParams) (PermissionsForResourceRow, error) { - row := q.db.QueryRow(ctx, permissionsForResource, arg.ResourceID, arg.Username) + row := q.db.QueryRow(ctx, permissionsForResource, arg.ResourceID, arg.UserID) var i PermissionsForResourceRow err := row.Scan(&i.ID, &i.Parent, &i.Permission) return i, err diff --git a/server/internal/sql/resources.sql.go b/server/internal/sql/resources.sql.go index 444a2095..9cc75591 100644 --- a/server/internal/sql/resources.sql.go +++ b/server/internal/sql/resources.sql.go @@ -113,14 +113,14 @@ WITH RECURSIVE nodes(id, parent, name, dir, created, modified, size, etag, depth FROM resources r LEFT JOIN permissions p ON r.id = p.resource_id - AND p.username = $2::text + AND p.user_id = $2::int WHERE r.id = $3::uuid UNION ALL SELECT r.id, r.parent, r.name, r.dir, r.created, r.modified, r.size, r.etag, n.depth + 1, concat(n.path, '/', r.name), CASE WHEN (p.permission IS NULL OR p.permission < n.permission) THEN n.permission ELSE p.permission END FROM resources r JOIN nodes n on r.parent = n.id LEFT JOIN permissions p ON r.id = p.resource_id - AND p.username = $2::text + AND p.user_id = $2::int WHERE deleted IS NULL AND CASE WHEN $4::boolean THEN true ELSE depth < 1 END ) @@ -130,7 +130,7 @@ WHERE CASE WHEN $1::boolean THEN true ELSE depth > 0 END type ReadDirParams struct { IncludeRoot bool - Username string + UserID int32 ID uuid.UUID Recursive bool } @@ -152,7 +152,7 @@ type ReadDirRow struct { func (q *Queries) ReadDir(ctx context.Context, arg ReadDirParams) ([]ReadDirRow, error) { rows, err := q.db.Query(ctx, readDir, arg.IncludeRoot, - arg.Username, + arg.UserID, arg.ID, arg.Recursive, ) @@ -233,7 +233,7 @@ WITH RECURSIVE nodes(id, parent, name, dir, created, modified, size, etag, depth FROM resources r LEFT JOIN permissions p ON r.id = p.resource_id - AND p.username = $2::text + AND p.user_id = $2::int WHERE r.id = $3::uuid UNION ALL SELECT r.id, r.parent, r.name, r.dir, r.created, r.modified, r.size, r.etag, n.depth + 1, concat(n.path, '/', r.name), n.search, CASE WHEN (p.permission IS NULL OR p.permission < n.permission) THEN n.permission ELSE p.permission END @@ -241,7 +241,7 @@ WITH RECURSIVE nodes(id, parent, name, dir, created, modified, size, etag, depth JOIN nodes n ON r.parent = n.id LEFT JOIN permissions p ON r.id = p.resource_id - AND p.username = $2::text + AND p.user_id = $2::int WHERE deleted IS NULL AND r.name = n.search[n.depth + 1] ) @@ -249,9 +249,9 @@ SELECT id, parent, name, dir, created, modified, size, etag, depth, path, search ` type ResourceByPathParams struct { - Search []string - Username string - Root uuid.UUID + Search []string + UserID int32 + Root uuid.UUID } type ResourceByPathRow struct { @@ -270,7 +270,7 @@ type ResourceByPathRow struct { } func (q *Queries) ResourceByPath(ctx context.Context, arg ResourceByPathParams) (ResourceByPathRow, error) { - row := q.db.QueryRow(ctx, resourceByPath, arg.Search, arg.Username, arg.Root) + row := q.db.QueryRow(ctx, resourceByPath, arg.Search, arg.UserID, arg.Root) var i ResourceByPathRow err := row.Scan( &i.ID, diff --git a/server/internal/sql/silos.sql.go b/server/internal/sql/silos.sql.go index f7244bbd..45ea9344 100644 --- a/server/internal/sql/silos.sql.go +++ b/server/internal/sql/silos.sql.go @@ -21,7 +21,7 @@ INSERT INTO silos( type CreateSiloParams struct { ID uuid.UUID - Owner string + Owner int32 Name string Storage string } @@ -78,11 +78,11 @@ func (q *Queries) ListAllSilos(ctx context.Context) ([]Silo, error) { } const listSilosForUser = `-- name: ListSilosForUser :many -SELECT id, created, modified, deleted, owner, name, storage from silos where owner = $1::text +SELECT id, created, modified, deleted, owner, name, storage from silos where owner = $1::int ` -func (q *Queries) ListSilosForUser(ctx context.Context, username string) ([]Silo, error) { - rows, err := q.db.Query(ctx, listSilosForUser, username) +func (q *Queries) ListSilosForUser(ctx context.Context, userID int32) ([]Silo, error) { + rows, err := q.db.Query(ctx, listSilosForUser, userID) if err != nil { return nil, err } diff --git a/server/internal/sql/users.sql.go b/server/internal/sql/users.sql.go index 8f2708ec..d9a6e5a5 100644 --- a/server/internal/sql/users.sql.go +++ b/server/internal/sql/users.sql.go @@ -29,7 +29,7 @@ func (q *Queries) CreateUser(ctx context.Context, arg CreateUserParams) error { } const listUsers = `-- name: ListUsers :many -SELECT username, display_name, password_hash, deleted from users WHERE deleted IS NULL +SELECT id, username, display_name, password_hash, deleted from users WHERE deleted IS NULL ` func (q *Queries) ListUsers(ctx context.Context) ([]User, error) { @@ -42,6 +42,7 @@ func (q *Queries) ListUsers(ctx context.Context) ([]User, error) { for rows.Next() { var i User if err := rows.Scan( + &i.ID, &i.Username, &i.DisplayName, &i.PasswordHash, @@ -58,13 +59,14 @@ func (q *Queries) ListUsers(ctx context.Context) ([]User, error) { } const userByUsername = `-- name: UserByUsername :one -SELECT username, display_name, password_hash, deleted from users WHERE username = $1 +SELECT id, username, display_name, password_hash, deleted from users WHERE username = $1 ` func (q *Queries) UserByUsername(ctx context.Context, username string) (User, error) { row := q.db.QueryRow(ctx, userByUsername, username) var i User err := row.Scan( + &i.ID, &i.Username, &i.DisplayName, &i.PasswordHash, diff --git a/server/sql/queries/access_tokens.sql b/server/sql/queries/access_tokens.sql index f39b84ae..afba1f29 100644 --- a/server/sql/queries/access_tokens.sql +++ b/server/sql/queries/access_tokens.sql @@ -3,7 +3,7 @@ SELECT * from access_tokens where id = $1; -- name: InsertAccessToken :one INSERT INTO access_tokens( - id, created, expires, username + id, created, expires, user_id ) VALUES( - @id::text, NOW(), NOW() + @validity::interval, @username::text + @id::text, NOW(), NOW() + @validity::interval, @user_id::int ) RETURNING *; diff --git a/server/sql/queries/permissions.sql b/server/sql/queries/permissions.sql index 2f632ef8..e54dc8fb 100644 --- a/server/sql/queries/permissions.sql +++ b/server/sql/queries/permissions.sql @@ -2,9 +2,9 @@ -- name: PermissionsForResource :one WITH RECURSIVE nodes(id, parent, permission) AS ( SELECT r.id, r.parent, p.permission - FROM resources r LEFT JOIN permissions p on r.id = p.resource_id WHERE r.id = @resource_id::uuid AND p.username = @username::text + FROM resources r LEFT JOIN permissions p on r.id = p.resource_id WHERE r.id = @resource_id::uuid AND p.user_id = @user_id::int UNION ALL SELECT r.id, r.parent, CASE WHEN (n.permission IS NULL OR p.permission > n.permission) THEN p.permission ELSE n.permission END - FROM resources r JOIN nodes n ON r.id = n.parent LEFT JOIN permissions p ON r.id = p.resource_id AND p.username = @username::text + FROM resources r JOIN nodes n ON r.id = n.parent LEFT JOIN permissions p ON r.id = p.resource_id AND p.user_id = @user_id::int ) SELECT * FROM nodes WHERE parent IS NULL; diff --git a/server/sql/queries/resources.sql b/server/sql/queries/resources.sql index cf8c69c8..f8fee441 100644 --- a/server/sql/queries/resources.sql +++ b/server/sql/queries/resources.sql @@ -37,14 +37,14 @@ WITH RECURSIVE nodes(id, parent, name, dir, created, modified, size, etag, depth FROM resources r LEFT JOIN permissions p ON r.id = p.resource_id - AND p.username = @username::text + AND p.user_id = @user_id::int WHERE r.id = @id::uuid UNION ALL SELECT r.id, r.parent, r.name, r.dir, r.created, r.modified, r.size, r.etag, n.depth + 1, concat(n.path, '/', r.name), CASE WHEN (p.permission IS NULL OR p.permission < n.permission) THEN n.permission ELSE p.permission END FROM resources r JOIN nodes n on r.parent = n.id LEFT JOIN permissions p ON r.id = p.resource_id - AND p.username = @username::text + AND p.user_id = @user_id::int WHERE deleted IS NULL AND CASE WHEN @recursive::boolean THEN true ELSE depth < 1 END ) @@ -57,7 +57,7 @@ WITH RECURSIVE nodes(id, parent, name, dir, created, modified, size, etag, depth FROM resources r LEFT JOIN permissions p ON r.id = p.resource_id - AND p.username = @username::text + AND p.user_id = @user_id::int WHERE r.id = @root::uuid UNION ALL SELECT r.id, r.parent, r.name, r.dir, r.created, r.modified, r.size, r.etag, n.depth + 1, concat(n.path, '/', r.name), n.search, CASE WHEN (p.permission IS NULL OR p.permission < n.permission) THEN n.permission ELSE p.permission END @@ -65,7 +65,7 @@ WITH RECURSIVE nodes(id, parent, name, dir, created, modified, size, etag, depth JOIN nodes n ON r.parent = n.id LEFT JOIN permissions p ON r.id = p.resource_id - AND p.username = @username::text + AND p.user_id = @user_id::int WHERE deleted IS NULL AND r.name = n.search[n.depth + 1] ) diff --git a/server/sql/queries/silos.sql b/server/sql/queries/silos.sql index 4974d942..199abe32 100644 --- a/server/sql/queries/silos.sql +++ b/server/sql/queries/silos.sql @@ -18,4 +18,4 @@ INSERT INTO silos( SELECT * from silos; -- name: ListSilosForUser :many -SELECT * from silos where owner = @username::text; \ No newline at end of file +SELECT * from silos where owner = @user_id::int; \ No newline at end of file