summaryrefslogtreecommitdiffstats
path: root/models
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2024-03-04 16:57:39 +0800
committerGitHub <noreply@github.com>2024-03-04 08:57:39 +0000
commite2277d07ca5112a797f8c86f825060027ff1c2da (patch)
tree77dc35194eaf4afb0f94265b46ec3c0faf312826 /models
parentc337ff0ec70618ef2ead7850f90ab2a8458db192 (diff)
downloadgitea-e2277d07ca5112a797f8c86f825060027ff1c2da.tar.gz
gitea-e2277d07ca5112a797f8c86f825060027ff1c2da.zip
Move some asymkey functions to service layer (#28894)
After the moving, all models will not depend on `util.Rename` so that I can do next step refactoring.
Diffstat (limited to 'models')
-rw-r--r--models/asymkey/ssh_key_authorized_keys.go66
-rw-r--r--models/asymkey/ssh_key_authorized_principals.go134
-rw-r--r--models/asymkey/ssh_key_principals.go40
3 files changed, 6 insertions, 234 deletions
diff --git a/models/asymkey/ssh_key_authorized_keys.go b/models/asymkey/ssh_key_authorized_keys.go
index 267ab252c8..9279db2020 100644
--- a/models/asymkey/ssh_key_authorized_keys.go
+++ b/models/asymkey/ssh_key_authorized_keys.go
@@ -12,7 +12,6 @@ import (
"path/filepath"
"strings"
"sync"
- "time"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/log"
@@ -44,6 +43,12 @@ const (
var sshOpLocker sync.Mutex
+func WithSSHOpLocker(f func() error) error {
+ sshOpLocker.Lock()
+ defer sshOpLocker.Unlock()
+ return f()
+}
+
// AuthorizedStringForKey creates the authorized keys string appropriate for the provided key
func AuthorizedStringForKey(key *PublicKey) string {
sb := &strings.Builder{}
@@ -114,65 +119,6 @@ func appendAuthorizedKeysToFile(keys ...*PublicKey) error {
return nil
}
-// RewriteAllPublicKeys removes any authorized key and rewrite all keys from database again.
-// Note: db.GetEngine(ctx).Iterate does not get latest data after insert/delete, so we have to call this function
-// outside any session scope independently.
-func RewriteAllPublicKeys(ctx context.Context) error {
- // Don't rewrite key if internal server
- if setting.SSH.StartBuiltinServer || !setting.SSH.CreateAuthorizedKeysFile {
- return nil
- }
-
- sshOpLocker.Lock()
- defer sshOpLocker.Unlock()
-
- if setting.SSH.RootPath != "" {
- // First of ensure that the RootPath is present, and if not make it with 0700 permissions
- // This of course doesn't guarantee that this is the right directory for authorized_keys
- // but at least if it's supposed to be this directory and it doesn't exist and we're the
- // right user it will at least be created properly.
- err := os.MkdirAll(setting.SSH.RootPath, 0o700)
- if err != nil {
- log.Error("Unable to MkdirAll(%s): %v", setting.SSH.RootPath, err)
- return err
- }
- }
-
- fPath := filepath.Join(setting.SSH.RootPath, "authorized_keys")
- tmpPath := fPath + ".tmp"
- t, err := os.OpenFile(tmpPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o600)
- if err != nil {
- return err
- }
- defer func() {
- t.Close()
- if err := util.Remove(tmpPath); err != nil {
- log.Warn("Unable to remove temporary authorized keys file: %s: Error: %v", tmpPath, err)
- }
- }()
-
- if setting.SSH.AuthorizedKeysBackup {
- isExist, err := util.IsExist(fPath)
- if err != nil {
- log.Error("Unable to check if %s exists. Error: %v", fPath, err)
- return err
- }
- if isExist {
- bakPath := fmt.Sprintf("%s_%d.gitea_bak", fPath, time.Now().Unix())
- if err = util.CopyFile(fPath, bakPath); err != nil {
- return err
- }
- }
- }
-
- if err := RegeneratePublicKeys(ctx, t); err != nil {
- return err
- }
-
- t.Close()
- return util.Rename(tmpPath, fPath)
-}
-
// RegeneratePublicKeys regenerates the authorized_keys file
func RegeneratePublicKeys(ctx context.Context, t io.StringWriter) error {
if err := db.GetEngine(ctx).Where("type != ?", KeyTypePrincipal).Iterate(new(PublicKey), func(idx int, bean any) (err error) {
diff --git a/models/asymkey/ssh_key_authorized_principals.go b/models/asymkey/ssh_key_authorized_principals.go
deleted file mode 100644
index 107d70c766..0000000000
--- a/models/asymkey/ssh_key_authorized_principals.go
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright 2021 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package asymkey
-
-import (
- "bufio"
- "context"
- "fmt"
- "io"
- "os"
- "path/filepath"
- "strings"
- "time"
-
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
-)
-
-// _____ __ .__ .__ .___
-// / _ \ __ ___/ |_| |__ ___________|__|_______ ____ __| _/
-// / /_\ \| | \ __\ | \ / _ \_ __ \ \___ // __ \ / __ |
-// / | \ | /| | | Y ( <_> ) | \/ |/ /\ ___// /_/ |
-// \____|__ /____/ |__| |___| /\____/|__| |__/_____ \\___ >____ |
-// \/ \/ \/ \/ \/
-// __________ .__ .__ .__
-// \______ _______|__| ____ ____ |_____________ | | ______
-// | ___\_ __ | |/ \_/ ___\| \____ \__ \ | | / ___/
-// | | | | \| | | \ \___| | |_> / __ \| |__\___ \
-// |____| |__| |__|___| /\___ |__| __(____ |____/____ >
-// \/ \/ |__| \/ \/
-//
-// This file contains functions for creating authorized_principals files
-//
-// There is a dependence on the database within RewriteAllPrincipalKeys & RegeneratePrincipalKeys
-// The sshOpLocker is used from ssh_key_authorized_keys.go
-
-const authorizedPrincipalsFile = "authorized_principals"
-
-// RewriteAllPrincipalKeys removes any authorized principal and rewrite all keys from database again.
-// Note: db.GetEngine(ctx).Iterate does not get latest data after insert/delete, so we have to call this function
-// outside any session scope independently.
-func RewriteAllPrincipalKeys(ctx context.Context) error {
- // Don't rewrite key if internal server
- if setting.SSH.StartBuiltinServer || !setting.SSH.CreateAuthorizedPrincipalsFile {
- return nil
- }
-
- sshOpLocker.Lock()
- defer sshOpLocker.Unlock()
-
- if setting.SSH.RootPath != "" {
- // First of ensure that the RootPath is present, and if not make it with 0700 permissions
- // This of course doesn't guarantee that this is the right directory for authorized_keys
- // but at least if it's supposed to be this directory and it doesn't exist and we're the
- // right user it will at least be created properly.
- err := os.MkdirAll(setting.SSH.RootPath, 0o700)
- if err != nil {
- log.Error("Unable to MkdirAll(%s): %v", setting.SSH.RootPath, err)
- return err
- }
- }
-
- fPath := filepath.Join(setting.SSH.RootPath, authorizedPrincipalsFile)
- tmpPath := fPath + ".tmp"
- t, err := os.OpenFile(tmpPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o600)
- if err != nil {
- return err
- }
- defer func() {
- t.Close()
- os.Remove(tmpPath)
- }()
-
- if setting.SSH.AuthorizedPrincipalsBackup {
- isExist, err := util.IsExist(fPath)
- if err != nil {
- log.Error("Unable to check if %s exists. Error: %v", fPath, err)
- return err
- }
- if isExist {
- bakPath := fmt.Sprintf("%s_%d.gitea_bak", fPath, time.Now().Unix())
- if err = util.CopyFile(fPath, bakPath); err != nil {
- return err
- }
- }
- }
-
- if err := regeneratePrincipalKeys(ctx, t); err != nil {
- return err
- }
-
- t.Close()
- return util.Rename(tmpPath, fPath)
-}
-
-func regeneratePrincipalKeys(ctx context.Context, t io.StringWriter) error {
- if err := db.GetEngine(ctx).Where("type = ?", KeyTypePrincipal).Iterate(new(PublicKey), func(idx int, bean any) (err error) {
- _, err = t.WriteString((bean.(*PublicKey)).AuthorizedString())
- return err
- }); err != nil {
- return err
- }
-
- fPath := filepath.Join(setting.SSH.RootPath, authorizedPrincipalsFile)
- isExist, err := util.IsExist(fPath)
- if err != nil {
- log.Error("Unable to check if %s exists. Error: %v", fPath, err)
- return err
- }
- if isExist {
- f, err := os.Open(fPath)
- if err != nil {
- return err
- }
- scanner := bufio.NewScanner(f)
- for scanner.Scan() {
- line := scanner.Text()
- if strings.HasPrefix(line, tplCommentPrefix) {
- scanner.Scan()
- continue
- }
- _, err = t.WriteString(line + "\n")
- if err != nil {
- f.Close()
- return err
- }
- }
- f.Close()
- }
- return nil
-}
diff --git a/models/asymkey/ssh_key_principals.go b/models/asymkey/ssh_key_principals.go
index 4e7dee2c91..e8b97d306e 100644
--- a/models/asymkey/ssh_key_principals.go
+++ b/models/asymkey/ssh_key_principals.go
@@ -9,51 +9,11 @@ import (
"strings"
"code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/perm"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
)
-// AddPrincipalKey adds new principal to database and authorized_principals file.
-func AddPrincipalKey(ctx context.Context, ownerID int64, content string, authSourceID int64) (*PublicKey, error) {
- dbCtx, committer, err := db.TxContext(ctx)
- if err != nil {
- return nil, err
- }
- defer committer.Close()
-
- // Principals cannot be duplicated.
- has, err := db.GetEngine(dbCtx).
- Where("content = ? AND type = ?", content, KeyTypePrincipal).
- Get(new(PublicKey))
- if err != nil {
- return nil, err
- } else if has {
- return nil, ErrKeyAlreadyExist{0, "", content}
- }
-
- key := &PublicKey{
- OwnerID: ownerID,
- Name: content,
- Content: content,
- Mode: perm.AccessModeWrite,
- Type: KeyTypePrincipal,
- LoginSourceID: authSourceID,
- }
- if err = db.Insert(dbCtx, key); err != nil {
- return nil, fmt.Errorf("addKey: %w", err)
- }
-
- if err = committer.Commit(); err != nil {
- return nil, err
- }
-
- committer.Close()
-
- return key, RewriteAllPrincipalKeys(ctx)
-}
-
// CheckPrincipalKeyString strips spaces and returns an error if the given principal contains newlines
func CheckPrincipalKeyString(ctx context.Context, user *user_model.User, content string) (_ string, err error) {
if setting.SSH.Disabled {