@@ -16,38 +16,51 @@ import (
1616	user_model "code.gitea.io/gitea/models/user" 
1717	"code.gitea.io/gitea/modules/secret" 
1818	"code.gitea.io/gitea/modules/setting" 
19- 	"code.gitea.io/gitea/modules/timeutil" 
2019	"code.gitea.io/gitea/modules/util" 
2120
2221	"golang.org/x/crypto/ssh" 
2322)
2423
2524// UserSSHKeypair represents an SSH keypair for repository mirroring 
2625type  UserSSHKeypair  struct  {
27- 	ID                   int64               `xorm:"pk autoincr"` 
28- 	OwnerID              int64               `xorm:"INDEX NOT NULL"` 
29- 	PrivateKeyEncrypted  string              `xorm:"TEXT NOT NULL"` 
30- 	PublicKey            string              `xorm:"TEXT NOT NULL"` 
31- 	Fingerprint          string              `xorm:"VARCHAR(255) UNIQUE NOT NULL"` 
32- 	CreatedUnix          timeutil.TimeStamp  `xorm:"created"` 
33- 	UpdatedUnix          timeutil.TimeStamp  `xorm:"updated"` 
26+ 	OwnerID              int64 
27+ 	PrivateKeyEncrypted  string 
28+ 	PublicKey            string 
29+ 	Fingerprint          string 
3430}
3531
36- func  init () {
37- 	db .RegisterModel (new (UserSSHKeypair ))
38- }
39- 
40- // GetUserSSHKeypairByOwner gets the most recent SSH keypair for the given owner 
32+ // GetUserSSHKeypairByOwner gets the SSH keypair for the given owner 
4133func  GetUserSSHKeypairByOwner (ctx  context.Context , ownerID  int64 ) (* UserSSHKeypair , error ) {
42- 	keypair  :=  & UserSSHKeypair {}
43- 	has , err  :=  db .GetEngine (ctx ).Where ("owner_id = ?" , ownerID ).
44- 		Desc ("created_unix" ).Get (keypair )
34+ 	settings , err  :=  user_model .GetSettings (ctx , ownerID , []string {
35+ 		user_model .UserSSHMirrorPrivPem ,
36+ 		user_model .UserSSHMirrorPubPem ,
37+ 		user_model .UserSSHMirrorFingerprint ,
38+ 	})
4539	if  err  !=  nil  {
4640		return  nil , err 
4741	}
48- 	if  ! has  {
42+ 	if  len ( settings )  ==   0  {
4943		return  nil , util .NewNotExistErrorf ("SSH keypair does not exist for owner %d" , ownerID )
5044	}
45+ 
46+ 	keypair  :=  & UserSSHKeypair {
47+ 		OwnerID : ownerID ,
48+ 	}
49+ 
50+ 	if  privSetting , exists  :=  settings [user_model .UserSSHMirrorPrivPem ]; exists  {
51+ 		keypair .PrivateKeyEncrypted  =  privSetting .SettingValue 
52+ 	}
53+ 	if  pubSetting , exists  :=  settings [user_model .UserSSHMirrorPubPem ]; exists  {
54+ 		keypair .PublicKey  =  pubSetting .SettingValue 
55+ 	}
56+ 	if  fpSetting , exists  :=  settings [user_model .UserSSHMirrorFingerprint ]; exists  {
57+ 		keypair .Fingerprint  =  fpSetting .SettingValue 
58+ 	}
59+ 
60+ 	if  keypair .PrivateKeyEncrypted  ==  ""  ||  keypair .PublicKey  ==  ""  ||  keypair .Fingerprint  ==  ""  {
61+ 		return  nil , util .NewNotExistErrorf ("SSH keypair incomplete for owner %d" , ownerID )
62+ 	}
63+ 
5164	return  keypair , nil 
5265}
5366
@@ -73,14 +86,30 @@ func CreateUserSSHKeypair(ctx context.Context, ownerID int64) (*UserSSHKeypair,
7386		return  nil , fmt .Errorf ("failed to encrypt private key: %w" , err )
7487	}
7588
89+ 	err  =  db .WithTx (ctx , func (ctx  context.Context ) error  {
90+ 		if  err  :=  user_model .SetUserSetting (ctx , ownerID , user_model .UserSSHMirrorPrivPem , privateKeyEncrypted ); err  !=  nil  {
91+ 			return  fmt .Errorf ("failed to save private key: %w" , err )
92+ 		}
93+ 		if  err  :=  user_model .SetUserSetting (ctx , ownerID , user_model .UserSSHMirrorPubPem , publicKeyStr ); err  !=  nil  {
94+ 			return  fmt .Errorf ("failed to save public key: %w" , err )
95+ 		}
96+ 		if  err  :=  user_model .SetUserSetting (ctx , ownerID , user_model .UserSSHMirrorFingerprint , fingerprintStr ); err  !=  nil  {
97+ 			return  fmt .Errorf ("failed to save fingerprint: %w" , err )
98+ 		}
99+ 		return  nil 
100+ 	})
101+ 	if  err  !=  nil  {
102+ 		return  nil , err 
103+ 	}
104+ 
76105	keypair  :=  & UserSSHKeypair {
77106		OwnerID :             ownerID ,
78107		PrivateKeyEncrypted : privateKeyEncrypted ,
79108		PublicKey :           publicKeyStr ,
80109		Fingerprint :         fingerprintStr ,
81110	}
82111
83- 	return  keypair , db . Insert ( ctx ,  keypair ) 
112+ 	return  keypair , nil 
84113}
85114
86115// GetDecryptedPrivateKey returns the decrypted private key 
@@ -115,12 +144,29 @@ func (k *UserSSHKeypair) GetPublicKeyWithComment(ctx context.Context) (string, e
115144
116145// DeleteUserSSHKeypair deletes an SSH keypair 
117146func  DeleteUserSSHKeypair (ctx  context.Context , ownerID  int64 ) error  {
118- 	_ , err  :=  db .GetEngine (ctx ).Where ("owner_id = ?" , ownerID ).Delete (& UserSSHKeypair {})
119- 	return  err 
147+ 	return  db .WithTx (ctx , func (ctx  context.Context ) error  {
148+ 		if  err  :=  user_model .DeleteUserSetting (ctx , ownerID , user_model .UserSSHMirrorPrivPem ); err  !=  nil  {
149+ 			return  err 
150+ 		}
151+ 		if  err  :=  user_model .DeleteUserSetting (ctx , ownerID , user_model .UserSSHMirrorPubPem ); err  !=  nil  {
152+ 			return  err 
153+ 		}
154+ 		return  user_model .DeleteUserSetting (ctx , ownerID , user_model .UserSSHMirrorFingerprint )
155+ 	})
120156}
121157
122158// RegenerateUserSSHKeypair regenerates an SSH keypair for the given owner 
123159func  RegenerateUserSSHKeypair (ctx  context.Context , ownerID  int64 ) (* UserSSHKeypair , error ) {
124- 	// TODO: This creates a new one old ones will be garbage collected later, as the user may accidentally regenerate 
125- 	return  CreateUserSSHKeypair (ctx , ownerID )
160+ 	var  keypair  * UserSSHKeypair 
161+ 	err  :=  db .WithTx (ctx , func (ctx  context.Context ) error  {
162+ 		_  =  DeleteUserSSHKeypair (ctx , ownerID )
163+ 
164+ 		newKeypair , err  :=  CreateUserSSHKeypair (ctx , ownerID )
165+ 		if  err  !=  nil  {
166+ 			return  err 
167+ 		}
168+ 		keypair  =  newKeypair 
169+ 		return  nil 
170+ 	})
171+ 	return  keypair , err 
126172}
0 commit comments