Compare commits
5 Commits
ee3c8810ac
...
4d0577775b
| Author | SHA1 | Date | |
|---|---|---|---|
| 4d0577775b | |||
| 83c405b282 | |||
| f9a3e4b389 | |||
| 5c13311aba | |||
| 68176b1bdd |
@@ -1,5 +1,6 @@
|
||||
package db
|
||||
|
||||
import "context"
|
||||
import "database/sql"
|
||||
import "errors"
|
||||
import "fmt"
|
||||
@@ -261,16 +262,18 @@ func (s *Store) GetAuthProviderWithGroupMappings(id string) (models.AuthProvider
|
||||
}
|
||||
|
||||
func (s *Store) CountAuthProviderUsers(id string) (int, error) {
|
||||
var row *sql.Row
|
||||
return countAuthProviderUsers(s, id)
|
||||
}
|
||||
|
||||
func countAuthProviderUsers(execer sqlExecutor, id string) (int, error) {
|
||||
var count int
|
||||
var err error
|
||||
|
||||
row = s.QueryRow(`SELECT COUNT(*) FROM users WHERE auth_provider_id = (SELECT id FROM auth_providers WHERE public_id = ?)`, strings.TrimSpace(id))
|
||||
err = row.Scan(&count)
|
||||
err = execer.QueryRow(`SELECT COUNT(*) FROM users WHERE auth_provider_id = (SELECT id FROM auth_providers WHERE public_id = ?)`, strings.TrimSpace(id)).Scan(&count)
|
||||
return count, err
|
||||
}
|
||||
|
||||
func (s *Store) CreateAuthProvider(item models.AuthProvider) (models.AuthProvider, error) {
|
||||
func (s *Store) CreateAuthProvider(ctx context.Context, item models.AuthProvider) (models.AuthProvider, error) {
|
||||
var tx txExecutor
|
||||
var err error
|
||||
var owned bool
|
||||
@@ -293,7 +296,7 @@ func (s *Store) CreateAuthProvider(item models.AuthProvider) (models.AuthProvide
|
||||
item.GroupSyncMode, err = normalizeAuthProviderGroupSyncMode(item.GroupSyncMode)
|
||||
if err != nil { return item, err }
|
||||
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil { return item, err }
|
||||
|
||||
_, err = tx.Exec(`INSERT INTO auth_providers (
|
||||
@@ -331,7 +334,7 @@ func (s *Store) CreateAuthProvider(item models.AuthProvider) (models.AuthProvide
|
||||
return s.GetAuthProviderWithGroupMappings(item.ID)
|
||||
}
|
||||
|
||||
func (s *Store) UpdateAuthProvider(item models.AuthProvider) (models.AuthProvider, error) {
|
||||
func (s *Store) UpdateAuthProvider(ctx context.Context, item models.AuthProvider) (models.AuthProvider, error) {
|
||||
var tx txExecutor
|
||||
var err error
|
||||
var owned bool
|
||||
@@ -351,7 +354,7 @@ func (s *Store) UpdateAuthProvider(item models.AuthProvider) (models.AuthProvide
|
||||
return item, err
|
||||
}
|
||||
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil { return item, err }
|
||||
|
||||
_, err = tx.Exec(`UPDATE auth_providers SET
|
||||
@@ -395,22 +398,32 @@ func (s *Store) UpdateAuthProvider(item models.AuthProvider) (models.AuthProvide
|
||||
return s.GetAuthProviderWithGroupMappings(item.ID)
|
||||
}
|
||||
|
||||
func (s *Store) DeleteAuthProvider(id string, force bool) error {
|
||||
func (s *Store) DeleteAuthProvider(ctx context.Context, id string, force bool) error {
|
||||
var count int
|
||||
var err error
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
|
||||
if strings.TrimSpace(id) == BuiltinDBProviderPublicID {
|
||||
return errors.New("builtin provider cannot be deleted")
|
||||
}
|
||||
tx, owned, err = s.beginImmediateContext(ctx)
|
||||
if err != nil { return err }
|
||||
if !force {
|
||||
count, err = s.CountAuthProviderUsers(id)
|
||||
count, err = countAuthProviderUsers(tx, id)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return errors.New("provider has associated users")
|
||||
}
|
||||
}
|
||||
_, err = s.Exec(`DELETE FROM auth_providers WHERE public_id = ?`, strings.TrimSpace(id))
|
||||
return err
|
||||
_, err = tx.Exec(`DELETE FROM auth_providers WHERE public_id = ?`, strings.TrimSpace(id))
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return err
|
||||
}
|
||||
return commitIfOwned(tx, owned)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package db
|
||||
|
||||
import "context"
|
||||
import "database/sql"
|
||||
import "errors"
|
||||
import "strings"
|
||||
@@ -59,13 +60,15 @@ func (s *Store) ListBlockComments(boardID, blockID string) ([]models.BlockCommen
|
||||
return comments, rows.Err()
|
||||
}
|
||||
|
||||
func (s *Store) CreateBlockComment(boardID, blockID, content, userID string) (models.BlockComment, error) {
|
||||
func (s *Store) CreateBlockComment(ctx context.Context, boardID, blockID, content, userID string) (models.BlockComment, error) {
|
||||
var id string
|
||||
var err error
|
||||
var now int64
|
||||
var internalBlockID int64
|
||||
var internalUserID int64
|
||||
var bc models.BlockComment
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
|
||||
id, err = util.NewID()
|
||||
if err != nil {
|
||||
@@ -73,37 +76,50 @@ func (s *Store) CreateBlockComment(boardID, blockID, content, userID string) (mo
|
||||
}
|
||||
now = time.Now().Unix()
|
||||
|
||||
err = s.QueryRow(`
|
||||
tx, owned, err = s.beginImmediateContext(ctx)
|
||||
if err != nil {
|
||||
return bc, err
|
||||
}
|
||||
err = tx.QueryRow(`
|
||||
SELECT bl.id FROM blocks bl
|
||||
JOIN boards brd ON brd.id = bl.board_id
|
||||
WHERE brd.public_id = ? AND bl.public_id = ? AND bl.delete_at = 0`,
|
||||
boardID, blockID).Scan(&internalBlockID)
|
||||
if err == sql.ErrNoRows {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return bc, sql.ErrNoRows
|
||||
}
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return bc, err
|
||||
}
|
||||
|
||||
err = s.QueryRow(`SELECT id FROM users WHERE public_id = ?`, userID).Scan(&internalUserID)
|
||||
err = tx.QueryRow(`SELECT id FROM users WHERE public_id = ?`, userID).Scan(&internalUserID)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return bc, err
|
||||
}
|
||||
|
||||
_, err = s.Exec(`
|
||||
_, err = tx.Exec(`
|
||||
INSERT INTO block_comments (public_id, block_id, content, created_by, created_at, updated_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?)`,
|
||||
id, internalBlockID, content, internalUserID, now, now)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return bc, err
|
||||
}
|
||||
|
||||
err = s.QueryRow(
|
||||
err = tx.QueryRow(
|
||||
`SELECT`+blockCommentSelectCols+blockCommentSelectFrom+`
|
||||
WHERE c.public_id = ?`, id).Scan(
|
||||
&bc.ID, &bc.BlockID, &bc.Content,
|
||||
&bc.CreatedBy, &bc.CreatedByName,
|
||||
&bc.CreatedAt, &bc.UpdatedAt, &bc.DeleteAt)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return bc, err
|
||||
}
|
||||
err = commitIfOwned(tx, owned)
|
||||
if err != nil {
|
||||
return bc, err
|
||||
}
|
||||
@@ -189,7 +205,7 @@ func (s *Store) ListBlockChecklistItems(boardID, blockID string) ([]models.Block
|
||||
return items, rows.Err()
|
||||
}
|
||||
|
||||
func (s *Store) CreateBlockChecklistItem(boardID, blockID, title, userID string) (models.BlockChecklistItem, error) {
|
||||
func (s *Store) CreateBlockChecklistItem(ctx context.Context, boardID, blockID, title, userID string) (models.BlockChecklistItem, error) {
|
||||
var id string
|
||||
var err error
|
||||
var now int64
|
||||
@@ -197,6 +213,8 @@ func (s *Store) CreateBlockChecklistItem(boardID, blockID, title, userID string)
|
||||
var internalUserID int64
|
||||
var maxOrder int64
|
||||
var item models.BlockChecklistItem
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
|
||||
id, err = util.NewID()
|
||||
if err != nil {
|
||||
@@ -204,40 +222,57 @@ func (s *Store) CreateBlockChecklistItem(boardID, blockID, title, userID string)
|
||||
}
|
||||
now = time.Now().Unix()
|
||||
|
||||
err = s.QueryRow(`
|
||||
tx, owned, err = s.beginImmediateContext(ctx)
|
||||
if err != nil {
|
||||
return item, err
|
||||
}
|
||||
err = tx.QueryRow(`
|
||||
SELECT bl.id FROM blocks bl
|
||||
JOIN boards brd ON brd.id = bl.board_id
|
||||
WHERE brd.public_id = ? AND bl.public_id = ? AND bl.delete_at = 0`,
|
||||
boardID, blockID).Scan(&internalBlockID)
|
||||
if err == sql.ErrNoRows {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return item, sql.ErrNoRows
|
||||
}
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return item, err
|
||||
}
|
||||
|
||||
err = s.QueryRow(`SELECT id FROM users WHERE public_id = ?`, userID).Scan(&internalUserID)
|
||||
err = tx.QueryRow(`SELECT id FROM users WHERE public_id = ?`, userID).Scan(&internalUserID)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return item, err
|
||||
}
|
||||
|
||||
err = s.QueryRow(`SELECT COALESCE(MAX(display_order), -1) FROM block_checklist_items WHERE block_id = ? AND delete_at = 0`, internalBlockID).Scan(&maxOrder)
|
||||
err = tx.QueryRow(`SELECT COALESCE(MAX(display_order), -1) FROM block_checklist_items WHERE block_id = ? AND delete_at = 0`, internalBlockID).Scan(&maxOrder)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return item, err
|
||||
}
|
||||
|
||||
_, err = s.Exec(`
|
||||
_, err = tx.Exec(`
|
||||
INSERT INTO block_checklist_items (public_id, block_id, title, done, display_order, created_by, updated_by, created_at, updated_at)
|
||||
VALUES (?, ?, ?, 0, ?, ?, ?, ?, ?)`,
|
||||
id, internalBlockID, title, maxOrder+1, internalUserID, internalUserID, now, now)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return item, err
|
||||
}
|
||||
|
||||
err = scanBlockChecklistItem(
|
||||
s.QueryRow(`SELECT`+blockChecklistItemSelectCols+blockChecklistItemSelectFrom+` WHERE ci.public_id = ?`, id),
|
||||
tx.QueryRow(`SELECT`+blockChecklistItemSelectCols+blockChecklistItemSelectFrom+` WHERE ci.public_id = ?`, id),
|
||||
&item)
|
||||
return item, err
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return item, err
|
||||
}
|
||||
err = commitIfOwned(tx, owned)
|
||||
if err != nil {
|
||||
return item, err
|
||||
}
|
||||
return item, nil
|
||||
}
|
||||
|
||||
func (s *Store) UpdateBlockChecklistItem(boardID, blockID, itemID, title string, done bool, userID string) (models.BlockChecklistItem, error) {
|
||||
@@ -303,7 +338,7 @@ func (s *Store) DeleteBlockChecklistItem(boardID, blockID, itemID string) error
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Store) ReorderBlockChecklistItems(boardID, blockID string, ids []string) ([]models.BlockChecklistItem, error) {
|
||||
func (s *Store) ReorderBlockChecklistItems(ctx context.Context, boardID, blockID string, ids []string) ([]models.BlockChecklistItem, error) {
|
||||
var internalBlockID int64
|
||||
var err error
|
||||
var now int64
|
||||
@@ -315,7 +350,7 @@ func (s *Store) ReorderBlockChecklistItems(boardID, blockID string, ids []string
|
||||
var n int64
|
||||
|
||||
now = time.Now().Unix()
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -411,44 +446,62 @@ func (s *Store) ListBlockAttachments(boardID, blockID string) ([]models.BlockAtt
|
||||
return items, rows.Err()
|
||||
}
|
||||
|
||||
func (s *Store) CreateBlockAttachment(boardID, blockID string, item models.BlockAttachment) (models.BlockAttachment, error) {
|
||||
func (s *Store) CreateBlockAttachment(ctx context.Context, boardID, blockID string, item models.BlockAttachment) (models.BlockAttachment, error) {
|
||||
var err error
|
||||
var internalBlockID int64
|
||||
var internalUserID int64
|
||||
var now int64
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
|
||||
now = time.Now().Unix()
|
||||
err = s.QueryRow(`
|
||||
tx, owned, err = s.beginImmediateContext(ctx)
|
||||
if err != nil {
|
||||
return item, err
|
||||
}
|
||||
err = tx.QueryRow(`
|
||||
SELECT bl.id FROM blocks bl
|
||||
JOIN boards brd ON brd.id = bl.board_id
|
||||
WHERE brd.public_id = ? AND bl.public_id = ? AND bl.delete_at = 0`,
|
||||
boardID, blockID).Scan(&internalBlockID)
|
||||
if err == sql.ErrNoRows {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return item, sql.ErrNoRows
|
||||
}
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return item, err
|
||||
}
|
||||
|
||||
err = s.QueryRow(`SELECT id FROM users WHERE public_id = ?`, item.CreatedBy).Scan(&internalUserID)
|
||||
err = tx.QueryRow(`SELECT id FROM users WHERE public_id = ?`, item.CreatedBy).Scan(&internalUserID)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return item, err
|
||||
}
|
||||
|
||||
item.BlockID = blockID
|
||||
item.CreatedAt = now
|
||||
_, err = s.Exec(`
|
||||
_, err = tx.Exec(`
|
||||
INSERT INTO block_attachments (public_id, block_id, filename, content_type, size, storage_path, created_by, created_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
item.ID, internalBlockID, item.Filename, item.ContentType, item.Size, item.StoragePath, internalUserID, now)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return item, err
|
||||
}
|
||||
|
||||
err = scanBlockAttachment(
|
||||
s.QueryRow(`SELECT`+blockAttachmentSelectCols+blockAttachmentSelectFrom+` WHERE ba.public_id = ?`, item.ID),
|
||||
tx.QueryRow(`SELECT`+blockAttachmentSelectCols+blockAttachmentSelectFrom+` WHERE ba.public_id = ?`, item.ID),
|
||||
&item)
|
||||
return item, err
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return item, err
|
||||
}
|
||||
err = commitIfOwned(tx, owned)
|
||||
if err != nil {
|
||||
return item, err
|
||||
}
|
||||
return item, nil
|
||||
}
|
||||
|
||||
func (s *Store) GetBlockAttachment(boardID, blockID, attachmentID string) (models.BlockAttachment, error) {
|
||||
@@ -467,20 +520,36 @@ func (s *Store) GetBlockAttachment(boardID, blockID, attachmentID string) (model
|
||||
return item, err
|
||||
}
|
||||
|
||||
func (s *Store) DeleteBlockAttachment(boardID, blockID, attachmentID string) (models.BlockAttachment, error) {
|
||||
func (s *Store) DeleteBlockAttachment(ctx context.Context, boardID, blockID, attachmentID string) (models.BlockAttachment, error) {
|
||||
var item models.BlockAttachment
|
||||
var now int64
|
||||
var result sql.Result
|
||||
var n int64
|
||||
var err error
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
|
||||
item, err = s.GetBlockAttachment(boardID, blockID, attachmentID)
|
||||
tx, owned, err = s.beginImmediateContext(ctx)
|
||||
if err != nil {
|
||||
return item, err
|
||||
}
|
||||
err = scanBlockAttachment(
|
||||
tx.QueryRow(`SELECT`+blockAttachmentSelectCols+blockAttachmentSelectFrom+`
|
||||
JOIN boards brd ON brd.id = bl.board_id
|
||||
WHERE brd.public_id = ? AND bl.public_id = ? AND bl.delete_at = 0 AND ba.public_id = ? AND ba.delete_at = 0`,
|
||||
boardID, blockID, attachmentID),
|
||||
&item)
|
||||
if err == sql.ErrNoRows {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return item, ErrBlockAttachmentNotFound
|
||||
}
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return item, err
|
||||
}
|
||||
|
||||
now = time.Now().Unix()
|
||||
result, err = s.Exec(`
|
||||
result, err = tx.Exec(`
|
||||
UPDATE block_attachments SET delete_at = ?
|
||||
WHERE public_id = ?
|
||||
AND delete_at = 0
|
||||
@@ -490,16 +559,23 @@ func (s *Store) DeleteBlockAttachment(boardID, blockID, attachmentID string) (mo
|
||||
WHERE brd.public_id = ? AND bl.public_id = ? AND bl.delete_at = 0
|
||||
)`, now, attachmentID, boardID, blockID)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return item, err
|
||||
}
|
||||
n, err = result.RowsAffected()
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return item, err
|
||||
}
|
||||
if n == 0 {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return item, ErrBlockAttachmentNotFound
|
||||
}
|
||||
item.DeleteAt = now
|
||||
err = commitIfOwned(tx, owned)
|
||||
if err != nil {
|
||||
return item, err
|
||||
}
|
||||
return item, nil
|
||||
}
|
||||
|
||||
@@ -701,7 +777,7 @@ func (s *Store) listBlockAssigneesForBoard(boardID string) (map[string][]models.
|
||||
return result, rows.Err()
|
||||
}
|
||||
|
||||
func (s *Store) UpsertBlockProperties(boardID, blockID string, props models.BlockProperties) (models.BlockProperties, error) {
|
||||
func (s *Store) UpsertBlockProperties(ctx context.Context, boardID, blockID string, props models.BlockProperties) (models.BlockProperties, error) {
|
||||
var internalBlockID int64
|
||||
var err error
|
||||
var tx txExecutor
|
||||
@@ -712,7 +788,7 @@ func (s *Store) UpsertBlockProperties(boardID, blockID string, props models.Bloc
|
||||
var affected int64
|
||||
|
||||
assigneeIDs = normalizeBlockAssigneeIDs(props)
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil {
|
||||
return props, err
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package db
|
||||
|
||||
import "context"
|
||||
import "database/sql"
|
||||
import "errors"
|
||||
import "fmt"
|
||||
@@ -65,7 +66,7 @@ func (s *Store) SeedDefaultBoardFieldValues(boardID string) error {
|
||||
Label: item.Label,
|
||||
Color: item.Color,
|
||||
}
|
||||
_, err = s.CreateBoardFieldValue(boardID, fv)
|
||||
_, err = s.CreateBoardFieldValue(context.Background(), boardID, fv)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -74,12 +75,16 @@ func (s *Store) SeedDefaultBoardFieldValues(boardID string) error {
|
||||
}
|
||||
|
||||
func (s *Store) ListBoardFieldValues(boardID, field string) ([]models.BoardFieldValue, error) {
|
||||
return listBoardFieldValues(s, boardID, field)
|
||||
}
|
||||
|
||||
func listBoardFieldValues(execer sqlExecutor, boardID string, field string) ([]models.BoardFieldValue, error) {
|
||||
var rows *sql.Rows
|
||||
var err error
|
||||
var result []models.BoardFieldValue
|
||||
var fv models.BoardFieldValue
|
||||
|
||||
rows, err = s.Query(
|
||||
rows, err = execer.Query(
|
||||
`SELECT`+fieldValueCols+fieldValueFrom+`
|
||||
WHERE brd.public_id = ? AND fv.field = ?
|
||||
ORDER BY fv.display_order ASC, fv.created_at ASC`, boardID, field)
|
||||
@@ -98,13 +103,15 @@ func (s *Store) ListBoardFieldValues(boardID, field string) ([]models.BoardField
|
||||
return result, rows.Err()
|
||||
}
|
||||
|
||||
func (s *Store) CreateBoardFieldValue(boardID string, fv models.BoardFieldValue) (models.BoardFieldValue, error) {
|
||||
func (s *Store) CreateBoardFieldValue(ctx context.Context, boardID string, fv models.BoardFieldValue) (models.BoardFieldValue, error) {
|
||||
var id string
|
||||
var err error
|
||||
var now int64
|
||||
var internalBoardID int64
|
||||
var maxOrder int64
|
||||
var result models.BoardFieldValue
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
|
||||
id, err = util.NewID()
|
||||
if err != nil {
|
||||
@@ -112,35 +119,51 @@ func (s *Store) CreateBoardFieldValue(boardID string, fv models.BoardFieldValue)
|
||||
}
|
||||
now = time.Now().Unix()
|
||||
|
||||
err = s.QueryRow(`SELECT id FROM boards WHERE public_id = ? AND delete_at = 0`, boardID).Scan(&internalBoardID)
|
||||
tx, owned, err = s.beginImmediateContext(ctx)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
err = tx.QueryRow(`SELECT id FROM boards WHERE public_id = ? AND delete_at = 0`, boardID).Scan(&internalBoardID)
|
||||
if err == sql.ErrNoRows {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return result, ErrBoardNotFound
|
||||
}
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return result, err
|
||||
}
|
||||
|
||||
err = s.QueryRow(
|
||||
err = tx.QueryRow(
|
||||
`SELECT COALESCE(MAX(display_order), -1) FROM board_field_values WHERE board_id = ? AND field = ?`,
|
||||
internalBoardID, fv.Field).Scan(&maxOrder)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return result, err
|
||||
}
|
||||
|
||||
_, err = s.Exec(`
|
||||
_, err = tx.Exec(`
|
||||
INSERT INTO board_field_values
|
||||
(public_id, board_id, field, value, label, color, display_order, start_date, end_date, created_at, updated_at)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
id, internalBoardID, fv.Field, fv.Value, fv.Label, fv.Color,
|
||||
maxOrder+1, fv.StartDate, fv.EndDate, now, now)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return result, err
|
||||
}
|
||||
|
||||
err = scanFieldValue(
|
||||
s.QueryRow(`SELECT`+fieldValueCols+fieldValueFrom+` WHERE fv.public_id = ?`, id),
|
||||
tx.QueryRow(`SELECT`+fieldValueCols+fieldValueFrom+` WHERE fv.public_id = ?`, id),
|
||||
&result)
|
||||
return result, err
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return result, err
|
||||
}
|
||||
err = commitIfOwned(tx, owned)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *Store) UpdateBoardFieldValue(boardID, valueID string, fv models.BoardFieldValue) (models.BoardFieldValue, error) {
|
||||
@@ -188,13 +211,17 @@ func blockPropsCol(field string) (string, bool) {
|
||||
return col, ok
|
||||
}
|
||||
|
||||
func (s *Store) CountBoardFieldValueRefs(boardID, field, value string) (int, error) {
|
||||
var col, ok = blockPropsCol(field)
|
||||
func countBoardFieldValueRefs(execer sqlExecutor, boardID string, field string, value string) (int, error) {
|
||||
var col string
|
||||
var ok bool
|
||||
var count int
|
||||
var err error
|
||||
|
||||
col, ok = blockPropsCol(field)
|
||||
if !ok {
|
||||
return 0, nil
|
||||
}
|
||||
var count int
|
||||
var err = s.QueryRow(
|
||||
err = execer.QueryRow(
|
||||
fmt.Sprintf(`
|
||||
SELECT COUNT(*) FROM block_properties bp
|
||||
JOIN blocks bl ON bl.id = bp.block_id
|
||||
@@ -204,74 +231,124 @@ func (s *Store) CountBoardFieldValueRefs(boardID, field, value string) (int, err
|
||||
return count, err
|
||||
}
|
||||
|
||||
func (s *Store) ReorderBoardFieldValues(boardID, field string, ids []string) ([]models.BoardFieldValue, error) {
|
||||
func (s *Store) CountBoardFieldValueRefs(boardID, field, value string) (int, error) {
|
||||
return countBoardFieldValueRefs(s, boardID, field, value)
|
||||
}
|
||||
|
||||
func (s *Store) ReorderBoardFieldValues(ctx context.Context, boardID, field string, ids []string) ([]models.BoardFieldValue, error) {
|
||||
var internalBoardID int64
|
||||
var err error
|
||||
var now int64
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
var i int
|
||||
var id string
|
||||
var result []models.BoardFieldValue
|
||||
var execResult sql.Result
|
||||
var n int64
|
||||
|
||||
now = time.Now().Unix()
|
||||
err = s.QueryRow(`SELECT id FROM boards WHERE public_id = ? AND delete_at = 0`, boardID).Scan(&internalBoardID)
|
||||
if err == sql.ErrNoRows {
|
||||
return nil, ErrBoardNotFound
|
||||
}
|
||||
tx, owned, err = s.beginImmediateContext(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = tx.QueryRow(`SELECT id FROM boards WHERE public_id = ? AND delete_at = 0`, boardID).Scan(&internalBoardID)
|
||||
if err == sql.ErrNoRows {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return nil, ErrBoardNotFound
|
||||
}
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i, id := range ids {
|
||||
_, err = s.Exec(`
|
||||
for i = 0; i < len(ids); i++ {
|
||||
id = ids[i]
|
||||
execResult, err = tx.Exec(`
|
||||
UPDATE board_field_values SET display_order = ?, updated_at = ?
|
||||
WHERE public_id = ? AND board_id = ? AND field = ?`,
|
||||
i, now, id, internalBoardID, field)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return nil, err
|
||||
}
|
||||
n, err = execResult.RowsAffected()
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return nil, err
|
||||
}
|
||||
if n == 0 {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return nil, ErrFieldValueNotFound
|
||||
}
|
||||
}
|
||||
|
||||
return s.ListBoardFieldValues(boardID, field)
|
||||
result, err = listBoardFieldValues(tx, boardID, field)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return nil, err
|
||||
}
|
||||
err = commitIfOwned(tx, owned)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *Store) DeleteBoardFieldValue(boardID, valueID string) error {
|
||||
func (s *Store) DeleteBoardFieldValue(ctx context.Context, boardID, valueID string) error {
|
||||
var err error
|
||||
var res sql.Result
|
||||
var n int64
|
||||
var value string
|
||||
var field string
|
||||
var count int
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
|
||||
err = s.QueryRow(`
|
||||
tx, owned, err = s.beginImmediateContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = tx.QueryRow(`
|
||||
SELECT fv.value, fv.field FROM board_field_values fv
|
||||
JOIN boards brd ON brd.id = fv.board_id
|
||||
WHERE fv.public_id = ? AND brd.public_id = ?`, valueID, boardID).Scan(&value, &field)
|
||||
if err == sql.ErrNoRows {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return ErrFieldValueNotFound
|
||||
}
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return err
|
||||
}
|
||||
|
||||
var count int
|
||||
count, err = s.CountBoardFieldValueRefs(boardID, field, value)
|
||||
count, err = countBoardFieldValueRefs(tx, boardID, field, value)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return fmt.Errorf("%w: %d card(s)", ErrFieldValueInUse, count)
|
||||
}
|
||||
|
||||
res, err = s.Exec(`
|
||||
res, err = tx.Exec(`
|
||||
DELETE FROM board_field_values
|
||||
WHERE public_id = ?
|
||||
AND board_id = (SELECT id FROM boards WHERE public_id = ? AND delete_at = 0)`,
|
||||
valueID, boardID)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return err
|
||||
}
|
||||
n, err = res.RowsAffected()
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return err
|
||||
}
|
||||
if n == 0 {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return ErrFieldValueNotFound
|
||||
}
|
||||
return nil
|
||||
return commitIfOwned(tx, owned)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package db
|
||||
|
||||
import "context"
|
||||
import "database/sql"
|
||||
import "errors"
|
||||
import "time"
|
||||
@@ -39,7 +40,7 @@ func scanBoard(row interface{ Scan(...any) error }, b *models.Board) error {
|
||||
)
|
||||
}
|
||||
|
||||
func (s *Store) CreateBoard(board models.Board) (models.Board, error) {
|
||||
func (s *Store) CreateBoard(ctx context.Context, board models.Board) (models.Board, error) {
|
||||
var id string
|
||||
var err error
|
||||
var nowUnix int64
|
||||
@@ -60,7 +61,7 @@ func (s *Store) CreateBoard(board models.Board) (models.Board, error) {
|
||||
board.CardProperties = "[]"
|
||||
}
|
||||
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil {
|
||||
return board, err
|
||||
}
|
||||
@@ -377,7 +378,7 @@ func (s *Store) insertBlockHistory(tx txExecutor, blockID int64, insertAt int64)
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *Store) CreateBlock(block models.Block) (models.Block, error) {
|
||||
func (s *Store) CreateBlock(ctx context.Context, block models.Block) (models.Block, error) {
|
||||
var id string
|
||||
var err error
|
||||
var nowUnix int64
|
||||
@@ -401,7 +402,7 @@ func (s *Store) CreateBlock(block models.Block) (models.Block, error) {
|
||||
block.Fields = "{}"
|
||||
}
|
||||
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil {
|
||||
return block, err
|
||||
}
|
||||
@@ -512,7 +513,7 @@ func (s *Store) ListBlocksByType(boardID string, blockType string) ([]models.Blo
|
||||
return blocks, rows.Err()
|
||||
}
|
||||
|
||||
func (s *Store) UpdateBlock(block models.Block) (models.Block, error) {
|
||||
func (s *Store) UpdateBlock(ctx context.Context, block models.Block) (models.Block, error) {
|
||||
var err error
|
||||
var nowUnix int64
|
||||
var tx txExecutor
|
||||
@@ -525,7 +526,7 @@ func (s *Store) UpdateBlock(block models.Block) (models.Block, error) {
|
||||
nowUnix = time.Now().UTC().Unix()
|
||||
block.UpdatedAt = nowUnix
|
||||
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil {
|
||||
return block, err
|
||||
}
|
||||
@@ -591,7 +592,7 @@ func (s *Store) UpdateBlock(block models.Block) (models.Block, error) {
|
||||
return s.GetBlock(block.BoardID, block.ID)
|
||||
}
|
||||
|
||||
func (s *Store) PatchBlocks(boardID string, patches []models.BlockPatch, updatedBy string) error {
|
||||
func (s *Store) PatchBlocks(ctx context.Context, boardID string, patches []models.BlockPatch, updatedBy string) error {
|
||||
var err error
|
||||
var nowUnix int64
|
||||
var tx txExecutor
|
||||
@@ -608,7 +609,7 @@ func (s *Store) PatchBlocks(boardID string, patches []models.BlockPatch, updated
|
||||
}
|
||||
nowUnix = time.Now().UTC().Unix()
|
||||
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -701,7 +702,7 @@ func (s *Store) PatchBlocks(boardID string, patches []models.BlockPatch, updated
|
||||
return commitIfOwned(tx, owned)
|
||||
}
|
||||
|
||||
func (s *Store) DeleteBlock(boardID string, id string, updatedBy string) error {
|
||||
func (s *Store) DeleteBlock(ctx context.Context, boardID string, id string, updatedBy string) error {
|
||||
var err error
|
||||
var nowUnix int64
|
||||
var tx txExecutor
|
||||
@@ -713,7 +714,7 @@ func (s *Store) DeleteBlock(boardID string, id string, updatedBy string) error {
|
||||
var dID int64
|
||||
|
||||
nowUnix = time.Now().UTC().Unix()
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -886,39 +887,48 @@ func (s *Store) ListBoardAssignableUsers(boardID string) ([]models.BoardAssignab
|
||||
return users, rows.Err()
|
||||
}
|
||||
|
||||
func (s *Store) UpsertBoardMember(member models.BoardMember) error {
|
||||
func (s *Store) UpsertBoardMember(ctx context.Context, member models.BoardMember) error {
|
||||
var err error
|
||||
var nowUnix int64
|
||||
var boardInternalID int64
|
||||
var userInternalID int64
|
||||
var row *sql.Row
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
|
||||
nowUnix = time.Now().UTC().Unix()
|
||||
if member.CreatedAt == 0 {
|
||||
member.CreatedAt = nowUnix
|
||||
}
|
||||
row = s.QueryRow(`SELECT id FROM boards WHERE public_id = ? AND delete_at = 0`, member.BoardID)
|
||||
err = row.Scan(&boardInternalID)
|
||||
tx, owned, err = s.beginImmediateContext(ctx)
|
||||
if err != nil { return err }
|
||||
err = tx.QueryRow(`SELECT id FROM boards WHERE public_id = ? AND delete_at = 0`, member.BoardID).Scan(&boardInternalID)
|
||||
if err == sql.ErrNoRows {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return ErrBoardNotFound
|
||||
}
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return err
|
||||
}
|
||||
row = s.QueryRow(`SELECT id FROM users WHERE public_id = ?`, member.UserID)
|
||||
err = row.Scan(&userInternalID)
|
||||
err = tx.QueryRow(`SELECT id FROM users WHERE public_id = ?`, member.UserID).Scan(&userInternalID)
|
||||
if err == sql.ErrNoRows {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return ErrUserNotFound
|
||||
}
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return err
|
||||
}
|
||||
_, err = s.Exec(`
|
||||
_, err = tx.Exec(`
|
||||
INSERT INTO board_members (board_id, user_id, role, created_at)
|
||||
VALUES (?, ?, ?, ?)
|
||||
ON CONFLICT(board_id, user_id) DO UPDATE SET role = excluded.role`,
|
||||
boardInternalID, userInternalID, member.Role, member.CreatedAt)
|
||||
return err
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return err
|
||||
}
|
||||
return commitIfOwned(tx, owned)
|
||||
}
|
||||
|
||||
func (s *Store) DeleteBoardMember(boardID string, userID string) error {
|
||||
|
||||
@@ -196,6 +196,11 @@ func (s *Store) QueryRow(query string, args ...any) *sql.Row {
|
||||
return s.execer().QueryRow(query, args...)
|
||||
}
|
||||
|
||||
func normalizeStoreContext(ctx context.Context) context.Context {
|
||||
if ctx == nil { return context.Background() }
|
||||
return ctx
|
||||
}
|
||||
|
||||
func (s *Store) BeginStore(ctx context.Context) (*Store, error) {
|
||||
var tx *sql.Tx
|
||||
var err error
|
||||
@@ -203,6 +208,7 @@ func (s *Store) BeginStore(ctx context.Context) (*Store, error) {
|
||||
if s == nil { return nil, fmt.Errorf("nil store") }
|
||||
if s.tx != nil { return s, nil } // more than one BeginStore calls, return the existing tx
|
||||
|
||||
ctx = normalizeStoreContext(ctx)
|
||||
tx, err = s.DB.BeginTx(ctx, nil)
|
||||
if err != nil { return nil, err }
|
||||
|
||||
@@ -215,6 +221,7 @@ func (s *Store) BeginImmediateStore(ctx context.Context) (*Store, error) {
|
||||
var tx *manualTx
|
||||
var err error
|
||||
|
||||
ctx = normalizeStoreContext(ctx)
|
||||
if s.tx != nil { return s, nil }
|
||||
if !s.imm { return s.BeginStore(ctx) }
|
||||
|
||||
@@ -244,22 +251,47 @@ func (s *Store) Rollback() error {
|
||||
return s.tx.Rollback()
|
||||
}
|
||||
|
||||
func (s *Store) begin() (txExecutor, bool, error) {
|
||||
//func (s *Store) begin() (txExecutor, bool, error) {
|
||||
// return s.beginContext(context.Background())
|
||||
//}
|
||||
|
||||
func (s *Store) beginContext(ctx context.Context) (txExecutor, bool, error) {
|
||||
var tx *sql.Tx
|
||||
var err error
|
||||
|
||||
ctx = normalizeStoreContext(ctx)
|
||||
if s == nil { return nil, false, fmt.Errorf("nil store") }
|
||||
|
||||
// return an existing transaction object that's already started by
|
||||
// BeginStore() and BeginImmediateStore().
|
||||
// the second return value is false because the transaction is not started here.
|
||||
if s != nil && s.tx != nil { return s.tx, false, nil }
|
||||
if s.tx != nil { return s.tx, false, nil }
|
||||
|
||||
tx, err = s.DB.Begin()
|
||||
tx, err = s.DB.BeginTx(ctx, nil)
|
||||
if err != nil { return nil, false, err }
|
||||
|
||||
// the second return value is true to indicate that the transaction has been started here
|
||||
return tx, true, nil
|
||||
}
|
||||
|
||||
//func (s *Store) beginImmediate() (txExecutor, bool, error) {
|
||||
// return s.beginImmediateContext(context.Background())
|
||||
//}
|
||||
|
||||
func (s *Store) beginImmediateContext(ctx context.Context) (txExecutor, bool, error) {
|
||||
var child *Store
|
||||
var err error
|
||||
|
||||
ctx = normalizeStoreContext(ctx)
|
||||
if s == nil { return nil, false, fmt.Errorf("nil store") }
|
||||
if s.tx != nil { return s.tx, false, nil }
|
||||
|
||||
child, err = s.BeginImmediateStore(ctx)
|
||||
if err != nil { return nil, false, err }
|
||||
|
||||
return child.tx, true, nil
|
||||
}
|
||||
|
||||
func rollbackIfOwned(tx txExecutor, owned bool) {
|
||||
if tx != nil && owned { _ = tx.Rollback() }
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package db
|
||||
|
||||
import "context"
|
||||
import "database/sql"
|
||||
import "errors"
|
||||
import "strings"
|
||||
@@ -87,26 +88,33 @@ func (s *Store) CreateUserGroup(item models.UserGroup) (models.UserGroup, error)
|
||||
return item, nil
|
||||
}
|
||||
|
||||
func (s *Store) UpdateUserGroup(item models.UserGroup) (models.UserGroup, error) {
|
||||
func (s *Store) UpdateUserGroup(ctx context.Context, item models.UserGroup) (models.UserGroup, error) {
|
||||
var now int64
|
||||
var err error
|
||||
var mappingCount int
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
|
||||
now = time.Now().UTC().Unix()
|
||||
item.UpdatedAt = now
|
||||
item.Scope = NormalizeUserGroupScope(item.Scope)
|
||||
tx, owned, err = s.beginImmediateContext(ctx)
|
||||
if err != nil { return item, err }
|
||||
if item.Scope != UserGroupScopeExplicit {
|
||||
err = s.QueryRow(`SELECT COUNT(*)
|
||||
err = tx.QueryRow(`SELECT COUNT(*)
|
||||
FROM auth_provider_group_mappings m
|
||||
JOIN user_groups g ON g.id = m.group_id
|
||||
WHERE g.public_id = ?`, strings.TrimSpace(item.ID)).Scan(&mappingCount)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return item, err
|
||||
}
|
||||
if mappingCount > 0 {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return item, errors.New("group is used by auth provider group mappings")
|
||||
}
|
||||
}
|
||||
_, err = s.Exec(`UPDATE user_groups
|
||||
_, err = tx.Exec(`UPDATE user_groups
|
||||
SET name = ?, description = ?, disabled = ?, totp_required = ?, scope = ?, updated_at = ?
|
||||
WHERE public_id = ?`,
|
||||
strings.TrimSpace(item.Name),
|
||||
@@ -118,22 +126,27 @@ func (s *Store) UpdateUserGroup(item models.UserGroup) (models.UserGroup, error)
|
||||
strings.TrimSpace(item.ID),
|
||||
)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return item, err
|
||||
}
|
||||
item, err = s.GetUserGroup(item.ID)
|
||||
err = tx.QueryRow(`SELECT public_id, name, description, disabled, totp_required, scope, created_at, updated_at
|
||||
FROM user_groups WHERE public_id = ?`, strings.TrimSpace(item.ID)).Scan(&item.ID, &item.Name, &item.Description, &item.Disabled, &item.TOTPRequired, &item.Scope, &item.CreatedAt, &item.UpdatedAt)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return item, err
|
||||
}
|
||||
err = commitIfOwned(tx, owned)
|
||||
if err != nil { return item, err }
|
||||
return item, nil
|
||||
}
|
||||
|
||||
func (s *Store) DeleteUserGroup(groupID string) error {
|
||||
func (s *Store) DeleteUserGroup(ctx context.Context, groupID string) error {
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
var err error
|
||||
var scope string
|
||||
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil { return err }
|
||||
|
||||
err = tx.QueryRow(`SELECT scope FROM user_groups WHERE public_id = ?`, strings.TrimSpace(groupID)).Scan(&scope)
|
||||
@@ -214,44 +227,67 @@ func (s *Store) ListUserGroupMembers(groupID string) ([]models.UserGroupMember,
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func (s *Store) AddUserGroupMember(groupID string, userID string) error {
|
||||
func (s *Store) AddUserGroupMember(ctx context.Context, groupID string, userID string) error {
|
||||
var now int64
|
||||
var err error
|
||||
var group models.UserGroup
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
var scope string
|
||||
|
||||
group, err = s.GetUserGroup(groupID)
|
||||
tx, owned, err = s.beginImmediateContext(ctx)
|
||||
if err != nil { return err }
|
||||
|
||||
if NormalizeUserGroupScope(group.Scope) != UserGroupScopeExplicit {
|
||||
err = tx.QueryRow(`SELECT scope FROM user_groups WHERE public_id = ?`, strings.TrimSpace(groupID)).Scan(&scope)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return err
|
||||
}
|
||||
if NormalizeUserGroupScope(scope) != UserGroupScopeExplicit {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return errors.New("virtual groups do not accept explicit members")
|
||||
}
|
||||
|
||||
now = time.Now().UTC().Unix()
|
||||
_, err = s.Exec(`INSERT OR IGNORE INTO user_group_members (group_id, user_id, created_at)
|
||||
_, err = tx.Exec(`INSERT OR IGNORE INTO user_group_members (group_id, user_id, created_at)
|
||||
VALUES ((SELECT id FROM user_groups WHERE public_id = ?), (SELECT id FROM users WHERE public_id = ?), ?)`,
|
||||
strings.TrimSpace(groupID), strings.TrimSpace(userID), now)
|
||||
|
||||
return err
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return err
|
||||
}
|
||||
return commitIfOwned(tx, owned)
|
||||
}
|
||||
|
||||
func (s *Store) RemoveUserGroupMember(groupID string, userID string) error {
|
||||
func (s *Store) RemoveUserGroupMember(ctx context.Context, groupID string, userID string) error {
|
||||
var err error
|
||||
var group models.UserGroup
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
var scope string
|
||||
|
||||
group, err = s.GetUserGroup(groupID)
|
||||
tx, owned, err = s.beginImmediateContext(ctx)
|
||||
if err != nil { return err }
|
||||
|
||||
if NormalizeUserGroupScope(group.Scope) != UserGroupScopeExplicit {
|
||||
err = tx.QueryRow(`SELECT scope FROM user_groups WHERE public_id = ?`, strings.TrimSpace(groupID)).Scan(&scope)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return err
|
||||
}
|
||||
if NormalizeUserGroupScope(scope) != UserGroupScopeExplicit {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return errors.New("virtual groups do not have explicit members")
|
||||
}
|
||||
|
||||
_, err = s.Exec(`DELETE FROM user_group_members
|
||||
_, err = tx.Exec(`DELETE FROM user_group_members
|
||||
WHERE group_id = (SELECT id FROM user_groups WHERE public_id = ?)
|
||||
AND user_id = (SELECT id FROM users WHERE public_id = ?)`,
|
||||
strings.TrimSpace(groupID),
|
||||
strings.TrimSpace(userID),
|
||||
)
|
||||
return err
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return err
|
||||
}
|
||||
return commitIfOwned(tx, owned)
|
||||
}
|
||||
|
||||
func (s *Store) ListProjectGroupRoles(projectID string) ([]models.ProjectGroupRole, error) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package db
|
||||
|
||||
import "context"
|
||||
import "database/sql"
|
||||
import "errors"
|
||||
import "strings"
|
||||
@@ -312,7 +313,7 @@ func (s *Store) GetActivePKIClientProfileForUser(profileID string, userID string
|
||||
return item, nil
|
||||
}
|
||||
|
||||
func (s *Store) CreatePKIClientProfile(item models.PKIClientProfile) (models.PKIClientProfile, error) {
|
||||
func (s *Store) CreatePKIClientProfile(ctx context.Context, item models.PKIClientProfile) (models.PKIClientProfile, error) {
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
var err error
|
||||
@@ -338,7 +339,7 @@ func (s *Store) CreatePKIClientProfile(item models.PKIClientProfile) (models.PKI
|
||||
now = time.Now().UTC().Unix()
|
||||
item.CreatedAt = now
|
||||
item.UpdatedAt = now
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil {
|
||||
return item, err
|
||||
}
|
||||
@@ -412,7 +413,7 @@ func (s *Store) CreatePKIClientProfile(item models.PKIClientProfile) (models.PKI
|
||||
return item, nil
|
||||
}
|
||||
|
||||
func (s *Store) UpdatePKIClientProfile(item models.PKIClientProfile) (models.PKIClientProfile, error) {
|
||||
func (s *Store) UpdatePKIClientProfile(ctx context.Context, item models.PKIClientProfile) (models.PKIClientProfile, error) {
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
var err error
|
||||
@@ -434,7 +435,7 @@ func (s *Store) UpdatePKIClientProfile(item models.PKIClientProfile) (models.PKI
|
||||
}
|
||||
now = time.Now().UTC().Unix()
|
||||
item.UpdatedAt = now
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil {
|
||||
return item, err
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package db
|
||||
|
||||
import "context"
|
||||
import "database/sql"
|
||||
import "strings"
|
||||
import "time"
|
||||
@@ -127,7 +128,7 @@ func (s *Store) DeletePKICA(id string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *Store) DeletePKICASubtree(id string) error {
|
||||
func (s *Store) DeletePKICASubtree(ctx context.Context, id string) error {
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
var rows *sql.Rows
|
||||
@@ -143,7 +144,7 @@ func (s *Store) DeletePKICASubtree(id string) error {
|
||||
var toDelete []string
|
||||
var contains bool
|
||||
parentByID = map[string]string{}
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -204,13 +205,13 @@ func (s *Store) DeletePKICASubtree(id string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Store) NextPKICASerial(caID string) (int64, error) {
|
||||
func (s *Store) NextPKICASerial(ctx context.Context, caID string) (int64, error) {
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
var err error
|
||||
var row *sql.Row
|
||||
var serial int64
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package db
|
||||
|
||||
import "context"
|
||||
import "database/sql"
|
||||
import "time"
|
||||
|
||||
@@ -74,7 +75,7 @@ func (s *Store) SetPrincipalAPIKeyDisabled(principalID string, id string, disabl
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *Store) GetPrincipalByAPIKeyHash(tokenHash string) (models.ServicePrincipal, error) {
|
||||
func (s *Store) GetPrincipalByAPIKeyHash(ctx context.Context, tokenHash string) (models.ServicePrincipal, error) {
|
||||
var principal models.ServicePrincipal
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
@@ -85,7 +86,7 @@ func (s *Store) GetPrincipalByAPIKeyHash(tokenHash string) (models.ServicePrinci
|
||||
var currentUnix int64
|
||||
var err error
|
||||
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil { return principal, err }
|
||||
|
||||
now = time.Now().UTC()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package db
|
||||
|
||||
import "context"
|
||||
import "database/sql"
|
||||
import "strings"
|
||||
import "time"
|
||||
@@ -72,12 +73,12 @@ func (s *Store) UpdateServicePrincipal(item models.ServicePrincipal) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *Store) DeleteServicePrincipal(id string) error {
|
||||
func (s *Store) DeleteServicePrincipal(ctx context.Context, id string) error {
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
var err error
|
||||
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil { return err }
|
||||
|
||||
_, err = tx.Exec(`DELETE FROM project_role_bindings WHERE subject_type = 'principal' AND subject_id = (SELECT id FROM service_principals WHERE public_id = ?)`, id)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package db
|
||||
|
||||
import "context"
|
||||
import "database/sql"
|
||||
import "strings"
|
||||
import "time"
|
||||
@@ -140,7 +141,7 @@ func (s *Store) TryStartRPMMirrorTask(repoID string, path string, now int64) (bo
|
||||
return rows > 0, nil
|
||||
}
|
||||
|
||||
func (s *Store) TryStartRPMMirrorRun(repoID string, path string, startedAt int64) (string, bool, error) {
|
||||
func (s *Store) TryStartRPMMirrorRun(ctx context.Context, repoID string, path string, startedAt int64) (string, bool, error) {
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
var res sql.Result
|
||||
@@ -148,7 +149,7 @@ func (s *Store) TryStartRPMMirrorRun(repoID string, path string, startedAt int64
|
||||
var runID string
|
||||
var err error
|
||||
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil {
|
||||
return "", false, err
|
||||
}
|
||||
@@ -191,7 +192,7 @@ func (s *Store) UpdateRPMMirrorTaskProgress(repoID string, path string, step str
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *Store) FinishRPMMirrorTask(repoID string, path string, success bool, revision string, errMsg string) error {
|
||||
func (s *Store) FinishRPMMirrorTask(ctx context.Context, repoID string, path string, success bool, revision string, errMsg string) error {
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
var now int64
|
||||
@@ -200,7 +201,7 @@ func (s *Store) FinishRPMMirrorTask(repoID string, path string, success bool, re
|
||||
var interval int64
|
||||
var row *sql.Row
|
||||
var err error
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -236,7 +237,7 @@ func (s *Store) FinishRPMMirrorTask(repoID string, path string, success bool, re
|
||||
return commitIfOwned(tx, owned)
|
||||
}
|
||||
|
||||
func (s *Store) FinishRPMMirrorTaskRun(repoID string, path string, runID string, success bool, finishedAt int64, step string, total int64, done int64, failed int64, deleted int64, revision string, errMsg string) error {
|
||||
func (s *Store) FinishRPMMirrorTaskRun(ctx context.Context, repoID string, path string, runID string, success bool, finishedAt int64, step string, total int64, done int64, failed int64, deleted int64, revision string, errMsg string) error {
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
var interval int64
|
||||
@@ -245,7 +246,7 @@ func (s *Store) FinishRPMMirrorTaskRun(repoID string, path string, runID string,
|
||||
var row *sql.Row
|
||||
var err error
|
||||
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -309,13 +310,13 @@ func (s *Store) SetRPMMirrorSyncEnabled(repoID string, path string, enabled bool
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *Store) ResetRunningRPMMirrorTasks() error {
|
||||
func (s *Store) ResetRunningRPMMirrorTasks(ctx context.Context) error {
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
var now int64
|
||||
var err error
|
||||
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -540,7 +541,7 @@ func (s *Store) DeleteRPMRepoDirSubtree(repoID string, path string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *Store) MoveRPMRepoDir(repoID string, oldPath string, newPath string) error {
|
||||
func (s *Store) MoveRPMRepoDir(ctx context.Context, repoID string, oldPath string, newPath string) error {
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
var now int64
|
||||
@@ -548,7 +549,7 @@ func (s *Store) MoveRPMRepoDir(repoID string, oldPath string, newPath string) er
|
||||
var newPrefix string
|
||||
var err error
|
||||
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil { return err }
|
||||
|
||||
now = time.Now().UTC().Unix()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package db
|
||||
|
||||
import "context"
|
||||
import "database/sql"
|
||||
import "encoding/json"
|
||||
import "errors"
|
||||
@@ -268,33 +269,50 @@ func (s *Store) UpdateSSHServer(item models.SSHServer) (models.SSHServer, error)
|
||||
return s.GetSSHServer(item.ID)
|
||||
}
|
||||
|
||||
func (s *Store) DeleteSSHServer(id string) error {
|
||||
func (s *Store) DeleteSSHServer(ctx context.Context, id string) error {
|
||||
var err error
|
||||
var row *sql.Row
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
var count int64
|
||||
var trimmedID string
|
||||
|
||||
trimmedID = strings.TrimSpace(id)
|
||||
row = s.QueryRow(`SELECT COUNT(*) FROM ssh_access_profiles WHERE server_id = (SELECT id FROM ssh_servers WHERE public_id = ?)`, trimmedID)
|
||||
err = row.Scan(&count)
|
||||
tx, owned, err = s.beginImmediateContext(ctx)
|
||||
if err != nil { return err }
|
||||
|
||||
err = tx.QueryRow(`SELECT COUNT(*) FROM ssh_access_profiles WHERE server_id = (SELECT id FROM ssh_servers WHERE public_id = ?)`, trimmedID).Scan(&count)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return &SSHServerDeleteReferenceError{Kind: "SSH access profile", Count: count}
|
||||
}
|
||||
row = s.QueryRow(`SELECT COUNT(*) FROM ssh_server_group_members WHERE server_id = (SELECT id FROM ssh_servers WHERE public_id = ?)`, trimmedID)
|
||||
err = row.Scan(&count)
|
||||
if err != nil { return err }
|
||||
err = tx.QueryRow(`SELECT COUNT(*) FROM ssh_server_group_members WHERE server_id = (SELECT id FROM ssh_servers WHERE public_id = ?)`, trimmedID).Scan(&count)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return &SSHServerDeleteReferenceError{Kind: "SSH server group membership", Count: count}
|
||||
}
|
||||
row = s.QueryRow(`SELECT COUNT(*) FROM ssh_sessions WHERE server_id = (SELECT id FROM ssh_servers WHERE public_id = ?)`, trimmedID)
|
||||
err = row.Scan(&count)
|
||||
if err != nil { return err }
|
||||
err = tx.QueryRow(`SELECT COUNT(*) FROM ssh_sessions WHERE server_id = (SELECT id FROM ssh_servers WHERE public_id = ?)`, trimmedID).Scan(&count)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return &SSHServerDeleteReferenceError{Kind: "SSH session history record", Count: count}
|
||||
}
|
||||
_, err = s.Exec(`DELETE FROM ssh_servers WHERE public_id = ?`, trimmedID)
|
||||
return err
|
||||
_, err = tx.Exec(`DELETE FROM ssh_servers WHERE public_id = ?`, trimmedID)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return err
|
||||
}
|
||||
return commitIfOwned(tx, owned)
|
||||
}
|
||||
|
||||
func (s *Store) ListSSHAccessProfiles() ([]models.SSHAccessProfile, error) {
|
||||
@@ -614,7 +632,7 @@ func (s *Store) GetSSHAccessProfile(id string) (models.SSHAccessProfile, error)
|
||||
return item, nil
|
||||
}
|
||||
|
||||
func (s *Store) CreateSSHAccessProfile(item models.SSHAccessProfile) (models.SSHAccessProfile, error) {
|
||||
func (s *Store) CreateSSHAccessProfile(ctx context.Context, item models.SSHAccessProfile) (models.SSHAccessProfile, error) {
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
var err error
|
||||
@@ -653,7 +671,7 @@ func (s *Store) CreateSSHAccessProfile(item models.SSHAccessProfile) (models.SSH
|
||||
now = time.Now().UTC().Unix()
|
||||
item.CreatedAt = now
|
||||
item.UpdatedAt = now
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil { return item, err }
|
||||
|
||||
item.SecretPayload = strings.TrimSpace(item.SecretPayload)
|
||||
@@ -776,7 +794,7 @@ func (s *Store) CreateSSHAccessProfile(item models.SSHAccessProfile) (models.SSH
|
||||
return item, nil
|
||||
}
|
||||
|
||||
func (s *Store) UpdateSSHAccessProfile(item models.SSHAccessProfile) (models.SSHAccessProfile, error) {
|
||||
func (s *Store) UpdateSSHAccessProfile(ctx context.Context, item models.SSHAccessProfile) (models.SSHAccessProfile, error) {
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
var err error
|
||||
@@ -809,7 +827,7 @@ func (s *Store) UpdateSSHAccessProfile(item models.SSHAccessProfile) (models.SSH
|
||||
if err != nil { return item, err }
|
||||
|
||||
item.UpdatedAt = time.Now().UTC().Unix()
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil { return item, err }
|
||||
|
||||
item.SecretPayload = strings.TrimSpace(item.SecretPayload)
|
||||
@@ -910,7 +928,7 @@ func (s *Store) UpdateSSHAccessProfile(item models.SSHAccessProfile) (models.SSH
|
||||
return item, nil
|
||||
}
|
||||
|
||||
func (s *Store) DeleteSSHAccessProfile(id string) error {
|
||||
func (s *Store) DeleteSSHAccessProfile(ctx context.Context, id string) error {
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
var row *sql.Row
|
||||
@@ -918,7 +936,7 @@ func (s *Store) DeleteSSHAccessProfile(id string) error {
|
||||
var credentialID sql.NullString
|
||||
var err error
|
||||
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1900,25 +1918,30 @@ func (s *Store) CreateSSHFileTransfer(item models.SSHFileTransfer) (models.SSHFi
|
||||
return item, err
|
||||
}
|
||||
|
||||
func (s *Store) FinishSSHFileTransfer(id string, status string, paths []string, bytesTransferred int64, errText string) error {
|
||||
var row *sql.Row
|
||||
func (s *Store) FinishSSHFileTransfer(ctx context.Context, id string, status string, paths []string, bytesTransferred int64, errText string) error {
|
||||
var startedAt int64
|
||||
var finishedAt int64
|
||||
var durationMS int64
|
||||
var pathsJSON string
|
||||
var err error
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
|
||||
pathsJSON, err = encodeStringList(paths)
|
||||
if err != nil { return err }
|
||||
finishedAt = time.Now().UTC().Unix()
|
||||
row = s.QueryRow(`SELECT started_at FROM ssh_file_transfers WHERE public_id = ?`, strings.TrimSpace(id))
|
||||
err = row.Scan(&startedAt)
|
||||
tx, owned, err = s.beginImmediateContext(ctx)
|
||||
if err != nil { return err }
|
||||
err = tx.QueryRow(`SELECT started_at FROM ssh_file_transfers WHERE public_id = ?`, strings.TrimSpace(id)).Scan(&startedAt)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return err
|
||||
}
|
||||
durationMS = 0
|
||||
if startedAt > 0 && finishedAt >= startedAt {
|
||||
durationMS = (finishedAt - startedAt) * 1000
|
||||
}
|
||||
_, err = s.Exec(`UPDATE ssh_file_transfers
|
||||
_, err = tx.Exec(`UPDATE ssh_file_transfers
|
||||
SET status = ?, paths_json = ?, bytes_transferred = ?, error = ?, finished_at = ?, duration_ms = ?
|
||||
WHERE public_id = ?`,
|
||||
strings.TrimSpace(status),
|
||||
@@ -1929,7 +1952,11 @@ func (s *Store) FinishSSHFileTransfer(id string, status string, paths []string,
|
||||
durationMS,
|
||||
strings.TrimSpace(id),
|
||||
)
|
||||
return err
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return err
|
||||
}
|
||||
return commitIfOwned(tx, owned)
|
||||
}
|
||||
|
||||
func scanSSHFileTransferRows(rows *sql.Rows, limit int) ([]models.SSHFileTransfer, bool, error) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package db
|
||||
|
||||
import "context"
|
||||
import "database/sql"
|
||||
import "errors"
|
||||
import "strings"
|
||||
@@ -109,7 +110,7 @@ func (s *Store) GetSSHCredentialForUser(userID string, id string) (models.SSHCre
|
||||
return item, err
|
||||
}
|
||||
|
||||
func (s *Store) CreateSSHCredential(item models.SSHCredential, secret models.SSHSecret) (models.SSHCredential, error) {
|
||||
func (s *Store) CreateSSHCredential(ctx context.Context, item models.SSHCredential, secret models.SSHSecret) (models.SSHCredential, error) {
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
var err error
|
||||
@@ -124,7 +125,7 @@ func (s *Store) CreateSSHCredential(item models.SSHCredential, secret models.SSH
|
||||
item.ID, err = util.NewID()
|
||||
if err != nil { return item, err }
|
||||
}
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil { return item, err }
|
||||
secret.Kind = "private_key"
|
||||
secret.CreatedByKind = item.CreatedByKind
|
||||
@@ -184,24 +185,48 @@ func (s *Store) UpdateSSHCredential(item models.SSHCredential) (models.SSHCreden
|
||||
return s.GetSSHCredential(item.ID)
|
||||
}
|
||||
|
||||
func (s *Store) DeleteSSHCredential(id string) error {
|
||||
var row *sql.Row
|
||||
func (s *Store) DeleteSSHCredential(ctx context.Context, id string) error {
|
||||
var count int
|
||||
var item models.SSHCredential
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
var secretID string
|
||||
var err error
|
||||
|
||||
id = strings.TrimSpace(id)
|
||||
row = s.QueryRow(`SELECT COUNT(*)
|
||||
tx, owned, err = s.beginImmediateContext(ctx)
|
||||
if err != nil { return err }
|
||||
|
||||
err = tx.QueryRow(`SELECT COUNT(*)
|
||||
FROM ssh_access_profiles p
|
||||
JOIN ssh_credentials c ON c.id = p.ssh_credential_id
|
||||
WHERE c.public_id = ?`, id)
|
||||
err = row.Scan(&count)
|
||||
if err != nil { return err }
|
||||
if count > 0 { return errors.New("ssh credential is used by access profiles") }
|
||||
item, err = s.GetSSHCredential(id)
|
||||
if err != nil { return err }
|
||||
_, err = s.Exec(`DELETE FROM ssh_credentials WHERE public_id = ?`, id)
|
||||
if err != nil { return err }
|
||||
_, err = s.Exec(`DELETE FROM ssh_secrets WHERE public_id = ?`, strings.TrimSpace(item.SecretID))
|
||||
return err
|
||||
WHERE c.public_id = ?`, id).Scan(&count)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return errors.New("ssh credential is used by access profiles")
|
||||
}
|
||||
err = tx.QueryRow(`SELECT COALESCE(sec.public_id, '')
|
||||
FROM ssh_credentials c
|
||||
LEFT JOIN ssh_secrets sec ON sec.id = c.secret_id
|
||||
WHERE c.public_id = ?`, id).Scan(&secretID)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return err
|
||||
}
|
||||
_, err = tx.Exec(`DELETE FROM ssh_credentials WHERE public_id = ?`, id)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return err
|
||||
}
|
||||
if strings.TrimSpace(secretID) != "" {
|
||||
_, err = tx.Exec(`DELETE FROM ssh_secrets WHERE public_id = ?`, strings.TrimSpace(secretID))
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return err
|
||||
}
|
||||
}
|
||||
return commitIfOwned(tx, owned)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package db
|
||||
|
||||
import "context"
|
||||
import "database/sql"
|
||||
import "encoding/json"
|
||||
import "errors"
|
||||
@@ -239,7 +240,7 @@ func (s *Store) GetSSHPrincipalGrant(id string) (models.SSHPrincipalGrant, error
|
||||
return item, nil
|
||||
}
|
||||
|
||||
func (s *Store) CreateSSHPrincipalGrant(item models.SSHPrincipalGrant) (models.SSHPrincipalGrant, error) {
|
||||
func (s *Store) CreateSSHPrincipalGrant(ctx context.Context, item models.SSHPrincipalGrant) (models.SSHPrincipalGrant, error) {
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
var err error
|
||||
@@ -276,7 +277,7 @@ func (s *Store) CreateSSHPrincipalGrant(item models.SSHPrincipalGrant) (models.S
|
||||
if err != nil {
|
||||
return item, err
|
||||
}
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil {
|
||||
return item, err
|
||||
}
|
||||
@@ -335,7 +336,7 @@ func (s *Store) CreateSSHPrincipalGrant(item models.SSHPrincipalGrant) (models.S
|
||||
return item, nil
|
||||
}
|
||||
|
||||
func (s *Store) UpdateSSHPrincipalGrant(item models.SSHPrincipalGrant) (models.SSHPrincipalGrant, error) {
|
||||
func (s *Store) UpdateSSHPrincipalGrant(ctx context.Context, item models.SSHPrincipalGrant) (models.SSHPrincipalGrant, error) {
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
var err error
|
||||
@@ -367,7 +368,7 @@ func (s *Store) UpdateSSHPrincipalGrant(item models.SSHPrincipalGrant) (models.S
|
||||
}
|
||||
now = time.Now().UTC().Unix()
|
||||
item.UpdatedAt = now
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil {
|
||||
return item, err
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package db
|
||||
|
||||
import "context"
|
||||
import "database/sql"
|
||||
import "errors"
|
||||
import "strings"
|
||||
@@ -113,7 +114,7 @@ func (s *Store) ListSSHServersForGroup(groupID string) ([]models.SSHServer, erro
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func (s *Store) CreateSSHServerGroup(item models.SSHServerGroup) (models.SSHServerGroup, error) {
|
||||
func (s *Store) CreateSSHServerGroup(ctx context.Context, item models.SSHServerGroup) (models.SSHServerGroup, error) {
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
var err error
|
||||
@@ -131,7 +132,7 @@ func (s *Store) CreateSSHServerGroup(item models.SSHServerGroup) (models.SSHServ
|
||||
now = time.Now().UTC().Unix()
|
||||
item.CreatedAt = now
|
||||
item.UpdatedAt = now
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil { return item, err }
|
||||
_, err = tx.Exec(`INSERT INTO ssh_server_groups (public_id, name, description, enabled, tags_json, created_by_kind, created_by_user_id, created_by_principal_id, created_by_subject_name, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, (SELECT id FROM users WHERE public_id = ? AND ? = 'user'), (SELECT id FROM service_principals WHERE public_id = ? AND ? = 'service_principal'), ?, ?, ?)`, item.ID, strings.TrimSpace(item.Name), strings.TrimSpace(item.Description), item.Enabled, tagsJSON, strings.TrimSpace(item.CreatedByKind), strings.TrimSpace(item.CreatedBySubjectID), strings.TrimSpace(item.CreatedByKind), strings.TrimSpace(item.CreatedBySubjectID), strings.TrimSpace(item.CreatedByKind), strings.TrimSpace(item.CreatedBySubjectName), item.CreatedAt, item.UpdatedAt)
|
||||
if err != nil { rollbackIfOwned(tx, owned); return item, err }
|
||||
@@ -140,7 +141,7 @@ func (s *Store) CreateSSHServerGroup(item models.SSHServerGroup) (models.SSHServ
|
||||
return s.GetSSHServerGroup(item.ID)
|
||||
}
|
||||
|
||||
func (s *Store) UpdateSSHServerGroup(item models.SSHServerGroup) (models.SSHServerGroup, error) {
|
||||
func (s *Store) UpdateSSHServerGroup(ctx context.Context, item models.SSHServerGroup) (models.SSHServerGroup, error) {
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
var err error
|
||||
@@ -152,7 +153,7 @@ func (s *Store) UpdateSSHServerGroup(item models.SSHServerGroup) (models.SSHServ
|
||||
tagsJSON, err = encodeStringList(item.Tags)
|
||||
if err != nil { return item, err }
|
||||
now = time.Now().UTC().Unix()
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil { return item, err }
|
||||
_, err = tx.Exec(`UPDATE ssh_server_groups SET name = ?, description = ?, enabled = ?, tags_json = ?, updated_at = ? WHERE public_id = ?`, strings.TrimSpace(item.Name), strings.TrimSpace(item.Description), item.Enabled, tagsJSON, now, strings.TrimSpace(item.ID))
|
||||
if err != nil { rollbackIfOwned(tx, owned); return item, err }
|
||||
@@ -161,21 +162,34 @@ func (s *Store) UpdateSSHServerGroup(item models.SSHServerGroup) (models.SSHServ
|
||||
return s.GetSSHServerGroup(item.ID)
|
||||
}
|
||||
|
||||
func (s *Store) DeleteSSHServerGroup(id string) error {
|
||||
var row *sql.Row
|
||||
func (s *Store) DeleteSSHServerGroup(ctx context.Context, id string) error {
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
var count int
|
||||
var err error
|
||||
|
||||
id = strings.TrimSpace(id)
|
||||
row = s.QueryRow(`SELECT COUNT(*)
|
||||
tx, owned, err = s.beginImmediateContext(ctx)
|
||||
if err != nil { return err }
|
||||
|
||||
err = tx.QueryRow(`SELECT COUNT(*)
|
||||
FROM ssh_access_profiles p
|
||||
JOIN ssh_server_groups g ON g.id = p.server_group_id
|
||||
WHERE g.public_id = ?`, id)
|
||||
err = row.Scan(&count)
|
||||
if err != nil { return err }
|
||||
if count > 0 { return errors.New("ssh server group is used by access profiles") }
|
||||
_, err = s.Exec(`DELETE FROM ssh_server_groups WHERE public_id = ?`, id)
|
||||
return err
|
||||
WHERE g.public_id = ?`, id).Scan(&count)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return err
|
||||
}
|
||||
if count > 0 {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return errors.New("ssh server group is used by access profiles")
|
||||
}
|
||||
_, err = tx.Exec(`DELETE FROM ssh_server_groups WHERE public_id = ?`, id)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return err
|
||||
}
|
||||
return commitIfOwned(tx, owned)
|
||||
}
|
||||
|
||||
func (s *Store) AddSSHServerGroupMember(groupID string, serverID string) error {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package db
|
||||
|
||||
import "context"
|
||||
import "database/sql"
|
||||
import "encoding/json"
|
||||
import "errors"
|
||||
@@ -145,13 +146,13 @@ func (s *Store) GetSSHUserCAForUser(id string) (models.SSHUserCA, error) {
|
||||
return item, nil
|
||||
}
|
||||
|
||||
func (s *Store) NextSSHUserCASerial(id string) (uint64, error) {
|
||||
func (s *Store) NextSSHUserCASerial(ctx context.Context, id string) (uint64, error) {
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
var row *sql.Row
|
||||
var serial int64
|
||||
var err error
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package db
|
||||
|
||||
import "context"
|
||||
import "database/sql"
|
||||
import "errors"
|
||||
import "strings"
|
||||
@@ -70,14 +71,14 @@ func (s *Store) GetTLSSettings() (models.TLSSettings, error) {
|
||||
return settings, nil
|
||||
}
|
||||
|
||||
func (s *Store) SetTLSSettings(settings models.TLSSettings) error {
|
||||
func (s *Store) SetTLSSettings(ctx context.Context, settings models.TLSSettings) error {
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
var err error
|
||||
var now int64
|
||||
var endpointPoliciesJSON string
|
||||
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil { return err }
|
||||
|
||||
now = time.Now().UTC().Unix()
|
||||
@@ -473,7 +474,7 @@ func (s *Store) GetSessionUser(token string) (models.User, time.Time, bool, erro
|
||||
return user, time.Unix(expiresUnix, 0).UTC(), totpVerified, nil
|
||||
}
|
||||
|
||||
func (s *Store) CreateProject(project models.Project) (models.Project, error) {
|
||||
func (s *Store) CreateProject(ctx context.Context, project models.Project) (models.Project, error) {
|
||||
var id string
|
||||
var err error
|
||||
var nowUnix int64
|
||||
@@ -490,7 +491,7 @@ func (s *Store) CreateProject(project models.Project) (models.Project, error) {
|
||||
project.UpdatedAt = nowUnix
|
||||
if project.UpdatedBy == "" { project.UpdatedBy = project.CreatedBy }
|
||||
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil { return project, err }
|
||||
if project.HomePage == "" { project.HomePage = "settings" }
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package db
|
||||
|
||||
import "context"
|
||||
import "database/sql"
|
||||
import "encoding/json"
|
||||
import "fmt"
|
||||
@@ -213,7 +214,7 @@ func (s *Store) GetTLSAuthPolicy(id string) (models.TLSAuthPolicy, error) {
|
||||
return item, nil
|
||||
}
|
||||
|
||||
func (s *Store) insertTLSAuthPolicyAllowedPKICerts(policyID int64, certPublicIDs []string) error {
|
||||
func insertTLSAuthPolicyAllowedPKICerts(execer sqlExecutor, policyID int64, certPublicIDs []string) error {
|
||||
var seen map[string]bool
|
||||
var i int
|
||||
var certPublicID string
|
||||
@@ -231,7 +232,7 @@ func (s *Store) insertTLSAuthPolicyAllowedPKICerts(policyID int64, certPublicIDs
|
||||
continue
|
||||
}
|
||||
seen[certPublicID] = true
|
||||
result, err = s.Exec(`INSERT INTO tls_auth_policy_allowed_pki_certs (policy_id, cert_id) SELECT ?, id FROM pki_certs WHERE public_id = ?`, policyID, certPublicID)
|
||||
result, err = execer.Exec(`INSERT INTO tls_auth_policy_allowed_pki_certs (policy_id, cert_id) SELECT ?, id FROM pki_certs WHERE public_id = ?`, policyID, certPublicID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -246,12 +247,14 @@ func (s *Store) insertTLSAuthPolicyAllowedPKICerts(policyID int64, certPublicIDs
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Store) CreateTLSAuthPolicy(item models.TLSAuthPolicy) (models.TLSAuthPolicy, error) {
|
||||
func (s *Store) CreateTLSAuthPolicy(ctx context.Context, item models.TLSAuthPolicy) (models.TLSAuthPolicy, error) {
|
||||
var id string
|
||||
var now int64
|
||||
var err error
|
||||
var result sql.Result
|
||||
var internalID int64
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
|
||||
if item.ID == "" {
|
||||
id, err = util.NewID()
|
||||
@@ -263,45 +266,61 @@ func (s *Store) CreateTLSAuthPolicy(item models.TLSAuthPolicy) (models.TLSAuthPo
|
||||
now = time.Now().UTC().Unix()
|
||||
item.CreatedAt = now
|
||||
item.UpdatedAt = now
|
||||
result, err = s.Exec(`INSERT INTO tls_auth_policies (public_id, name, description, read_mode, write_mode, require_principal_for_write, allowed_cert_fingerprints, required_permissions, permission_match, required_scope, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
tx, owned, err = s.beginImmediateContext(ctx)
|
||||
if err != nil { return item, err }
|
||||
|
||||
result, err = tx.Exec(`INSERT INTO tls_auth_policies (public_id, name, description, read_mode, write_mode, require_principal_for_write, allowed_cert_fingerprints, required_permissions, permission_match, required_scope, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
item.ID, item.Name, item.Description, item.ReadMode, item.WriteMode, item.RequirePrincipalForWrite, strings.Join(item.AllowedCertFingerprints, ","), strings.Join(item.RequiredPermissions, ","), item.PermissionMatch, item.RequiredScope, item.CreatedAt, item.UpdatedAt)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return item, err
|
||||
}
|
||||
internalID, err = result.LastInsertId()
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return item, err
|
||||
}
|
||||
err = s.insertTLSAuthPolicyAllowedPKICerts(internalID, item.AllowedPKIClientCertIDs)
|
||||
err = insertTLSAuthPolicyAllowedPKICerts(tx, internalID, item.AllowedPKIClientCertIDs)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return item, err
|
||||
}
|
||||
err = commitIfOwned(tx, owned)
|
||||
if err != nil { return item, err }
|
||||
return item, nil
|
||||
}
|
||||
|
||||
func (s *Store) UpdateTLSAuthPolicy(item models.TLSAuthPolicy) error {
|
||||
func (s *Store) UpdateTLSAuthPolicy(ctx context.Context, item models.TLSAuthPolicy) error {
|
||||
var now int64
|
||||
var err error
|
||||
var row *sql.Row
|
||||
var internalID int64
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
|
||||
row = s.QueryRow(`SELECT id FROM tls_auth_policies WHERE public_id = ?`, item.ID)
|
||||
err = row.Scan(&internalID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
tx, owned, err = s.beginImmediateContext(ctx)
|
||||
if err != nil { return err }
|
||||
|
||||
err = tx.QueryRow(`SELECT id FROM tls_auth_policies WHERE public_id = ?`, item.ID).Scan(&internalID)
|
||||
if err != nil { rollbackIfOwned(tx, owned); return err }
|
||||
now = time.Now().UTC().Unix()
|
||||
item.UpdatedAt = now
|
||||
_, err = s.Exec(`UPDATE tls_auth_policies SET name = ?, description = ?, read_mode = ?, write_mode = ?, require_principal_for_write = ?, allowed_cert_fingerprints = ?, required_permissions = ?, permission_match = ?, required_scope = ?, updated_at = ? WHERE public_id = ?`,
|
||||
_, err = tx.Exec(`UPDATE tls_auth_policies SET name = ?, description = ?, read_mode = ?, write_mode = ?, require_principal_for_write = ?, allowed_cert_fingerprints = ?, required_permissions = ?, permission_match = ?, required_scope = ?, updated_at = ? WHERE public_id = ?`,
|
||||
item.Name, item.Description, item.ReadMode, item.WriteMode, item.RequirePrincipalForWrite, strings.Join(item.AllowedCertFingerprints, ","), strings.Join(item.RequiredPermissions, ","), item.PermissionMatch, item.RequiredScope, item.UpdatedAt, item.ID)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return err
|
||||
}
|
||||
_, err = s.Exec(`DELETE FROM tls_auth_policy_allowed_pki_certs WHERE policy_id = ?`, internalID)
|
||||
_, err = tx.Exec(`DELETE FROM tls_auth_policy_allowed_pki_certs WHERE policy_id = ?`, internalID)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return err
|
||||
}
|
||||
return s.insertTLSAuthPolicyAllowedPKICerts(internalID, item.AllowedPKIClientCertIDs)
|
||||
err = insertTLSAuthPolicyAllowedPKICerts(tx, internalID, item.AllowedPKIClientCertIDs)
|
||||
if err != nil {
|
||||
rollbackIfOwned(tx, owned)
|
||||
return err
|
||||
}
|
||||
return commitIfOwned(tx, owned)
|
||||
}
|
||||
|
||||
func (s *Store) DeleteTLSAuthPolicy(id string) error {
|
||||
@@ -362,7 +381,7 @@ func (s *Store) EnsureDefaultTLSAuthPolicies() error {
|
||||
if err != sql.ErrNoRows {
|
||||
return err
|
||||
}
|
||||
_, err = s.CreateTLSAuthPolicy(item)
|
||||
_, err = s.CreateTLSAuthPolicy(context.Background(), item)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -382,7 +401,7 @@ func (s *Store) EnsureTLSAuthPolicyBindings() error {
|
||||
}
|
||||
if len(settings.EndpointPolicies) == 0 {
|
||||
settings.EndpointPolicies = DefaultTLSEndpointPolicies()
|
||||
err = s.SetTLSSettings(settings)
|
||||
err = s.SetTLSSettings(context.Background(), settings)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package db
|
||||
|
||||
import "context"
|
||||
import "database/sql"
|
||||
import "strings"
|
||||
import "time"
|
||||
@@ -38,7 +39,7 @@ func (s *Store) UpdateUser(user models.User) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *Store) UpdateUserWithPassword(user models.User, passwordHash string) error {
|
||||
func (s *Store) UpdateUserWithPassword(ctx context.Context, user models.User, passwordHash string) error {
|
||||
var err error
|
||||
var nowUnix int64
|
||||
var tx txExecutor
|
||||
@@ -46,7 +47,7 @@ func (s *Store) UpdateUserWithPassword(user models.User, passwordHash string) er
|
||||
|
||||
nowUnix = time.Now().UTC().Unix()
|
||||
user.UpdatedAt = nowUnix
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -143,12 +144,12 @@ func (s *Store) ClearUserAvatar(id string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *Store) DeleteUser(id string) error {
|
||||
func (s *Store) DeleteUser(ctx context.Context, id string) error {
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
var err error
|
||||
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil { return err }
|
||||
|
||||
_, err = tx.Exec(`DELETE FROM project_role_bindings WHERE subject_type = 'user' AND subject_id = (SELECT id FROM users WHERE public_id = ?)`, id)
|
||||
@@ -202,7 +203,7 @@ func (s *Store) SetUserDisabled(id string, disabled bool) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (s *Store) GetUserByAPIKeyHash(tokenHash string) (models.User, error) {
|
||||
func (s *Store) GetUserByAPIKeyHash(ctx context.Context, tokenHash string) (models.User, error) {
|
||||
var user models.User
|
||||
var tx txExecutor
|
||||
var owned bool
|
||||
@@ -211,7 +212,7 @@ func (s *Store) GetUserByAPIKeyHash(tokenHash string) (models.User, error) {
|
||||
var nowUnix int64
|
||||
var err error
|
||||
|
||||
tx, owned, err = s.begin()
|
||||
tx, owned, err = s.beginContext(ctx)
|
||||
if err != nil { return user, err }
|
||||
|
||||
nowUnix = time.Now().UTC().Unix()
|
||||
|
||||
@@ -524,7 +524,7 @@ func (api *API) Login(w http.ResponseWriter, r *http.Request, _ map[string]strin
|
||||
if err == nil {
|
||||
user = created
|
||||
if p.DefaultUserGroupID != "" {
|
||||
_ = api.store(r).AddUserGroupMember(p.DefaultUserGroupID, user.ID)
|
||||
_ = api.store(r).AddUserGroupMember(r.Context(), p.DefaultUserGroupID, user.ID)
|
||||
}
|
||||
} else {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusInternalServerError, err.Error())
|
||||
@@ -748,7 +748,7 @@ func (api *API) UpdateMe(w http.ResponseWriter, r *http.Request, _ map[string]st
|
||||
WriteJSONWithErrorReason(w, r, http.StatusInternalServerError, "failed to hash password")
|
||||
return
|
||||
}
|
||||
err = api.store(r).UpdateUserWithPassword(user, hash)
|
||||
err = api.store(r).UpdateUserWithPassword(r.Context(), user, hash)
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
@@ -1044,7 +1044,7 @@ func (api *API) UpdateUser(w http.ResponseWriter, r *http.Request, params map[st
|
||||
WriteJSONWithErrorReason(w, r, http.StatusInternalServerError, "failed to hash password")
|
||||
return
|
||||
}
|
||||
err = api.store(r).UpdateUserWithPassword(user, hash)
|
||||
err = api.store(r).UpdateUserWithPassword(r.Context(), user, hash)
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
@@ -1064,7 +1064,7 @@ func (api *API) DeleteUser(w http.ResponseWriter, r *http.Request, params map[st
|
||||
if !api.requireAdmin(w, r) {
|
||||
return
|
||||
}
|
||||
err = api.store(r).DeleteUser(params["id"])
|
||||
err = api.store(r).DeleteUser(r.Context(), params["id"])
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
@@ -1171,7 +1171,7 @@ func (api *API) UpdateUserGroup(w http.ResponseWriter, r *http.Request, params m
|
||||
group.Disabled = req.Disabled
|
||||
group.TOTPRequired = req.TOTPRequired
|
||||
group.Scope = db.NormalizeUserGroupScope(req.Scope)
|
||||
group, err = api.store(r).UpdateUserGroup(group)
|
||||
group, err = api.store(r).UpdateUserGroup(r.Context(), group)
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
@@ -1184,7 +1184,7 @@ func (api *API) DeleteUserGroup(w http.ResponseWriter, r *http.Request, params m
|
||||
if !api.requireAdmin(w, r) {
|
||||
return
|
||||
}
|
||||
err = api.store(r).DeleteUserGroup(params["id"])
|
||||
err = api.store(r).DeleteUserGroup(r.Context(), params["id"])
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
@@ -1222,7 +1222,7 @@ func (api *API) AddUserGroupMember(w http.ResponseWriter, r *http.Request, param
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, "user_id required")
|
||||
return
|
||||
}
|
||||
err = api.store(r).AddUserGroupMember(params["id"], req.UserID)
|
||||
err = api.store(r).AddUserGroupMember(r.Context(), params["id"], req.UserID)
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
@@ -1235,7 +1235,7 @@ func (api *API) RemoveUserGroupMember(w http.ResponseWriter, r *http.Request, pa
|
||||
if !api.requireAdmin(w, r) {
|
||||
return
|
||||
}
|
||||
err = api.store(r).RemoveUserGroupMember(params["id"], params["userId"])
|
||||
err = api.store(r).RemoveUserGroupMember(r.Context(), params["id"], params["userId"])
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
@@ -1354,7 +1354,7 @@ func (api *API) UpdateTLSSettings(w http.ResponseWriter, r *http.Request, _ map[
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
err = api.store(r).SetTLSSettings(settings)
|
||||
err = api.store(r).SetTLSSettings(r.Context(), settings)
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
@@ -1396,7 +1396,7 @@ func (api *API) CreateTLSAuthPolicy(w http.ResponseWriter, r *http.Request, _ ma
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
created, err = api.store(r).CreateTLSAuthPolicy(item)
|
||||
created, err = api.store(r).CreateTLSAuthPolicy(r.Context(), item)
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
@@ -1427,7 +1427,7 @@ func (api *API) UpdateTLSAuthPolicy(w http.ResponseWriter, r *http.Request, para
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
err = api.store(r).UpdateTLSAuthPolicy(item)
|
||||
err = api.store(r).UpdateTLSAuthPolicy(r.Context(), item)
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
@@ -1700,7 +1700,7 @@ func (api *API) DeleteServicePrincipal(w http.ResponseWriter, r *http.Request, p
|
||||
if !api.requireAdmin(w, r) {
|
||||
return
|
||||
}
|
||||
err = api.store(r).DeleteServicePrincipal(params["id"])
|
||||
err = api.store(r).DeleteServicePrincipal(r.Context(), params["id"])
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
@@ -2076,7 +2076,7 @@ func (api *API) CreateProject(w http.ResponseWriter, r *http.Request, _ map[stri
|
||||
CreatedBy: user.ID,
|
||||
UpdatedBy: user.ID,
|
||||
}
|
||||
created, err = api.store(r).CreateProject(project)
|
||||
created, err = api.store(r).CreateProject(r.Context(), project)
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
@@ -4461,7 +4461,7 @@ func (api *API) RepoRPMRenameSubdir(w http.ResponseWriter, r *http.Request, para
|
||||
WriteJSONWithErrorReason(w, r, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
err = api.store(r).MoveRPMRepoDir(repo.ID, relPathClean, newRelPath)
|
||||
err = api.store(r).MoveRPMRepoDir(r.Context(), repo.ID, relPathClean, newRelPath)
|
||||
if err != nil {
|
||||
_ = os.Rename(newPath, fullPath)
|
||||
WriteJSONWithErrorReason(w, r, http.StatusInternalServerError, err.Error())
|
||||
|
||||
@@ -63,7 +63,7 @@ func (api *API) CreateAuthProvider(w http.ResponseWriter, r *http.Request, _ map
|
||||
return
|
||||
}
|
||||
}
|
||||
created, err = api.store(r).CreateAuthProvider(req)
|
||||
created, err = api.store(r).CreateAuthProvider(r.Context(), req)
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
@@ -103,13 +103,13 @@ func (api *API) UpdateAuthProvider(w http.ResponseWriter, r *http.Request, param
|
||||
if strings.TrimSpace(req.Name) != "" {
|
||||
existing.Name = strings.TrimSpace(req.Name)
|
||||
}
|
||||
updated, err = api.store(r).UpdateAuthProvider(existing)
|
||||
updated, err = api.store(r).UpdateAuthProvider(r.Context(), existing)
|
||||
} else {
|
||||
if strings.TrimSpace(req.Name) == "" {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, "name is required")
|
||||
return
|
||||
}
|
||||
updated, err = api.store(r).UpdateAuthProvider(req)
|
||||
updated, err = api.store(r).UpdateAuthProvider(r.Context(), req)
|
||||
}
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
@@ -144,7 +144,7 @@ func (api *API) DeleteAuthProvider(w http.ResponseWriter, r *http.Request, param
|
||||
return
|
||||
}
|
||||
}
|
||||
err = api.store(r).DeleteAuthProvider(params["id"], force)
|
||||
err = api.store(r).DeleteAuthProvider(r.Context(), params["id"], force)
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
|
||||
@@ -72,7 +72,7 @@ func (api *API) CreateBlockComment(w http.ResponseWriter, r *http.Request, param
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, "content is required")
|
||||
return
|
||||
}
|
||||
comment, err = api.store(r).CreateBlockComment(params["boardId"], params["blockId"], req.Content, user.ID)
|
||||
comment, err = api.store(r).CreateBlockComment(r.Context(), params["boardId"], params["blockId"], req.Content, user.ID)
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusNotFound, "block not found")
|
||||
@@ -184,7 +184,7 @@ func (api *API) CreateBlockChecklistItem(w http.ResponseWriter, r *http.Request,
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, "title is required")
|
||||
return
|
||||
}
|
||||
item, err = api.store(r).CreateBlockChecklistItem(params["boardId"], params["blockId"], req.Title, user.ID)
|
||||
item, err = api.store(r).CreateBlockChecklistItem(r.Context(), params["boardId"], params["blockId"], req.Title, user.ID)
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusNotFound, "block not found")
|
||||
@@ -266,7 +266,7 @@ func (api *API) ReorderBlockChecklistItems(w http.ResponseWriter, r *http.Reques
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, "ids are required")
|
||||
return
|
||||
}
|
||||
items, err = api.store(r).ReorderBlockChecklistItems(params["boardId"], params["blockId"], req.IDs)
|
||||
items, err = api.store(r).ReorderBlockChecklistItems(r.Context(), params["boardId"], params["blockId"], req.IDs)
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusNotFound, "block not found")
|
||||
@@ -368,7 +368,7 @@ func (api *API) CreateBlockAttachment(w http.ResponseWriter, r *http.Request, pa
|
||||
StoragePath: finalPath,
|
||||
CreatedBy: user.ID,
|
||||
}
|
||||
created, err = api.store(r).CreateBlockAttachment(params["boardId"], params["blockId"], attachment)
|
||||
created, err = api.store(r).CreateBlockAttachment(r.Context(), params["boardId"], params["blockId"], attachment)
|
||||
if err != nil {
|
||||
_ = os.Remove(finalPath)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
@@ -423,7 +423,7 @@ func (api *API) DeleteBlockAttachment(w http.ResponseWriter, r *http.Request, pa
|
||||
if !api.requireBoardRole(w, r, params["boardId"], "editor") {
|
||||
return
|
||||
}
|
||||
item, err = api.store(r).DeleteBlockAttachment(params["boardId"], params["blockId"], params["attachmentId"])
|
||||
item, err = api.store(r).DeleteBlockAttachment(r.Context(), params["boardId"], params["blockId"], params["attachmentId"])
|
||||
if err != nil {
|
||||
if errors.Is(err, db.ErrBlockAttachmentNotFound) {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusNotFound, "attachment not found")
|
||||
@@ -507,7 +507,7 @@ func (api *API) UpsertBlockProperties(w http.ResponseWriter, r *http.Request, pa
|
||||
Sprint: req.Sprint,
|
||||
Description: req.Description,
|
||||
}
|
||||
bp, err = api.store(r).UpsertBlockProperties(params["boardId"], params["blockId"], bp)
|
||||
bp, err = api.store(r).UpsertBlockProperties(r.Context(), params["boardId"], params["blockId"], bp)
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusNotFound, "block not found")
|
||||
|
||||
@@ -55,7 +55,7 @@ func (api *API) CreateBoardFieldValue(w http.ResponseWriter, r *http.Request, pa
|
||||
StartDate: req.StartDate,
|
||||
EndDate: req.EndDate,
|
||||
}
|
||||
created, err = api.store(r).CreateBoardFieldValue(params["boardId"], fv)
|
||||
created, err = api.store(r).CreateBoardFieldValue(r.Context(), params["boardId"], fv)
|
||||
if err != nil {
|
||||
if errors.Is(err, db.ErrBoardNotFound) {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusNotFound, "board not found")
|
||||
@@ -114,7 +114,7 @@ func (api *API) ReorderBoardFieldValues(w http.ResponseWriter, r *http.Request,
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, "ids are required")
|
||||
return
|
||||
}
|
||||
values, err = api.store(r).ReorderBoardFieldValues(params["boardId"], params["field"], req.IDs)
|
||||
values, err = api.store(r).ReorderBoardFieldValues(r.Context(), params["boardId"], params["field"], req.IDs)
|
||||
if err != nil {
|
||||
if errors.Is(err, db.ErrBoardNotFound) {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusNotFound, "board not found")
|
||||
@@ -135,7 +135,7 @@ func (api *API) DeleteBoardFieldValue(w http.ResponseWriter, r *http.Request, pa
|
||||
if !api.requireBoardRole(w, r, params["boardId"], "admin") {
|
||||
return
|
||||
}
|
||||
err = api.store(r).DeleteBoardFieldValue(params["boardId"], params["valueId"])
|
||||
err = api.store(r).DeleteBoardFieldValue(r.Context(), params["boardId"], params["valueId"])
|
||||
if err != nil {
|
||||
if errors.Is(err, db.ErrFieldValueNotFound) {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusNotFound, "field value not found")
|
||||
|
||||
@@ -262,7 +262,7 @@ func (api *API) CreateBoard(w http.ResponseWriter, r *http.Request, params map[s
|
||||
IsTemplate: req.IsTemplate,
|
||||
CreatedBy: user.ID,
|
||||
}
|
||||
created, err = api.store(r).CreateBoard(board)
|
||||
created, err = api.store(r).CreateBoard(r.Context(), board)
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
@@ -443,7 +443,7 @@ func (api *API) CreateBlock(w http.ResponseWriter, r *http.Request, params map[s
|
||||
CreatedBy: user.ID,
|
||||
UpdatedBy: user.ID,
|
||||
}
|
||||
created, err = api.store(r).CreateBlock(block)
|
||||
created, err = api.store(r).CreateBlock(r.Context(), block)
|
||||
if err != nil {
|
||||
if errors.Is(err, db.ErrParentNotInBoard) {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
@@ -515,7 +515,7 @@ func (api *API) UpdateBlock(w http.ResponseWriter, r *http.Request, params map[s
|
||||
}
|
||||
}
|
||||
block.UpdatedBy = user.ID
|
||||
updated, err = api.store(r).UpdateBlock(block)
|
||||
updated, err = api.store(r).UpdateBlock(r.Context(), block)
|
||||
if err != nil {
|
||||
if errors.Is(err, db.ErrParentNotInBoard) || errors.Is(err, db.ErrParentCycle) {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
@@ -546,7 +546,7 @@ func (api *API) PatchBlocks(w http.ResponseWriter, r *http.Request, params map[s
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, "invalid json")
|
||||
return
|
||||
}
|
||||
err = api.store(r).PatchBlocks(params["boardId"], patches, user.ID)
|
||||
err = api.store(r).PatchBlocks(r.Context(), params["boardId"], patches, user.ID)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusNotFound, "block not found")
|
||||
@@ -575,7 +575,7 @@ func (api *API) DeleteBlock(w http.ResponseWriter, r *http.Request, params map[s
|
||||
if !api.requireBoardRole(w, r, params["boardId"], "editor") {
|
||||
return
|
||||
}
|
||||
err = api.store(r).DeleteBlock(params["boardId"], params["blockId"], user.ID)
|
||||
err = api.store(r).DeleteBlock(r.Context(), params["boardId"], params["blockId"], user.ID)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusNotFound, "block not found")
|
||||
@@ -661,7 +661,7 @@ func (api *API) AddBoardMember(w http.ResponseWriter, r *http.Request, params ma
|
||||
UserID: req.UserID,
|
||||
Role: role,
|
||||
}
|
||||
err = api.store(r).UpsertBoardMember(member)
|
||||
err = api.store(r).UpsertBoardMember(r.Context(), member)
|
||||
if err != nil {
|
||||
if errors.Is(err, db.ErrBoardNotFound) || errors.Is(err, db.ErrUserNotFound) {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusNotFound, err.Error())
|
||||
@@ -697,7 +697,7 @@ func (api *API) UpdateBoardMember(w http.ResponseWriter, r *http.Request, params
|
||||
UserID: params["userId"],
|
||||
Role: role,
|
||||
}
|
||||
err = api.store(r).UpsertBoardMember(member)
|
||||
err = api.store(r).UpsertBoardMember(r.Context(), member)
|
||||
if err != nil {
|
||||
if errors.Is(err, db.ErrBoardNotFound) || errors.Is(err, db.ErrUserNotFound) {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusNotFound, err.Error())
|
||||
|
||||
@@ -435,7 +435,7 @@ func (api *API) oidcSyncUserGroups(ctx context.Context, provider models.AuthProv
|
||||
mode = strings.TrimSpace(provider.GroupSyncMode)
|
||||
if mode == db.GroupSyncModeOff || mode == "" {
|
||||
if isNew && strings.TrimSpace(provider.DefaultUserGroupID) != "" {
|
||||
err = api.storeContext(ctx).AddUserGroupMember(provider.DefaultUserGroupID, user.ID)
|
||||
err = api.storeContext(ctx).AddUserGroupMember(ctx, provider.DefaultUserGroupID, user.ID)
|
||||
if err != nil { return fmt.Errorf("oidc default user group assignment failed: %w", err) }
|
||||
}
|
||||
return nil
|
||||
@@ -466,17 +466,17 @@ func (api *API) oidcSyncUserGroups(ctx context.Context, provider models.AuthProv
|
||||
assignedAny = false
|
||||
for groupID, matched = range groupMatched {
|
||||
if matched {
|
||||
err = api.storeContext(ctx).AddUserGroupMember(groupID, user.ID)
|
||||
err = api.storeContext(ctx).AddUserGroupMember(ctx, groupID, user.ID)
|
||||
if err != nil { return fmt.Errorf("oidc sso group assignment failed: %w", err) }
|
||||
assignedAny = true
|
||||
} else if mode == db.GroupSyncModeSync {
|
||||
err = api.storeContext(ctx).RemoveUserGroupMember(groupID, user.ID)
|
||||
err = api.storeContext(ctx).RemoveUserGroupMember(ctx, groupID, user.ID)
|
||||
if err != nil { return fmt.Errorf("oidc sso group removal failed: %w", err) }
|
||||
}
|
||||
}
|
||||
|
||||
if isNew && !assignedAny && strings.TrimSpace(provider.DefaultUserGroupID) != "" {
|
||||
err = api.storeContext(ctx).AddUserGroupMember(provider.DefaultUserGroupID, user.ID)
|
||||
err = api.storeContext(ctx).AddUserGroupMember(ctx, provider.DefaultUserGroupID, user.ID)
|
||||
if err != nil { return fmt.Errorf("oidc default user group assignment failed: %w", err) }
|
||||
}
|
||||
|
||||
|
||||
@@ -213,7 +213,7 @@ func (api *API) CreatePKIClientProfile(w http.ResponseWriter, r *http.Request, _
|
||||
if hasCurrentUser {
|
||||
item.CreatedByUserID = currentUser.ID
|
||||
}
|
||||
item, err = api.store(r).CreatePKIClientProfile(item)
|
||||
item, err = api.store(r).CreatePKIClientProfile(r.Context(), item)
|
||||
if err != nil {
|
||||
api.Logger.Write(logIDPKI, codit_logger.LOG_WARN, "client profile create failed name=%s err=%v", item.Name, err)
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
@@ -296,7 +296,7 @@ func (api *API) UpdatePKIClientProfile(w http.ResponseWriter, r *http.Request, p
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, "name is required")
|
||||
return
|
||||
}
|
||||
existing, err = api.store(r).UpdatePKIClientProfile(existing)
|
||||
existing, err = api.store(r).UpdatePKIClientProfile(r.Context(), existing)
|
||||
if err != nil {
|
||||
api.Logger.Write(logIDPKI, codit_logger.LOG_WARN, "client profile update failed id=%s err=%v", params["id"], err)
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
@@ -448,7 +448,7 @@ func (api *API) IssuePKIClientCertForSelf(w http.ResponseWriter, r *http.Request
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, "generated SAN URI is invalid")
|
||||
return
|
||||
}
|
||||
serial, err = api.store(r).NextPKICASerial(ca.ID)
|
||||
serial, err = api.store(r).NextPKICASerial(r.Context(), ca.ID)
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
|
||||
@@ -531,7 +531,7 @@ func (api *API) IssuePKICert(w http.ResponseWriter, r *http.Request, _ map[strin
|
||||
WriteJSONWithErrorReason(w, r, http.StatusNotFound, "CA not found")
|
||||
return
|
||||
}
|
||||
serial, err = api.store(r).NextPKICASerial(ca.ID)
|
||||
serial, err = api.store(r).NextPKICASerial(r.Context(), ca.ID)
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
@@ -884,7 +884,7 @@ func (api *API) DeletePKICA(w http.ResponseWriter, r *http.Request, params map[s
|
||||
return
|
||||
}
|
||||
if force {
|
||||
err = api.store(r).DeletePKICASubtree(ca.ID)
|
||||
err = api.store(r).DeletePKICASubtree(r.Context(), ca.ID)
|
||||
} else {
|
||||
err = api.store(r).DeletePKICA(ca.ID)
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ func (api *API) finishSSHFileTransferAudit(audit *sshFileTransferAudit, status s
|
||||
return
|
||||
}
|
||||
audit.Finished = true
|
||||
err = audit.Store.FinishSSHFileTransfer(audit.Item.ID, status, audit.Paths, audit.Bytes, audit.ErrorText)
|
||||
err = audit.Store.FinishSSHFileTransfer(context.Background(), audit.Item.ID, status, audit.Paths, audit.Bytes, audit.ErrorText)
|
||||
if err != nil {
|
||||
api.Logger.Write(logIDSSHBroker, codit_logger.LOG_WARN, "ssh file transfer audit finish failed id=%s op=%s err=%s", audit.Item.ID, audit.Item.Operation, err.Error())
|
||||
return
|
||||
@@ -308,7 +308,7 @@ func (api *API) UploadSSHSessionFilesForSelf(w http.ResponseWriter, r *http.Requ
|
||||
if audit != nil {
|
||||
audit.Paths = append(audit.Paths, remotePath)
|
||||
}
|
||||
sshClient, err = api.openSSHSessionFileTransferClient(store, user, sessionItem, password, otpCode)
|
||||
sshClient, err = api.openSSHSessionFileTransferClient(r.Context(), store, user, sessionItem, password, otpCode)
|
||||
if err != nil {
|
||||
if audit != nil {
|
||||
audit.ErrorText = err.Error()
|
||||
@@ -428,7 +428,7 @@ func (api *API) DownloadSSHSessionFilesForSelf(w http.ResponseWriter, r *http.Re
|
||||
api.writeSSHSessionFileTransferError(w, r, err)
|
||||
return
|
||||
}
|
||||
sshClient, err = api.openSSHSessionFileTransferClient(store, user, sessionItem, req.Password, req.OTPCode)
|
||||
sshClient, err = api.openSSHSessionFileTransferClient(r.Context(), store, user, sessionItem, req.Password, req.OTPCode)
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
@@ -601,7 +601,7 @@ func (api *API) CopySSHSessionFilesForSelf(w http.ResponseWriter, r *http.Reques
|
||||
api.writeSSHSessionFileTransferError(w, r, err)
|
||||
return
|
||||
}
|
||||
sourceSSHClient, err = api.openSSHSessionFileTransferClient(store, user, sourceSession, req.SourcePassword, req.SourceOTPCode)
|
||||
sourceSSHClient, err = api.openSSHSessionFileTransferClient(r.Context(), store, user, sourceSession, req.SourcePassword, req.SourceOTPCode)
|
||||
if err != nil {
|
||||
WriteJSON(w, http.StatusBadRequest, map[string]string{"error": "source session: " + err.Error()})
|
||||
return
|
||||
@@ -609,7 +609,7 @@ func (api *API) CopySSHSessionFilesForSelf(w http.ResponseWriter, r *http.Reques
|
||||
stopSourceClose = closeSSHClientOnContext(r.Context(), sourceSSHClient)
|
||||
defer stopSourceClose()
|
||||
defer sourceSSHClient.Close()
|
||||
targetSSHClient, err = api.openSSHSessionFileTransferClient(store, user, targetSession, req.TargetPassword, req.TargetOTPCode)
|
||||
targetSSHClient, err = api.openSSHSessionFileTransferClient(r.Context(), store, user, targetSession, req.TargetPassword, req.TargetOTPCode)
|
||||
if err != nil {
|
||||
WriteJSON(w, http.StatusBadRequest, map[string]string{"error": "target session: " + err.Error()})
|
||||
return
|
||||
@@ -775,7 +775,7 @@ func (api *API) writeSSHSessionFileTransferError(w http.ResponseWriter, r *http.
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
}
|
||||
|
||||
func (api *API) openSSHSessionFileTransferClient(store *db.Store, user models.User, sessionItem models.SSHSession, promptedPassword string, otpCode string) (*ssh.Client, error) {
|
||||
func (api *API) openSSHSessionFileTransferClient(ctx context.Context, store *db.Store, user models.User, sessionItem models.SSHSession, promptedPassword string, otpCode string) (*ssh.Client, error) {
|
||||
var prepared sshSessionPrepared
|
||||
var prepareStage string
|
||||
var sshConfig *ssh.ClientConfig
|
||||
@@ -784,7 +784,7 @@ func (api *API) openSSHSessionFileTransferClient(store *db.Store, user models.Us
|
||||
var connectedHostKey ssh.PublicKey
|
||||
var err error
|
||||
|
||||
prepared, prepareStage, err = api.prepareSSHSession(store, &user, &sessionItem, promptedPassword, otpCode)
|
||||
prepared, prepareStage, err = api.prepareSSHSession(ctx, store, &user, &sessionItem, promptedPassword, otpCode)
|
||||
if err != nil {
|
||||
if prepareStage == sshPrepareStageLoadProfile {
|
||||
return nil, errors.New("ssh access profile not found")
|
||||
|
||||
@@ -442,7 +442,7 @@ func (api *API) DeleteSSHServerAdmin(w http.ResponseWriter, r *http.Request, par
|
||||
if !api.requireAdmin(w, r) {
|
||||
return
|
||||
}
|
||||
err = api.store(r).DeleteSSHServer(params["id"])
|
||||
err = api.store(r).DeleteSSHServer(r.Context(), params["id"])
|
||||
if err != nil {
|
||||
if errors.As(err, &referenceErr) {
|
||||
WriteJSON(w, http.StatusConflict, map[string]string{"error": err.Error() + "; remove the references first or disable the server instead"})
|
||||
@@ -491,7 +491,7 @@ func (api *API) CreateSSHServerGroupAdmin(w http.ResponseWriter, r *http.Request
|
||||
}
|
||||
|
||||
item = models.SSHServerGroup{Name: strings.TrimSpace(req.Name), Description: strings.TrimSpace(req.Description), Enabled: req.Enabled, Tags: req.Tags, CreatedByKind: "user", CreatedBySubjectID: user.ID, CreatedBySubjectName: user.Username}
|
||||
item, err = api.store(r).CreateSSHServerGroup(item)
|
||||
item, err = api.store(r).CreateSSHServerGroup(r.Context(), item)
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
@@ -518,7 +518,7 @@ func (api *API) UpdateSSHServerGroupAdmin(w http.ResponseWriter, r *http.Request
|
||||
item.Description = strings.TrimSpace(req.Description)
|
||||
item.Enabled = req.Enabled
|
||||
item.Tags = req.Tags
|
||||
item, err = api.store(r).UpdateSSHServerGroup(item)
|
||||
item, err = api.store(r).UpdateSSHServerGroup(r.Context(), item)
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
@@ -529,7 +529,7 @@ func (api *API) UpdateSSHServerGroupAdmin(w http.ResponseWriter, r *http.Request
|
||||
func (api *API) DeleteSSHServerGroupAdmin(w http.ResponseWriter, r *http.Request, params map[string]string) {
|
||||
var err error
|
||||
if !api.requireAdmin(w, r) { return }
|
||||
err = api.store(r).DeleteSSHServerGroup(params["id"])
|
||||
err = api.store(r).DeleteSSHServerGroup(r.Context(), params["id"])
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
@@ -658,7 +658,7 @@ func (api *API) CreateSSHCredentialAdmin(w http.ResponseWriter, r *http.Request,
|
||||
CreatedBySubjectName: user.Username,
|
||||
}
|
||||
secret = models.SSHSecret{Payload: encrypted}
|
||||
item, err = api.store(r).CreateSSHCredential(item, secret)
|
||||
item, err = api.store(r).CreateSSHCredential(r.Context(), item, secret)
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
@@ -695,7 +695,7 @@ func (api *API) UpdateSSHCredentialAdmin(w http.ResponseWriter, r *http.Request,
|
||||
func (api *API) DeleteSSHCredentialAdmin(w http.ResponseWriter, r *http.Request, params map[string]string) {
|
||||
var err error
|
||||
if !api.requireAdmin(w, r) { return }
|
||||
err = api.store(r).DeleteSSHCredential(params["id"])
|
||||
err = api.store(r).DeleteSSHCredential(r.Context(), params["id"])
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
@@ -772,7 +772,7 @@ func (api *API) CreateSSHCredentialForSelf(w http.ResponseWriter, r *http.Reques
|
||||
CreatedBySubjectName: user.Username,
|
||||
}
|
||||
secret = models.SSHSecret{Payload: encrypted}
|
||||
item, err = api.store(r).CreateSSHCredential(item, secret)
|
||||
item, err = api.store(r).CreateSSHCredential(r.Context(), item, secret)
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
@@ -828,7 +828,7 @@ func (api *API) DeleteSSHCredentialForSelf(w http.ResponseWriter, r *http.Reques
|
||||
WriteJSONWithErrorReason(w, r, http.StatusNotFound, "ssh credential not found")
|
||||
return
|
||||
}
|
||||
err = api.store(r).DeleteSSHCredential(params["id"])
|
||||
err = api.store(r).DeleteSSHCredential(r.Context(), params["id"])
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
@@ -900,7 +900,7 @@ func (api *API) CreateSSHAccessProfileAdmin(w http.ResponseWriter, r *http.Reque
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
item, err = api.store(r).CreateSSHAccessProfile(item)
|
||||
item, err = api.store(r).CreateSSHAccessProfile(r.Context(), item)
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
@@ -948,7 +948,7 @@ func (api *API) UpdateSSHAccessProfileAdmin(w http.ResponseWriter, r *http.Reque
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
item, err = api.store(r).UpdateSSHAccessProfile(item)
|
||||
item, err = api.store(r).UpdateSSHAccessProfile(r.Context(), item)
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
@@ -962,7 +962,7 @@ func (api *API) DeleteSSHAccessProfileAdmin(w http.ResponseWriter, r *http.Reque
|
||||
if !api.requireAdmin(w, r) {
|
||||
return
|
||||
}
|
||||
err = api.store(r).DeleteSSHAccessProfile(params["id"])
|
||||
err = api.store(r).DeleteSSHAccessProfile(r.Context(), params["id"])
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusNotFound, "ssh access profile not found")
|
||||
@@ -1304,7 +1304,7 @@ func (api *API) DeleteSSHServerForSelf(w http.ResponseWriter, r *http.Request, p
|
||||
WriteJSONWithErrorReason(w, r, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
err = api.store(r).DeleteSSHServer(params["id"])
|
||||
err = api.store(r).DeleteSSHServer(r.Context(), params["id"])
|
||||
if err != nil {
|
||||
if errors.As(err, &referenceErr) {
|
||||
WriteJSON(w, http.StatusConflict, map[string]string{"error": err.Error() + "; remove the references first or disable the server instead"})
|
||||
@@ -1478,7 +1478,7 @@ func (api *API) CreateSSHAccessProfileForSelf(w http.ResponseWriter, r *http.Req
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
item, err = api.store(r).CreateSSHAccessProfile(item)
|
||||
item, err = api.store(r).CreateSSHAccessProfile(r.Context(), item)
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
@@ -1530,7 +1530,7 @@ func (api *API) UpdateSSHAccessProfileForSelf(w http.ResponseWriter, r *http.Req
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
item, err = api.store(r).UpdateSSHAccessProfile(item)
|
||||
item, err = api.store(r).UpdateSSHAccessProfile(r.Context(), item)
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
@@ -1562,7 +1562,7 @@ func (api *API) DeleteSSHAccessProfileForSelf(w http.ResponseWriter, r *http.Req
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
err = api.store(r).DeleteSSHAccessProfile(item.ID)
|
||||
err = api.store(r).DeleteSSHAccessProfile(r.Context(), item.ID)
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
@@ -1789,7 +1789,7 @@ func (api *API) CreateSSHSessionForSelf(w http.ResponseWriter, r *http.Request,
|
||||
return
|
||||
}
|
||||
|
||||
prepared, prepareStage, err = api.prepareSSHSession(api.store(r), &user, &item, req.Password, req.OTPCode)
|
||||
prepared, prepareStage, err = api.prepareSSHSession(r.Context(), api.store(r), &user, &item, req.Password, req.OTPCode)
|
||||
if err != nil {
|
||||
if prepareStage == sshPrepareStageHostKeyMissing || prepareStage == sshPrepareStageBuildAuth {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
@@ -2564,7 +2564,7 @@ func discoverSSHServerHostKey(host string, port int, defaultUser string) (models
|
||||
return item, nil
|
||||
}
|
||||
|
||||
func (api *API) prepareSSHSession(store *db.Store, user *models.User, sessionItem *models.SSHSession, promptedPassword string, otpCode string) (sshSessionPrepared, string, error) {
|
||||
func (api *API) prepareSSHSession(ctx context.Context, store *db.Store, user *models.User, sessionItem *models.SSHSession, promptedPassword string, otpCode string) (sshSessionPrepared, string, error) {
|
||||
var prepared sshSessionPrepared
|
||||
var err error
|
||||
|
||||
@@ -2593,7 +2593,7 @@ func (api *API) prepareSSHSession(store *db.Store, user *models.User, sessionIte
|
||||
prepared.PinHostKeyOnFirstUse = true
|
||||
}
|
||||
|
||||
prepared.AuthMethods, err = api.buildSSHSessionAuth(store, prepared.Profile, promptedPassword, otpCode)
|
||||
prepared.AuthMethods, err = api.buildSSHSessionAuth(ctx, store, prepared.Profile, promptedPassword, otpCode)
|
||||
if err != nil {
|
||||
return prepared, sshPrepareStageBuildAuth, err
|
||||
}
|
||||
@@ -3013,7 +3013,7 @@ func (api *API) runSSHSessionStream(store *db.Store, user *models.User, sessionI
|
||||
api.logSSHSessionPreparedUse(sessionItem, user, &profile)
|
||||
} else {
|
||||
prepared = &sshSessionPrepared{}
|
||||
*prepared, prepareStage, err = api.prepareSSHSession(store, user, sessionItem, promptedPassword, promptedOTPCode)
|
||||
*prepared, prepareStage, err = api.prepareSSHSession(context.Background(), store, user, sessionItem, promptedPassword, promptedOTPCode)
|
||||
if err != nil {
|
||||
if prepareStage == sshPrepareStageLoadProfile {
|
||||
api.logSSHSessionPrepareFailure(sessionItem, user, prepareStage, err)
|
||||
@@ -3622,7 +3622,7 @@ func appendSSHSecondFactorAuthMethods(methods []ssh.AuthMethod, profile models.S
|
||||
return methods, nil
|
||||
}
|
||||
|
||||
func (api *API) buildSSHSessionAuth(store *db.Store, profile models.SSHAccessProfile, promptedPassword string, otpCode string) ([]ssh.AuthMethod, error) {
|
||||
func (api *API) buildSSHSessionAuth(ctx context.Context, store *db.Store, profile models.SSHAccessProfile, promptedPassword string, otpCode string) ([]ssh.AuthMethod, error) {
|
||||
var methods []ssh.AuthMethod
|
||||
var secret models.SSHSecret
|
||||
var credential models.SSHCredential
|
||||
@@ -3682,7 +3682,7 @@ func (api *API) buildSSHSessionAuth(store *db.Store, profile models.SSHAccessPro
|
||||
principals, err = api.resolveSSHAccessProfilePrincipals(store, profile)
|
||||
if err != nil { return nil, err }
|
||||
|
||||
signed, err = api.signSSHUserKeyWithCA(store, ca, profile.AuthPublicKey, "", principals, profile.DefaultCertValidSeconds, profile.MaxCertValidSeconds)
|
||||
signed, err = api.signSSHUserKeyWithCA(ctx, store, ca, profile.AuthPublicKey, "", principals, profile.DefaultCertValidSeconds, profile.MaxCertValidSeconds)
|
||||
if err != nil { return nil, err }
|
||||
|
||||
certKey, _, _, _, err = ssh.ParseAuthorizedKey([]byte(strings.TrimSpace(signed.Certificate)))
|
||||
|
||||
@@ -182,7 +182,7 @@ func (api *API) CreateSSHPrincipalGrant(w http.ResponseWriter, r *http.Request,
|
||||
if hasCurrentUser {
|
||||
item.CreatedByUserID = currentUser.ID
|
||||
}
|
||||
item, err = api.store(r).CreateSSHPrincipalGrant(item)
|
||||
item, err = api.store(r).CreateSSHPrincipalGrant(r.Context(), item)
|
||||
if err != nil {
|
||||
api.Logger.Write(logIDSSHCA, codit_logger.LOG_WARN, "grant create failed name=%s err=%v", name, err)
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
@@ -254,7 +254,7 @@ func (api *API) UpdateSSHPrincipalGrant(w http.ResponseWriter, r *http.Request,
|
||||
item.Disabled = req.Disabled
|
||||
item.Reason = strings.TrimSpace(req.Reason)
|
||||
item.Targets = targets
|
||||
item, err = api.store(r).UpdateSSHPrincipalGrant(item)
|
||||
item, err = api.store(r).UpdateSSHPrincipalGrant(r.Context(), item)
|
||||
if err != nil {
|
||||
api.Logger.Write(logIDSSHCA, codit_logger.LOG_WARN, "grant update failed id=%s err=%v", params["id"], err)
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package handlers
|
||||
|
||||
import "context"
|
||||
import codit_logger "codit/logger"
|
||||
import "crypto/ed25519"
|
||||
import "crypto/ecdsa"
|
||||
@@ -378,7 +379,7 @@ func (api *API) SignSSHUserKey(w http.ResponseWriter, r *http.Request, params ma
|
||||
return
|
||||
}
|
||||
validSeconds = req.ValidSeconds
|
||||
response, err = api.signSSHUserKeyWithCA(api.store(r), item, sourcePublicKey, strings.TrimSpace(req.KeyID), principals, validSeconds, 604800)
|
||||
response, err = api.signSSHUserKeyWithCA(r.Context(), api.store(r), item, sourcePublicKey, strings.TrimSpace(req.KeyID), principals, validSeconds, 604800)
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
@@ -708,9 +709,9 @@ func (api *API) SignSSHUserKeyForSelf(w http.ResponseWriter, r *http.Request, pa
|
||||
}
|
||||
validSeconds = req.ValidSeconds
|
||||
if maxGrantValidSeconds > 0 && maxGrantValidSeconds < item.MaxUserValidSeconds {
|
||||
response, err = api.signSSHUserKeyWithCA(api.store(r), item, sourcePublicKey, strings.TrimSpace(req.KeyID), principals, validSeconds, maxGrantValidSeconds)
|
||||
response, err = api.signSSHUserKeyWithCA(r.Context(), api.store(r), item, sourcePublicKey, strings.TrimSpace(req.KeyID), principals, validSeconds, maxGrantValidSeconds)
|
||||
} else {
|
||||
response, err = api.signSSHUserKeyWithCA(api.store(r), item, sourcePublicKey, strings.TrimSpace(req.KeyID), principals, validSeconds, item.MaxUserValidSeconds)
|
||||
response, err = api.signSSHUserKeyWithCA(r.Context(), api.store(r), item, sourcePublicKey, strings.TrimSpace(req.KeyID), principals, validSeconds, item.MaxUserValidSeconds)
|
||||
}
|
||||
if err != nil {
|
||||
WriteJSONWithErrorReason(w, r, http.StatusBadRequest, err.Error())
|
||||
@@ -734,7 +735,7 @@ func (api *API) SignSSHUserKeyForSelf(w http.ResponseWriter, r *http.Request, pa
|
||||
WriteJSON(w, http.StatusOK, response)
|
||||
}
|
||||
|
||||
func (api *API) signSSHUserKeyWithCA(store *db.Store, item models.SSHUserCA, publicKey string, keyID string, principals []string, validSeconds int64, maxValidSeconds int64) (sshSignUserKeyResponse, error) {
|
||||
func (api *API) signSSHUserKeyWithCA(ctx context.Context, store *db.Store, item models.SSHUserCA, publicKey string, keyID string, principals []string, validSeconds int64, maxValidSeconds int64) (sshSignUserKeyResponse, error) {
|
||||
var response sshSignUserKeyResponse
|
||||
var signer ssh.Signer
|
||||
var key ssh.PublicKey
|
||||
@@ -765,7 +766,7 @@ func (api *API) signSSHUserKeyWithCA(store *db.Store, item models.SSHUserCA, pub
|
||||
if validSeconds < 60 || validSeconds > maxValidSeconds {
|
||||
return response, fmt.Errorf("valid_seconds must be between 60 and %d", maxValidSeconds)
|
||||
}
|
||||
serial, err = store.NextSSHUserCASerial(item.ID)
|
||||
serial, err = store.NextSSHUserCASerial(ctx, item.ID)
|
||||
if err != nil {
|
||||
return response, err
|
||||
}
|
||||
|
||||
@@ -57,14 +57,14 @@ func WithUserCookie(store *db.Store, sessionCookieName string, next http.Handler
|
||||
return
|
||||
}
|
||||
hash = util.HashToken(token)
|
||||
user, err = activeStore.GetUserByAPIKeyHash(hash)
|
||||
user, err = activeStore.GetUserByAPIKeyHash(r.Context(), hash)
|
||||
if err == nil {
|
||||
rememberUser(r.Context(), user)
|
||||
ctx = context.WithValue(r.Context(), userKey, user)
|
||||
next.ServeHTTP(w, r.WithContext(ctx))
|
||||
return
|
||||
}
|
||||
principal, err = activeStore.GetPrincipalByAPIKeyHash(hash)
|
||||
principal, err = activeStore.GetPrincipalByAPIKeyHash(r.Context(), hash)
|
||||
if err != nil {
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
@@ -82,14 +82,14 @@ func WithUserCookie(store *db.Store, sessionCookieName string, next http.Handler
|
||||
return
|
||||
}
|
||||
hash = util.HashToken(token)
|
||||
user, err = activeStore.GetUserByAPIKeyHash(hash)
|
||||
user, err = activeStore.GetUserByAPIKeyHash(r.Context(), hash)
|
||||
if err == nil {
|
||||
rememberUser(r.Context(), user)
|
||||
ctx = context.WithValue(r.Context(), userKey, user)
|
||||
next.ServeHTTP(w, r.WithContext(ctx))
|
||||
return
|
||||
}
|
||||
principal, err = activeStore.GetPrincipalByAPIKeyHash(hash)
|
||||
principal, err = activeStore.GetPrincipalByAPIKeyHash(r.Context(), hash)
|
||||
if err != nil {
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
|
||||
@@ -131,7 +131,7 @@ func (m *MirrorManager) Start() {
|
||||
if m == nil {
|
||||
return
|
||||
}
|
||||
err = m.store.ResetRunningRPMMirrorTasks()
|
||||
err = m.store.ResetRunningRPMMirrorTasks(context.Background())
|
||||
if err != nil && m.logger != nil {
|
||||
m.logger.Write(logIDRPMMirror, codit_logger.LOG_ERROR, "reset running tasks failed err=%v", err)
|
||||
}
|
||||
@@ -199,7 +199,7 @@ func (m *MirrorManager) runDue() {
|
||||
return
|
||||
}
|
||||
for i = 0; i < len(tasks); i++ {
|
||||
runID, started, err = m.store.TryStartRPMMirrorRun(tasks[i].RepoID, tasks[i].MirrorPath, now)
|
||||
runID, started, err = m.store.TryStartRPMMirrorRun(context.Background(), tasks[i].RepoID, tasks[i].MirrorPath, now)
|
||||
if err != nil {
|
||||
if m.logger != nil {
|
||||
m.logger.Write(logIDRPMMirror, codit_logger.LOG_ERROR, "try start failed repo=%s path=%s err=%v", tasks[i].RepoID, tasks[i].MirrorPath, err)
|
||||
@@ -353,7 +353,7 @@ func (m *MirrorManager) finishTaskRun(task models.RPMMirrorTask, runID string, s
|
||||
var err error
|
||||
|
||||
finishedAt = time.Now().UTC().Unix()
|
||||
err = m.store.FinishRPMMirrorTaskRun(task.RepoID, task.MirrorPath, runID, success, finishedAt, step, total, done, failed, deleted, revision, errMsg)
|
||||
err = m.store.FinishRPMMirrorTaskRun(context.Background(), task.RepoID, task.MirrorPath, runID, success, finishedAt, step, total, done, failed, deleted, revision, errMsg)
|
||||
if err != nil && m.logger != nil {
|
||||
m.logger.Write(logIDRPMMirror, codit_logger.LOG_ERROR, "finish sync state failed repo=%s path=%s run=%s err=%v", task.RepoID, task.MirrorPath, runID, err)
|
||||
}
|
||||
|
||||
+6
-6
@@ -362,22 +362,22 @@ func auth_user(store *db.Store, username string, password string) (bool, error)
|
||||
if err != nil || hash == "" {
|
||||
if password != "" {
|
||||
key = password
|
||||
user, err = store.GetUserByAPIKeyHash(util.HashToken(key))
|
||||
user, err = store.GetUserByAPIKeyHash(context.Background(), util.HashToken(key))
|
||||
if err == nil {
|
||||
return true, nil
|
||||
}
|
||||
principal, err = store.GetPrincipalByAPIKeyHash(util.HashToken(key))
|
||||
principal, err = store.GetPrincipalByAPIKeyHash(context.Background(), util.HashToken(key))
|
||||
if err == nil {
|
||||
return !principal.Disabled, nil
|
||||
}
|
||||
}
|
||||
if password == "" && username != "" {
|
||||
key = username
|
||||
user, err = store.GetUserByAPIKeyHash(util.HashToken(key))
|
||||
user, err = store.GetUserByAPIKeyHash(context.Background(), util.HashToken(key))
|
||||
if err == nil {
|
||||
return true, nil
|
||||
}
|
||||
principal, err = store.GetPrincipalByAPIKeyHash(util.HashToken(key))
|
||||
principal, err = store.GetPrincipalByAPIKeyHash(context.Background(), util.HashToken(key))
|
||||
if err == nil {
|
||||
return !principal.Disabled, nil
|
||||
}
|
||||
@@ -388,11 +388,11 @@ func auth_user(store *db.Store, username string, password string) (bool, error)
|
||||
if err != nil {
|
||||
if password != "" {
|
||||
key = password
|
||||
user, err = store.GetUserByAPIKeyHash(util.HashToken(key))
|
||||
user, err = store.GetUserByAPIKeyHash(context.Background(), util.HashToken(key))
|
||||
if err == nil {
|
||||
return true, nil
|
||||
}
|
||||
principal, err = store.GetPrincipalByAPIKeyHash(util.HashToken(key))
|
||||
principal, err = store.GetPrincipalByAPIKeyHash(context.Background(), util.HashToken(key))
|
||||
if err == nil {
|
||||
return !principal.Disabled, nil
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package tests
|
||||
|
||||
import "context"
|
||||
import "database/sql"
|
||||
import "path/filepath"
|
||||
import "testing"
|
||||
@@ -127,7 +128,7 @@ func TestAPIKeyAuthSuccess(t *testing.T) {
|
||||
defer store.Close()
|
||||
user = createTestUser(t, store, "alice")
|
||||
token = createAPIKey(t, store, user.ID, "default", 0)
|
||||
got, err = store.GetUserByAPIKeyHash(util.HashToken(token))
|
||||
got, err = store.GetUserByAPIKeyHash(context.Background(), util.HashToken(token))
|
||||
if err != nil {
|
||||
t.Fatalf("lookup by api key: %v", err)
|
||||
}
|
||||
@@ -145,7 +146,7 @@ func TestAPIKeyAuthExpiredKeyFails(t *testing.T) {
|
||||
defer store.Close()
|
||||
user = createTestUser(t, store, "bob")
|
||||
token = createAPIKey(t, store, user.ID, "expired", time.Now().UTC().Unix()-60)
|
||||
_, err = store.GetUserByAPIKeyHash(util.HashToken(token))
|
||||
_, err = store.GetUserByAPIKeyHash(context.Background(), util.HashToken(token))
|
||||
if err == nil {
|
||||
t.Fatalf("expected error for expired key")
|
||||
}
|
||||
@@ -177,7 +178,7 @@ func TestAPIKeyAuthDisabledKeyFails(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("disable key: %v", err)
|
||||
}
|
||||
_, err = store.GetUserByAPIKeyHash(util.HashToken(token))
|
||||
_, err = store.GetUserByAPIKeyHash(context.Background(), util.HashToken(token))
|
||||
if err == nil {
|
||||
t.Fatalf("expected error for disabled key")
|
||||
}
|
||||
@@ -199,7 +200,7 @@ func TestAPIKeyAuthDisabledUserFails(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("disable user: %v", err)
|
||||
}
|
||||
_, err = store.GetUserByAPIKeyHash(util.HashToken(token))
|
||||
_, err = store.GetUserByAPIKeyHash(context.Background(), util.HashToken(token))
|
||||
if err == nil {
|
||||
t.Fatalf("expected error for disabled user")
|
||||
}
|
||||
@@ -225,7 +226,7 @@ func TestDeleteUserCascadesAPIKeys(t *testing.T) {
|
||||
if len(keys) != 2 {
|
||||
t.Fatalf("expected two keys before delete, got %d", len(keys))
|
||||
}
|
||||
err = store.DeleteUser(user.ID)
|
||||
err = store.DeleteUser(context.Background(), user.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("delete user: %v", err)
|
||||
}
|
||||
@@ -249,7 +250,7 @@ func TestPrincipalAPIKeyAuthSuccess(t *testing.T) {
|
||||
defer store.Close()
|
||||
principal = createTestServicePrincipal(t, store, "robot")
|
||||
token = createPrincipalAPIKey(t, store, principal.ID, "default", 0)
|
||||
got, err = store.GetPrincipalByAPIKeyHash(util.HashToken(token))
|
||||
got, err = store.GetPrincipalByAPIKeyHash(context.Background(), util.HashToken(token))
|
||||
if err != nil {
|
||||
t.Fatalf("lookup principal by api key: %v", err)
|
||||
}
|
||||
@@ -273,7 +274,7 @@ func TestPrincipalAPIKeyAuthDisabledPrincipalFails(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("disable principal: %v", err)
|
||||
}
|
||||
_, err = store.GetPrincipalByAPIKeyHash(util.HashToken(token))
|
||||
_, err = store.GetPrincipalByAPIKeyHash(context.Background(), util.HashToken(token))
|
||||
if err == nil {
|
||||
t.Fatalf("expected error for disabled principal")
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package tests
|
||||
|
||||
import "context"
|
||||
import "testing"
|
||||
|
||||
import "codit/internal/db"
|
||||
@@ -18,7 +19,7 @@ func createTestProject(t *testing.T, store *db.Store, user models.User, slug str
|
||||
UpdatedBy: user.ID,
|
||||
HomePage: "info",
|
||||
}
|
||||
project, err = store.CreateProject(project)
|
||||
project, err = store.CreateProject(context.Background(), project)
|
||||
if err != nil {
|
||||
t.Fatalf("create project: %v", err)
|
||||
}
|
||||
@@ -85,14 +86,14 @@ func TestResetRunningRPMMirrorTasksMarksRunsFailed(t *testing.T) {
|
||||
project = createTestProject(t, store, user, "mirror-reset")
|
||||
repo = createTestRPMRepo(t, store, project, user, "repo")
|
||||
dir = createTestRPMMirrorDir(t, store, repo, "x86_64", 600)
|
||||
runID, started, err = store.TryStartRPMMirrorRun(repo.ID, dir.Path, 1000)
|
||||
runID, started, err = store.TryStartRPMMirrorRun(context.Background(), repo.ID, dir.Path, 1000)
|
||||
if err != nil {
|
||||
t.Fatalf("try start mirror run: %v", err)
|
||||
}
|
||||
if !started {
|
||||
t.Fatalf("expected mirror run to start")
|
||||
}
|
||||
err = store.ResetRunningRPMMirrorTasks()
|
||||
err = store.ResetRunningRPMMirrorTasks(context.Background(), )
|
||||
if err != nil {
|
||||
t.Fatalf("reset running mirror tasks: %v", err)
|
||||
}
|
||||
@@ -147,14 +148,14 @@ func TestFinishRPMMirrorTaskRunUpdatesTaskAndRun(t *testing.T) {
|
||||
project = createTestProject(t, store, user, "mirror-finish")
|
||||
repo = createTestRPMRepo(t, store, project, user, "repo")
|
||||
dir = createTestRPMMirrorDir(t, store, repo, "x86_64", 600)
|
||||
runID, started, err = store.TryStartRPMMirrorRun(repo.ID, dir.Path, 1000)
|
||||
runID, started, err = store.TryStartRPMMirrorRun(context.Background(), repo.ID, dir.Path, 1000)
|
||||
if err != nil {
|
||||
t.Fatalf("try start mirror run: %v", err)
|
||||
}
|
||||
if !started {
|
||||
t.Fatalf("expected mirror run to start")
|
||||
}
|
||||
err = store.FinishRPMMirrorTaskRun(repo.ID, dir.Path, runID, true, 1700, "done", 4, 4, 0, 0, "rev-1", "")
|
||||
err = store.FinishRPMMirrorTaskRun(context.Background(), repo.ID, dir.Path, runID, true, 1700, "done", 4, 4, 0, 0, "rev-1", "")
|
||||
if err != nil {
|
||||
t.Fatalf("finish mirror task run: %v", err)
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package tests
|
||||
|
||||
import "context"
|
||||
import "testing"
|
||||
|
||||
import "codit/internal/models"
|
||||
|
||||
func createTestUserGroup(t *testing.T, store interface {
|
||||
CreateUserGroup(models.UserGroup) (models.UserGroup, error)
|
||||
AddUserGroupMember(string, string) error
|
||||
AddUserGroupMember(context.Context, string, string) error
|
||||
}, name string, userID string) models.UserGroup {
|
||||
var group models.UserGroup
|
||||
var err error
|
||||
@@ -20,7 +21,7 @@ func createTestUserGroup(t *testing.T, store interface {
|
||||
if err != nil {
|
||||
t.Fatalf("create user group: %v", err)
|
||||
}
|
||||
err = store.AddUserGroupMember(group.ID, userID)
|
||||
err = store.AddUserGroupMember(context.Background(), group.ID, userID)
|
||||
if err != nil {
|
||||
t.Fatalf("add user group member: %v", err)
|
||||
}
|
||||
@@ -55,7 +56,7 @@ func TestSSHAccessProfileVisibilityForUserAndGroupTargets(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatalf("create ssh server: %v", err)
|
||||
}
|
||||
created, err = store.CreateSSHAccessProfile(models.SSHAccessProfile{
|
||||
created, err = store.CreateSSHAccessProfile(context.Background(), models.SSHAccessProfile{
|
||||
ServerID: server.ID,
|
||||
Name: "web deploy",
|
||||
Description: "deploy access",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package tests
|
||||
|
||||
import "context"
|
||||
import "testing"
|
||||
import "time"
|
||||
|
||||
@@ -15,7 +16,7 @@ func TestSSHPrincipalGrantStoresMultiplePrincipals(t *testing.T) {
|
||||
|
||||
defer dbStore.Close()
|
||||
user = createTestUser(t, dbStore, "ssh-grant-user")
|
||||
created, err = dbStore.CreateSSHPrincipalGrant(models.SSHPrincipalGrant{
|
||||
created, err = dbStore.CreateSSHPrincipalGrant(context.Background(), models.SSHPrincipalGrant{
|
||||
Name: "hyung-hwan-login",
|
||||
Principals: []string{"hyung-hwan", "ops"},
|
||||
Targets: []models.SSHPrincipalGrantTarget{
|
||||
|
||||
Reference in New Issue
Block a user