forked from NYANDEV/forgejo
#3281 fix x.Iterate returns nothing inside session scope with SQLite3
This commit is contained in:
parent
4d8b905541
commit
2d76de2574
6 changed files with 35 additions and 98 deletions
|
@ -5,12 +5,10 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"os"
|
||||
|
@ -24,6 +22,7 @@ import (
|
|||
"github.com/go-xorm/xorm"
|
||||
"golang.org/x/crypto/ssh"
|
||||
|
||||
"github.com/gogits/gogs/modules/base"
|
||||
"github.com/gogits/gogs/modules/log"
|
||||
"github.com/gogits/gogs/modules/process"
|
||||
"github.com/gogits/gogs/modules/setting"
|
||||
|
@ -457,96 +456,20 @@ func ListPublicKeys(uid int64) ([]*PublicKey, error) {
|
|||
return keys, x.Where("owner_id = ?", uid).Find(&keys)
|
||||
}
|
||||
|
||||
// rewriteAuthorizedKeys finds and deletes corresponding line in authorized_keys file.
|
||||
func rewriteAuthorizedKeys(key *PublicKey, p, tmpP string) error {
|
||||
fr, err := os.Open(p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fr.Close()
|
||||
|
||||
fw, err := os.OpenFile(tmpP, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0600)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fw.Close()
|
||||
|
||||
isFound := false
|
||||
keyword := fmt.Sprintf("key-%d", key.ID)
|
||||
buf := bufio.NewReader(fr)
|
||||
for {
|
||||
line, errRead := buf.ReadString('\n')
|
||||
line = strings.TrimSpace(line)
|
||||
|
||||
if errRead != nil {
|
||||
if errRead != io.EOF {
|
||||
return errRead
|
||||
}
|
||||
|
||||
// Reached end of file, if nothing to read then break,
|
||||
// otherwise handle the last line.
|
||||
if len(line) == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Found the line and copy rest of file.
|
||||
if !isFound && strings.Contains(line, keyword) && strings.Contains(line, key.Content) {
|
||||
isFound = true
|
||||
continue
|
||||
}
|
||||
// Still finding the line, copy the line that currently read.
|
||||
if _, err = fw.WriteString(line + "\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if errRead == io.EOF {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !isFound {
|
||||
log.Warn("SSH key %d not found in authorized_keys file for deletion", key.ID)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdatePublicKey updates given public key.
|
||||
func UpdatePublicKey(key *PublicKey) error {
|
||||
_, err := x.Id(key.ID).AllCols().Update(key)
|
||||
return err
|
||||
}
|
||||
|
||||
func deletePublicKey(e *xorm.Session, keyID int64) error {
|
||||
sshOpLocker.Lock()
|
||||
defer sshOpLocker.Unlock()
|
||||
|
||||
key := &PublicKey{ID: keyID}
|
||||
has, err := e.Get(key)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !has {
|
||||
// deletePublicKeys does the actual key deletion but does not update authorized_keys file.
|
||||
func deletePublicKeys(e *xorm.Session, keyIDs ...int64) error {
|
||||
if len(keyIDs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if _, err = e.Id(key.ID).Delete(new(PublicKey)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Don't need to rewrite this file if builtin SSH server is enabled.
|
||||
if setting.SSH.StartBuiltinServer {
|
||||
return nil
|
||||
}
|
||||
|
||||
fpath := filepath.Join(setting.SSH.RootPath, "authorized_keys")
|
||||
tmpPath := fpath + ".tmp"
|
||||
if err = rewriteAuthorizedKeys(key, fpath, tmpPath); err != nil {
|
||||
return err
|
||||
} else if err = os.Remove(fpath); err != nil {
|
||||
return err
|
||||
}
|
||||
return os.Rename(tmpPath, fpath)
|
||||
_, err := e.In("id", strings.Join(base.Int64sToStrings(keyIDs), ",")).Delete(new(PublicKey))
|
||||
return err
|
||||
}
|
||||
|
||||
// DeletePublicKey deletes SSH key information both in database and authorized_keys file.
|
||||
|
@ -570,14 +493,20 @@ func DeletePublicKey(doer *User, id int64) (err error) {
|
|||
return err
|
||||
}
|
||||
|
||||
if err = deletePublicKey(sess, id); err != nil {
|
||||
if err = deletePublicKeys(sess, id); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return sess.Commit()
|
||||
if err = sess.Commit(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return RewriteAllPublicKeys()
|
||||
}
|
||||
|
||||
// RewriteAllPublicKeys removes any authorized key and rewrite all keys from database again.
|
||||
// Note: x.Iterate does not get latest data after insert/delete, so we have to call this function
|
||||
// outsite any session scope independently.
|
||||
func RewriteAllPublicKeys() error {
|
||||
sshOpLocker.Lock()
|
||||
defer sshOpLocker.Unlock()
|
||||
|
@ -814,7 +743,7 @@ func DeleteDeployKey(doer *User, id int64) error {
|
|||
if err != nil {
|
||||
return err
|
||||
} else if !has {
|
||||
if err = deletePublicKey(sess, key.KeyID); err != nil {
|
||||
if err = deletePublicKeys(sess, key.KeyID); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue