2021-07-24 13:16:34 +03:00
// Copyright 2021 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
2021-12-10 11:14:24 +03:00
package asymkey
2021-07-24 13:16:34 +03:00
import (
"errors"
"fmt"
"strings"
2021-09-19 14:49:59 +03:00
"code.gitea.io/gitea/models/db"
2021-11-28 14:58:28 +03:00
"code.gitea.io/gitea/models/perm"
2021-11-11 10:03:30 +03:00
user_model "code.gitea.io/gitea/models/user"
2021-07-24 13:16:34 +03:00
"code.gitea.io/gitea/modules/setting"
)
// __________ .__ .__ .__
// \______ _______|__| ____ ____ |_____________ | | ______
// | ___\_ __ | |/ \_/ ___\| \____ \__ \ | | / ___/
// | | | | \| | | \ \___| | |_> / __ \| |__\___ \
// |____| |__| |__|___| /\___ |__| __(____ |____/____ >
// \/ \/ |__| \/ \/
//
// This file contains functions related to principals
// AddPrincipalKey adds new principal to database and authorized_principals file.
2022-01-02 16:12:35 +03:00
func AddPrincipalKey ( ownerID int64 , content string , authSourceID int64 ) ( * PublicKey , error ) {
2021-11-21 18:41:00 +03:00
ctx , committer , err := db . TxContext ( )
if err != nil {
2021-07-24 13:16:34 +03:00
return nil , err
}
2021-11-21 18:41:00 +03:00
defer committer . Close ( )
2021-07-24 13:16:34 +03:00
// Principals cannot be duplicated.
2022-05-20 17:08:52 +03:00
has , err := db . GetEngine ( ctx ) .
2021-07-24 13:16:34 +03:00
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 ,
2021-11-28 14:58:28 +03:00
Mode : perm . AccessModeWrite ,
2021-07-24 13:16:34 +03:00
Type : KeyTypePrincipal ,
2022-01-02 16:12:35 +03:00
LoginSourceID : authSourceID ,
2021-07-24 13:16:34 +03:00
}
2022-05-20 17:08:52 +03:00
if err = db . Insert ( ctx , key ) ; err != nil {
2021-07-24 13:16:34 +03:00
return nil , fmt . Errorf ( "addKey: %v" , err )
}
2021-11-21 18:41:00 +03:00
if err = committer . Commit ( ) ; err != nil {
2021-07-24 13:16:34 +03:00
return nil , err
}
2021-11-21 18:41:00 +03:00
committer . Close ( )
2021-07-24 13:16:34 +03:00
2022-05-20 17:08:52 +03:00
return key , RewriteAllPrincipalKeys ( db . DefaultContext )
2021-07-24 13:16:34 +03:00
}
// CheckPrincipalKeyString strips spaces and returns an error if the given principal contains newlines
2021-11-24 12:49:20 +03:00
func CheckPrincipalKeyString ( user * user_model . User , content string ) ( _ string , err error ) {
2021-07-24 13:16:34 +03:00
if setting . SSH . Disabled {
2021-12-10 11:14:24 +03:00
return "" , db . ErrSSHDisabled { }
2021-07-24 13:16:34 +03:00
}
content = strings . TrimSpace ( content )
if strings . ContainsAny ( content , "\r\n" ) {
return "" , errors . New ( "only a single line with a single principal please" )
}
// check all the allowed principals, email, username or anything
// if any matches, return ok
for _ , v := range setting . SSH . AuthorizedPrincipalsAllow {
switch v {
case "anything" :
return content , nil
case "email" :
2021-11-11 10:03:30 +03:00
emails , err := user_model . GetEmailAddresses ( user . ID )
2021-07-24 13:16:34 +03:00
if err != nil {
return "" , err
}
for _ , email := range emails {
if ! email . IsActivated {
continue
}
if content == email . Email {
return content , nil
}
}
case "username" :
if content == user . Name {
return content , nil
}
}
}
return "" , fmt . Errorf ( "didn't match allowed principals: %s" , setting . SSH . AuthorizedPrincipalsAllow )
}
// ListPrincipalKeys returns a list of principals belongs to given user.
2021-09-24 14:32:56 +03:00
func ListPrincipalKeys ( uid int64 , listOptions db . ListOptions ) ( [ ] * PublicKey , error ) {
2021-09-23 18:45:36 +03:00
sess := db . GetEngine ( db . DefaultContext ) . Where ( "owner_id = ? AND type = ?" , uid , KeyTypePrincipal )
2021-07-24 13:16:34 +03:00
if listOptions . Page != 0 {
2021-09-24 14:32:56 +03:00
sess = db . SetSessionPagination ( sess , & listOptions )
2021-07-24 13:16:34 +03:00
keys := make ( [ ] * PublicKey , 0 , listOptions . PageSize )
return keys , sess . Find ( & keys )
}
keys := make ( [ ] * PublicKey , 0 , 5 )
return keys , sess . Find ( & keys )
}