mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: Add user scoped git ssh keys (#834)
This commit is contained in:
@@ -31,6 +31,7 @@ func New() database.Store {
|
||||
provisionerJobResource: make([]database.WorkspaceResource, 0),
|
||||
workspaceBuild: make([]database.WorkspaceBuild, 0),
|
||||
provisionerJobAgent: make([]database.WorkspaceAgent, 0),
|
||||
GitSSHKey: make([]database.GitSSHKey, 0),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +58,7 @@ type fakeQuerier struct {
|
||||
provisionerJobLog []database.ProvisionerJobLog
|
||||
workspace []database.Workspace
|
||||
workspaceBuild []database.WorkspaceBuild
|
||||
GitSSHKey []database.GitSSHKey
|
||||
}
|
||||
|
||||
// InTx doesn't rollback data properly for in-memory yet.
|
||||
@@ -1239,3 +1241,63 @@ func (q *fakeQuerier) UpdateWorkspaceDeletedByID(_ context.Context, arg database
|
||||
}
|
||||
return sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) InsertGitSSHKey(_ context.Context, arg database.InsertGitSSHKeyParams) (database.GitSSHKey, error) {
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
|
||||
//nolint:gosimple
|
||||
gitSSHKey := database.GitSSHKey{
|
||||
UserID: arg.UserID,
|
||||
CreatedAt: arg.CreatedAt,
|
||||
UpdatedAt: arg.UpdatedAt,
|
||||
PrivateKey: arg.PrivateKey,
|
||||
PublicKey: arg.PublicKey,
|
||||
}
|
||||
q.GitSSHKey = append(q.GitSSHKey, gitSSHKey)
|
||||
return gitSSHKey, nil
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) GetGitSSHKey(_ context.Context, userID uuid.UUID) (database.GitSSHKey, error) {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
for _, key := range q.GitSSHKey {
|
||||
if key.UserID == userID {
|
||||
return key, nil
|
||||
}
|
||||
}
|
||||
return database.GitSSHKey{}, sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) UpdateGitSSHKey(_ context.Context, arg database.UpdateGitSSHKeyParams) error {
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
|
||||
for index, key := range q.GitSSHKey {
|
||||
if key.UserID.String() != arg.UserID.String() {
|
||||
continue
|
||||
}
|
||||
key.UpdatedAt = arg.UpdatedAt
|
||||
key.PrivateKey = arg.PrivateKey
|
||||
key.PublicKey = arg.PublicKey
|
||||
q.GitSSHKey[index] = key
|
||||
return nil
|
||||
}
|
||||
return sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) DeleteGitSSHKey(_ context.Context, userID uuid.UUID) error {
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
|
||||
for index, key := range q.GitSSHKey {
|
||||
if key.UserID.String() != userID.String() {
|
||||
continue
|
||||
}
|
||||
q.GitSSHKey[index] = q.GitSSHKey[len(q.GitSSHKey)-1]
|
||||
q.GitSSHKey = q.GitSSHKey[:len(q.GitSSHKey)-1]
|
||||
return nil
|
||||
}
|
||||
return sql.ErrNoRows
|
||||
}
|
||||
|
||||
Generated
+14
@@ -89,6 +89,14 @@ CREATE TABLE files (
|
||||
data bytea NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE gitsshkeys (
|
||||
user_id uuid NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
private_key text NOT NULL,
|
||||
public_key text NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE licenses (
|
||||
id integer NOT NULL,
|
||||
license jsonb NOT NULL,
|
||||
@@ -283,6 +291,9 @@ ALTER TABLE ONLY api_keys
|
||||
ALTER TABLE ONLY files
|
||||
ADD CONSTRAINT files_pkey PRIMARY KEY (hash);
|
||||
|
||||
ALTER TABLE ONLY gitsshkeys
|
||||
ADD CONSTRAINT gitsshkeys_pkey PRIMARY KEY (user_id);
|
||||
|
||||
ALTER TABLE ONLY licenses
|
||||
ADD CONSTRAINT licenses_pkey PRIMARY KEY (id);
|
||||
|
||||
@@ -379,6 +390,9 @@ CREATE UNIQUE INDEX workspaces_owner_id_name_idx ON workspaces USING btree (owne
|
||||
ALTER TABLE ONLY api_keys
|
||||
ADD CONSTRAINT api_keys_user_id_uuid_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY gitsshkeys
|
||||
ADD CONSTRAINT gitsshkeys_user_id_fkey FOREIGN KEY (user_id) REFERENCES users(id);
|
||||
|
||||
ALTER TABLE ONLY organization_members
|
||||
ADD CONSTRAINT organization_members_organization_id_uuid_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
DROP TABLE gitsshkeys;
|
||||
@@ -0,0 +1,7 @@
|
||||
CREATE TABLE IF NOT EXISTS gitsshkeys (
|
||||
user_id uuid PRIMARY KEY NOT NULL REFERENCES users (id),
|
||||
created_at timestamptz NOT NULL,
|
||||
updated_at timestamptz NOT NULL,
|
||||
private_key text NOT NULL,
|
||||
public_key text NOT NULL
|
||||
);
|
||||
@@ -255,6 +255,14 @@ type File struct {
|
||||
Data []byte `db:"data" json:"data"`
|
||||
}
|
||||
|
||||
type GitSSHKey struct {
|
||||
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||
PrivateKey string `db:"private_key" json:"private_key"`
|
||||
PublicKey string `db:"public_key" json:"public_key"`
|
||||
}
|
||||
|
||||
type License struct {
|
||||
ID int32 `db:"id" json:"id"`
|
||||
License json.RawMessage `db:"license" json:"license"`
|
||||
|
||||
@@ -10,9 +10,11 @@ import (
|
||||
|
||||
type querier interface {
|
||||
AcquireProvisionerJob(ctx context.Context, arg AcquireProvisionerJobParams) (ProvisionerJob, error)
|
||||
DeleteGitSSHKey(ctx context.Context, userID uuid.UUID) error
|
||||
DeleteParameterValueByID(ctx context.Context, id uuid.UUID) error
|
||||
GetAPIKeyByID(ctx context.Context, id string) (APIKey, error)
|
||||
GetFileByHash(ctx context.Context, hash string) (File, error)
|
||||
GetGitSSHKey(ctx context.Context, userID uuid.UUID) (GitSSHKey, error)
|
||||
GetOrganizationByID(ctx context.Context, id uuid.UUID) (Organization, error)
|
||||
GetOrganizationByName(ctx context.Context, name string) (Organization, error)
|
||||
GetOrganizationMemberByUserID(ctx context.Context, arg GetOrganizationMemberByUserIDParams) (OrganizationMember, error)
|
||||
@@ -54,6 +56,7 @@ type querier interface {
|
||||
GetWorkspacesByUserID(ctx context.Context, arg GetWorkspacesByUserIDParams) ([]Workspace, error)
|
||||
InsertAPIKey(ctx context.Context, arg InsertAPIKeyParams) (APIKey, error)
|
||||
InsertFile(ctx context.Context, arg InsertFileParams) (File, error)
|
||||
InsertGitSSHKey(ctx context.Context, arg InsertGitSSHKeyParams) (GitSSHKey, error)
|
||||
InsertOrganization(ctx context.Context, arg InsertOrganizationParams) (Organization, error)
|
||||
InsertOrganizationMember(ctx context.Context, arg InsertOrganizationMemberParams) (OrganizationMember, error)
|
||||
InsertParameterSchema(ctx context.Context, arg InsertParameterSchemaParams) (ParameterSchema, error)
|
||||
@@ -69,6 +72,7 @@ type querier interface {
|
||||
InsertWorkspaceBuild(ctx context.Context, arg InsertWorkspaceBuildParams) (WorkspaceBuild, error)
|
||||
InsertWorkspaceResource(ctx context.Context, arg InsertWorkspaceResourceParams) (WorkspaceResource, error)
|
||||
UpdateAPIKeyByID(ctx context.Context, arg UpdateAPIKeyByIDParams) error
|
||||
UpdateGitSSHKey(ctx context.Context, arg UpdateGitSSHKeyParams) error
|
||||
UpdateProjectActiveVersionByID(ctx context.Context, arg UpdateProjectActiveVersionByIDParams) error
|
||||
UpdateProjectDeletedByID(ctx context.Context, arg UpdateProjectDeletedByIDParams) error
|
||||
UpdateProjectVersionByID(ctx context.Context, arg UpdateProjectVersionByIDParams) error
|
||||
|
||||
@@ -235,6 +235,108 @@ func (q *sqlQuerier) InsertFile(ctx context.Context, arg InsertFileParams) (File
|
||||
return i, err
|
||||
}
|
||||
|
||||
const deleteGitSSHKey = `-- name: DeleteGitSSHKey :exec
|
||||
DELETE FROM
|
||||
gitsshkeys
|
||||
WHERE
|
||||
user_id = $1
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) DeleteGitSSHKey(ctx context.Context, userID uuid.UUID) error {
|
||||
_, err := q.db.ExecContext(ctx, deleteGitSSHKey, userID)
|
||||
return err
|
||||
}
|
||||
|
||||
const getGitSSHKey = `-- name: GetGitSSHKey :one
|
||||
SELECT
|
||||
user_id, created_at, updated_at, private_key, public_key
|
||||
FROM
|
||||
gitsshkeys
|
||||
WHERE
|
||||
user_id = $1
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) GetGitSSHKey(ctx context.Context, userID uuid.UUID) (GitSSHKey, error) {
|
||||
row := q.db.QueryRowContext(ctx, getGitSSHKey, userID)
|
||||
var i GitSSHKey
|
||||
err := row.Scan(
|
||||
&i.UserID,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
&i.PrivateKey,
|
||||
&i.PublicKey,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const insertGitSSHKey = `-- name: InsertGitSSHKey :one
|
||||
INSERT INTO
|
||||
gitsshkeys (
|
||||
user_id,
|
||||
created_at,
|
||||
updated_at,
|
||||
private_key,
|
||||
public_key
|
||||
)
|
||||
VALUES
|
||||
($1, $2, $3, $4, $5) RETURNING user_id, created_at, updated_at, private_key, public_key
|
||||
`
|
||||
|
||||
type InsertGitSSHKeyParams struct {
|
||||
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||
PrivateKey string `db:"private_key" json:"private_key"`
|
||||
PublicKey string `db:"public_key" json:"public_key"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) InsertGitSSHKey(ctx context.Context, arg InsertGitSSHKeyParams) (GitSSHKey, error) {
|
||||
row := q.db.QueryRowContext(ctx, insertGitSSHKey,
|
||||
arg.UserID,
|
||||
arg.CreatedAt,
|
||||
arg.UpdatedAt,
|
||||
arg.PrivateKey,
|
||||
arg.PublicKey,
|
||||
)
|
||||
var i GitSSHKey
|
||||
err := row.Scan(
|
||||
&i.UserID,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
&i.PrivateKey,
|
||||
&i.PublicKey,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const updateGitSSHKey = `-- name: UpdateGitSSHKey :exec
|
||||
UPDATE
|
||||
gitsshkeys
|
||||
SET
|
||||
updated_at = $2,
|
||||
private_key = $3,
|
||||
public_key = $4
|
||||
WHERE
|
||||
user_id = $1
|
||||
`
|
||||
|
||||
type UpdateGitSSHKeyParams struct {
|
||||
UserID uuid.UUID `db:"user_id" json:"user_id"`
|
||||
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||
PrivateKey string `db:"private_key" json:"private_key"`
|
||||
PublicKey string `db:"public_key" json:"public_key"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) UpdateGitSSHKey(ctx context.Context, arg UpdateGitSSHKeyParams) error {
|
||||
_, err := q.db.ExecContext(ctx, updateGitSSHKey,
|
||||
arg.UserID,
|
||||
arg.UpdatedAt,
|
||||
arg.PrivateKey,
|
||||
arg.PublicKey,
|
||||
)
|
||||
return err
|
||||
}
|
||||
|
||||
const getOrganizationMemberByUserID = `-- name: GetOrganizationMemberByUserID :one
|
||||
SELECT
|
||||
user_id, organization_id, created_at, updated_at, roles
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
-- name: InsertGitSSHKey :one
|
||||
INSERT INTO
|
||||
gitsshkeys (
|
||||
user_id,
|
||||
created_at,
|
||||
updated_at,
|
||||
private_key,
|
||||
public_key
|
||||
)
|
||||
VALUES
|
||||
($1, $2, $3, $4, $5) RETURNING *;
|
||||
|
||||
-- name: GetGitSSHKey :one
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
gitsshkeys
|
||||
WHERE
|
||||
user_id = $1;
|
||||
|
||||
-- name: UpdateGitSSHKey :exec
|
||||
UPDATE
|
||||
gitsshkeys
|
||||
SET
|
||||
updated_at = $2,
|
||||
private_key = $3,
|
||||
public_key = $4
|
||||
WHERE
|
||||
user_id = $1;
|
||||
|
||||
-- name: DeleteGitSSHKey :exec
|
||||
DELETE FROM
|
||||
gitsshkeys
|
||||
WHERE
|
||||
user_id = $1;
|
||||
@@ -27,3 +27,4 @@ rename:
|
||||
oidc_refresh_token: OIDCRefreshToken
|
||||
parameter_type_system_hcl: ParameterTypeSystemHCL
|
||||
userstatus: UserStatus
|
||||
gitsshkey: GitSSHKey
|
||||
|
||||
Reference in New Issue
Block a user