mirror of
https://github.com/harness/drone.git
synced 2025-05-09 01:30:26 +08:00

This change introduces the concept of a principal (abstraction of call identity), and adds a new service account type principal. Also adds support for different tokens (session, PAT, SAT, OAuth2) and adds auth.Session which is being used to capture information about the caller and call method.
177 lines
4.9 KiB
Go
177 lines
4.9 KiB
Go
// Copyright 2021 Harness Inc. All rights reserved.
|
|
// Use of this source code is governed by the Polyform Free Trial License
|
|
// that can be found in the LICENSE.md file for this repository.
|
|
|
|
package database
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
|
|
"github.com/harness/gitness/internal/store"
|
|
"github.com/harness/gitness/types"
|
|
"github.com/harness/gitness/types/enum"
|
|
|
|
"github.com/jmoiron/sqlx"
|
|
)
|
|
|
|
var _ store.ServiceAccountStore = (*ServiceAccountStore)(nil)
|
|
|
|
// NewServiceAccountStore returns a new ServiceAccountStore.
|
|
func NewServiceAccountStore(db *sqlx.DB) *ServiceAccountStore {
|
|
return &ServiceAccountStore{db}
|
|
}
|
|
|
|
// ServiceAccountStore implements a ServiceAccountStore backed by a relational
|
|
// database.
|
|
type ServiceAccountStore struct {
|
|
db *sqlx.DB
|
|
}
|
|
|
|
// Find finds the service account by id.
|
|
func (s *ServiceAccountStore) Find(ctx context.Context, id int64) (*types.ServiceAccount, error) {
|
|
dst := new(types.ServiceAccount)
|
|
if err := s.db.GetContext(ctx, dst, serviceAccountSelectID, id); err != nil {
|
|
return nil, processSQLErrorf(err, "Select by id query failed")
|
|
}
|
|
return dst, nil
|
|
}
|
|
|
|
// Create saves the service account.
|
|
func (s *ServiceAccountStore) Create(ctx context.Context, sa *types.ServiceAccount) error {
|
|
query, arg, err := s.db.BindNamed(serviceAccountInsert, sa)
|
|
if err != nil {
|
|
return processSQLErrorf(err, "Failed to bind service account object")
|
|
}
|
|
|
|
if err = s.db.QueryRowContext(ctx, query, arg...).Scan(&sa.ID); err != nil {
|
|
return processSQLErrorf(err, "Insert query failed")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Update updates the service account details.
|
|
func (s *ServiceAccountStore) Update(ctx context.Context, sa *types.ServiceAccount) error {
|
|
query, arg, err := s.db.BindNamed(serviceAccountUpdate, sa)
|
|
if err != nil {
|
|
return processSQLErrorf(err, "Failed to bind service account object")
|
|
}
|
|
|
|
if _, err = s.db.ExecContext(ctx, query, arg...); err != nil {
|
|
return processSQLErrorf(err, "Update query failed")
|
|
}
|
|
|
|
return err
|
|
}
|
|
|
|
// Delete deletes the service account.
|
|
func (s *ServiceAccountStore) Delete(ctx context.Context, id int64) error {
|
|
tx, err := s.db.BeginTx(ctx, nil)
|
|
if err != nil {
|
|
return processSQLErrorf(err, "Failed to start a new transaction")
|
|
}
|
|
defer func(tx *sql.Tx) {
|
|
_ = tx.Rollback()
|
|
}(tx)
|
|
// delete the service account
|
|
if _, err = tx.ExecContext(ctx, serviceAccountDelete, id); err != nil {
|
|
return processSQLErrorf(err, "The delete query failed")
|
|
}
|
|
return tx.Commit()
|
|
}
|
|
|
|
// List returns a list of service accounts for a specific parent.
|
|
func (s *ServiceAccountStore) List(ctx context.Context, parentType enum.ParentResourceType,
|
|
parentID int64) ([]*types.ServiceAccount, error) {
|
|
dst := []*types.ServiceAccount{}
|
|
|
|
err := s.db.SelectContext(ctx, &dst, serviceAccountSelectByParentTypeAndID, parentType, parentID)
|
|
if err != nil {
|
|
return nil, processSQLErrorf(err, "Failed executing default list query")
|
|
}
|
|
return dst, nil
|
|
}
|
|
|
|
// Count returns a count of service accounts for a specific parent.
|
|
func (s *ServiceAccountStore) Count(ctx context.Context,
|
|
parentType enum.ParentResourceType, parentID int64) (int64, error) {
|
|
var count int64
|
|
err := s.db.QueryRowContext(ctx, serviceAccountCountByParentTypeAndID, parentType, parentID).Scan(&count)
|
|
if err != nil {
|
|
return 0, processSQLErrorf(err, "Failed executing count query")
|
|
}
|
|
return count, nil
|
|
}
|
|
|
|
const serviceAccountCountByParentTypeAndID = `
|
|
SELECT count(*)
|
|
FROM principals
|
|
WHERE principal_type = "serviceaccount" and principal_sa_parentType = $1 and principal_sa_parentId = $2
|
|
`
|
|
|
|
const serviceAccountBase = `
|
|
SELECT
|
|
principal_id
|
|
,principal_name
|
|
,principal_externalId
|
|
,principal_blocked
|
|
,principal_salt
|
|
,principal_created
|
|
,principal_updated
|
|
,principal_sa_parentType
|
|
,principal_sa_parentId
|
|
FROM principals
|
|
`
|
|
|
|
const serviceAccountSelectByParentTypeAndID = serviceAccountBase + `
|
|
WHERE principal_type = "serviceaccount" AND principal_sa_parentType = $1 AND principal_sa_parentId = $2
|
|
ORDER BY principal_name ASC
|
|
`
|
|
|
|
const serviceAccountSelectID = serviceAccountBase + `
|
|
WHERE principal_type = "serviceaccount" AND principal_id = $1
|
|
`
|
|
|
|
const serviceAccountDelete = `
|
|
DELETE FROM principals
|
|
WHERE principal_type = "serviceaccount" AND principal_id = $1
|
|
`
|
|
|
|
const serviceAccountInsert = `
|
|
INSERT INTO principals (
|
|
principal_type
|
|
,principal_name
|
|
,principal_admin
|
|
,principal_externalId
|
|
,principal_blocked
|
|
,principal_salt
|
|
,principal_created
|
|
,principal_updated
|
|
,principal_sa_parentType
|
|
,principal_sa_parentId
|
|
) values (
|
|
"serviceaccount"
|
|
,:principal_name
|
|
,false
|
|
,:principal_externalId
|
|
,:principal_blocked
|
|
,:principal_salt
|
|
,:principal_created
|
|
,:principal_updated
|
|
,:principal_sa_parentType
|
|
,:principal_sa_parentId
|
|
) RETURNING principal_id
|
|
`
|
|
|
|
const serviceAccountUpdate = `
|
|
UPDATE principals
|
|
SET
|
|
principal_name = :principal_name
|
|
,:principal_externalId = :principal_externalId
|
|
,:principal_blocked = :principal_blocked
|
|
,:principal_salt = :principal_salt
|
|
,:principal_updated = :principal_updated
|
|
WHERE principal_type = "serviceaccount" AND principal_id = :principal_id
|
|
`
|