mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 19:45:25 +01:00 
			
		
		
		
	#3281 fix x.Iterate returns nothing inside session scope with SQLite3
This commit is contained in:
		
							parent
							
								
									4d8b905541
								
							
						
					
					
						commit
						2d76de2574
					
				| @ -3,7 +3,7 @@ Gogs - Go Git Service [ |  | ||||||
| 
 | 
 | ||||||
| ##### Current tip version: 0.9.56 (see [Releases](https://github.com/gogits/gogs/releases) for binary versions) | ##### Current tip version: 0.9.57 (see [Releases](https://github.com/gogits/gogs/releases) for binary versions) | ||||||
| 
 | 
 | ||||||
| | Web | UI  | Preview  | | | Web | UI  | Preview  | | ||||||
| |:-------------:|:-------:|:-------:| | |:-------------:|:-------:|:-------:| | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								gogs.go
									
									
									
									
									
								
							| @ -17,7 +17,7 @@ import ( | |||||||
| 	"github.com/gogits/gogs/modules/setting" | 	"github.com/gogits/gogs/modules/setting" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const APP_VER = "0.9.56.0726" | const APP_VER = "0.9.57.0726" | ||||||
| 
 | 
 | ||||||
| func init() { | func init() { | ||||||
| 	runtime.GOMAXPROCS(runtime.NumCPU()) | 	runtime.GOMAXPROCS(runtime.NumCPU()) | ||||||
|  | |||||||
| @ -27,9 +27,10 @@ type Engine interface { | |||||||
| 	Exec(string, ...interface{}) (sql.Result, error) | 	Exec(string, ...interface{}) (sql.Result, error) | ||||||
| 	Find(interface{}, ...interface{}) error | 	Find(interface{}, ...interface{}) error | ||||||
| 	Get(interface{}) (bool, error) | 	Get(interface{}) (bool, error) | ||||||
|  | 	Id(interface{}) *xorm.Session | ||||||
| 	Insert(...interface{}) (int64, error) | 	Insert(...interface{}) (int64, error) | ||||||
| 	InsertOne(interface{}) (int64, error) | 	InsertOne(interface{}) (int64, error) | ||||||
| 	Id(interface{}) *xorm.Session | 	Iterate(interface{}, xorm.IterFunc) error | ||||||
| 	Sql(string, ...interface{}) *xorm.Session | 	Sql(string, ...interface{}) *xorm.Session | ||||||
| 	Where(string, ...interface{}) *xorm.Session | 	Where(string, ...interface{}) *xorm.Session | ||||||
| } | } | ||||||
|  | |||||||
| @ -5,12 +5,10 @@ | |||||||
| package models | package models | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"bufio" |  | ||||||
| 	"encoding/base64" | 	"encoding/base64" | ||||||
| 	"encoding/binary" | 	"encoding/binary" | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"io" |  | ||||||
| 	"io/ioutil" | 	"io/ioutil" | ||||||
| 	"math/big" | 	"math/big" | ||||||
| 	"os" | 	"os" | ||||||
| @ -24,6 +22,7 @@ import ( | |||||||
| 	"github.com/go-xorm/xorm" | 	"github.com/go-xorm/xorm" | ||||||
| 	"golang.org/x/crypto/ssh" | 	"golang.org/x/crypto/ssh" | ||||||
| 
 | 
 | ||||||
|  | 	"github.com/gogits/gogs/modules/base" | ||||||
| 	"github.com/gogits/gogs/modules/log" | 	"github.com/gogits/gogs/modules/log" | ||||||
| 	"github.com/gogits/gogs/modules/process" | 	"github.com/gogits/gogs/modules/process" | ||||||
| 	"github.com/gogits/gogs/modules/setting" | 	"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) | 	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. | // UpdatePublicKey updates given public key. | ||||||
| func UpdatePublicKey(key *PublicKey) error { | func UpdatePublicKey(key *PublicKey) error { | ||||||
| 	_, err := x.Id(key.ID).AllCols().Update(key) | 	_, err := x.Id(key.ID).AllCols().Update(key) | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func deletePublicKey(e *xorm.Session, keyID int64) error { | // deletePublicKeys does the actual key deletion but does not update authorized_keys file. | ||||||
| 	sshOpLocker.Lock() | func deletePublicKeys(e *xorm.Session, keyIDs ...int64) error { | ||||||
| 	defer sshOpLocker.Unlock() | 	if len(keyIDs) == 0 { | ||||||
| 
 |  | ||||||
| 	key := &PublicKey{ID: keyID} |  | ||||||
| 	has, err := e.Get(key) |  | ||||||
| 	if err != nil { |  | ||||||
| 		return err |  | ||||||
| 	} else if !has { |  | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if _, err = e.Id(key.ID).Delete(new(PublicKey)); err != nil { | 	_, err := e.In("id", strings.Join(base.Int64sToStrings(keyIDs), ",")).Delete(new(PublicKey)) | ||||||
| 		return err | 	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) |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // DeletePublicKey deletes SSH key information both in database and authorized_keys file. | // 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 | 		return err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if err = deletePublicKey(sess, id); err != nil { | 	if err = deletePublicKeys(sess, id); err != nil { | ||||||
| 		return err | 		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. | // 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 { | func RewriteAllPublicKeys() error { | ||||||
| 	sshOpLocker.Lock() | 	sshOpLocker.Lock() | ||||||
| 	defer sshOpLocker.Unlock() | 	defer sshOpLocker.Unlock() | ||||||
| @ -814,7 +743,7 @@ func DeleteDeployKey(doer *User, id int64) error { | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} else if !has { | 	} else if !has { | ||||||
| 		if err = deletePublicKey(sess, key.KeyID); err != nil { | 		if err = deletePublicKeys(sess, key.KeyID); err != nil { | ||||||
| 			return err | 			return err | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -768,10 +768,13 @@ func deleteUser(e *xorm.Session, u *User) error { | |||||||
| 	if err = e.Find(&keys, &PublicKey{OwnerID: u.ID}); err != nil { | 	if err = e.Find(&keys, &PublicKey{OwnerID: u.ID}); err != nil { | ||||||
| 		return fmt.Errorf("get all public keys: %v", err) | 		return fmt.Errorf("get all public keys: %v", err) | ||||||
| 	} | 	} | ||||||
| 	for _, key := range keys { | 
 | ||||||
| 		if err = deletePublicKey(e, key.ID); err != nil { | 	keyIDs := make([]int64, len(keys)) | ||||||
| 			return fmt.Errorf("deletePublicKey: %v", err) | 	for i := range keys { | ||||||
| 		} | 		keyIDs[i] = keys[i].ID | ||||||
|  | 	} | ||||||
|  | 	if err = deletePublicKeys(e, keyIDs...); err != nil { | ||||||
|  | 		return fmt.Errorf("deletePublicKeys: %v", err) | ||||||
| 	} | 	} | ||||||
| 	// ***** END: PublicKey ***** | 	// ***** END: PublicKey ***** | ||||||
| 
 | 
 | ||||||
| @ -788,7 +791,6 @@ func deleteUser(e *xorm.Session, u *User) error { | |||||||
| 	// Note: There are something just cannot be roll back, | 	// Note: There are something just cannot be roll back, | ||||||
| 	//	so just keep error logs of those operations. | 	//	so just keep error logs of those operations. | ||||||
| 
 | 
 | ||||||
| 	RewriteAllPublicKeys() |  | ||||||
| 	os.RemoveAll(UserPath(u.Name)) | 	os.RemoveAll(UserPath(u.Name)) | ||||||
| 	os.Remove(u.CustomAvatarPath()) | 	os.Remove(u.CustomAvatarPath()) | ||||||
| 
 | 
 | ||||||
| @ -809,15 +811,20 @@ func DeleteUser(u *User) (err error) { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return sess.Commit() | 	if err = sess.Commit(); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return RewriteAllPublicKeys() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // DeleteInactivateUsers deletes all inactivate users and email addresses. | // DeleteInactivateUsers deletes all inactivate users and email addresses. | ||||||
| func DeleteInactivateUsers() (err error) { | func DeleteInactivateUsers() (err error) { | ||||||
| 	users := make([]*User, 0, 10) | 	users := make([]*User, 0, 10) | ||||||
| 	if err = x.Where("is_active=?", false).Find(&users); err != nil { | 	if err = x.Where("is_active = ?", false).Find(&users); err != nil { | ||||||
| 		return fmt.Errorf("get all inactive users: %v", err) | 		return fmt.Errorf("get all inactive users: %v", err) | ||||||
| 	} | 	} | ||||||
|  | 	// FIXME: should only update authorized_keys file once after all deletions. | ||||||
| 	for _, u := range users { | 	for _, u := range users { | ||||||
| 		if err = DeleteUser(u); err != nil { | 		if err = DeleteUser(u); err != nil { | ||||||
| 			// Ignore users that were set inactive by admin. | 			// Ignore users that were set inactive by admin. | ||||||
| @ -828,7 +835,7 @@ func DeleteInactivateUsers() (err error) { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	_, err = x.Where("is_activated=?", false).Delete(new(EmailAddress)) | 	_, err = x.Where("is_activated = ?", false).Delete(new(EmailAddress)) | ||||||
| 	return err | 	return err | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1 +1 @@ | |||||||
| 0.9.56.0726 | 0.9.57.0726 | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user