Some checks failed
cache-seeder / prune (push) Has been skipped
cache-seeder / frontend (push) Failing after 3s
cache-seeder / python (push) Failing after 3s
cache-seeder / gobuild (push) Failing after 4s
cache-seeder / lint (bindata, lint-backend) (push) Failing after 3s
giteabot backport / giteabot (push) Has been skipped
giteabot / giteabot (push) Has been skipped
cache-prune / prune (push) Has been skipped
release-nightly-snapcraft / build-and-publish (ubuntu-24.04) (push) Has been cancelled
release-nightly-snapcraft / build-and-publish (ubuntu-24.04-arm) (push) Has been cancelled
release-nightly / nightly-binary (push) Has been cancelled
release-nightly / nightly-container (push) Has been cancelled
cron-renovate / cron-renovate (push) Has been skipped
76 lines
2.6 KiB
Go
76 lines
2.6 KiB
Go
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package deploykey
|
|
|
|
import (
|
|
"context"
|
|
|
|
"gitea.dev/models/asymkey"
|
|
"gitea.dev/models/db"
|
|
"gitea.dev/models/perm"
|
|
"gitea.dev/modules/util"
|
|
|
|
"xorm.io/builder"
|
|
)
|
|
|
|
// AddDeployKeySSH add new deploy-key to database and authorized_keys file.
|
|
func AddDeployKeySSH(ctx context.Context, repoID int64, name, content string, accessMode perm.AccessMode) (*DeployKey, error) {
|
|
if accessMode != perm.AccessModeRead && accessMode != perm.AccessModeWrite {
|
|
return nil, util.NewInvalidArgumentErrorf("invalid access mode")
|
|
}
|
|
return db.WithTx2(ctx, func(ctx context.Context) (*DeployKey, error) {
|
|
pkey, err := asymkey.FindOrAddDeployPublicKey(ctx, content)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if has, err := db.Exist[DeployKey](ctx, builder.Eq{"repo_id": repoID, "key_id": pkey.ID}); err != nil {
|
|
return nil, err
|
|
} else if has {
|
|
return nil, ErrDeployKeyAlreadyExist{pkey.ID, repoID}
|
|
}
|
|
if err := checkDeployKeyName(ctx, repoID, name); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
key := &DeployKey{KeyID: pkey.ID, RepoID: repoID, KeyType: KeyTypeSSH, Name: name, Fingerprint: pkey.Fingerprint, Mode: accessMode}
|
|
return key, db.Insert(ctx, key)
|
|
})
|
|
}
|
|
|
|
func (key *DeployKey) LoadPublicKey(ctx context.Context) (err error) {
|
|
if key.PublicKey != nil {
|
|
return nil
|
|
}
|
|
key.PublicKey, err = asymkey.GetPublicKeyByID(ctx, key.KeyID)
|
|
return err
|
|
}
|
|
|
|
// GetDeployKeyByID returns deploy-key by given ID.
|
|
func GetDeployKeyByID(ctx context.Context, repoID, deployKeyID int64) (*DeployKey, error) {
|
|
key, exist, err := db.Get[DeployKey](ctx, builder.Eq{"id": deployKeyID, "repo_id": repoID})
|
|
if err != nil {
|
|
return nil, err
|
|
} else if !exist {
|
|
return nil, ErrDeployKeyNotExist{deployKeyID, 0, repoID}
|
|
}
|
|
return key, nil
|
|
}
|
|
|
|
// GetDeployKeyByRepoPublicKey returns deploy-key by given public key ID and repository ID.
|
|
func GetDeployKeyByRepoPublicKey(ctx context.Context, repoID, publicKeyID int64) (*DeployKey, error) {
|
|
// the type is part of the condition because every token row carries key id 0
|
|
key, exist, err := db.Get[DeployKey](ctx, builder.Eq{"key_id": publicKeyID, "repo_id": repoID, "key_type": KeyTypeSSH})
|
|
if err != nil {
|
|
return nil, err
|
|
} else if !exist {
|
|
return nil, ErrDeployKeyNotExist{0, publicKeyID, repoID}
|
|
}
|
|
return key, nil
|
|
}
|
|
|
|
// IsDeployKeyExistByPublicKeyID return true if there is at least one deploy-key with the key id
|
|
func IsDeployKeyExistByPublicKeyID(ctx context.Context, keyID int64) (bool, error) {
|
|
return db.Exist[DeployKey](ctx, builder.Eq{"key_id": keyID, "key_type": KeyTypeSSH})
|
|
}
|