2021-07-24 11:16:34 +01: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.
package models
import (
"errors"
"fmt"
"strings"
2021-09-19 19:49:59 +08:00
"code.gitea.io/gitea/models/db"
2021-11-11 15:03:30 +08:00
user_model "code.gitea.io/gitea/models/user"
2021-07-24 11:16:34 +01:00
"code.gitea.io/gitea/modules/setting"
)
// __________ .__ .__ .__
// \______ _______|__| ____ ____ |_____________ | | ______
// | ___\_ __ | |/ \_/ ___\| \____ \__ \ | | / ___/
// | | | | \| | | \ \___| | |_> / __ \| |__\___ \
// |____| |__| |__|___| /\___ |__| __(____ |____/____ >
// \/ \/ |__| \/ \/
//
// This file contains functions related to principals
// AddPrincipalKey adds new principal to database and authorized_principals file.
func AddPrincipalKey ( ownerID int64 , content string , loginSourceID int64 ) ( * PublicKey , error ) {
2021-11-21 23:41:00 +08:00
ctx , committer , err := db . TxContext ( )
if err != nil {
2021-07-24 11:16:34 +01:00
return nil , err
}
2021-11-21 23:41:00 +08:00
defer committer . Close ( )
sess := db . GetEngine ( ctx )
2021-07-24 11:16:34 +01:00
// Principals cannot be duplicated.
has , err := sess .
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 : AccessModeWrite ,
Type : KeyTypePrincipal ,
LoginSourceID : loginSourceID ,
}
if err = addPrincipalKey ( sess , key ) ; err != nil {
return nil , fmt . Errorf ( "addKey: %v" , err )
}
2021-11-21 23:41:00 +08:00
if err = committer . Commit ( ) ; err != nil {
2021-07-24 11:16:34 +01:00
return nil , err
}
2021-11-21 23:41:00 +08:00
committer . Close ( )
2021-07-24 11:16:34 +01:00
return key , RewriteAllPrincipalKeys ( )
}
2021-09-19 19:49:59 +08:00
func addPrincipalKey ( e db . Engine , key * PublicKey ) ( err error ) {
2021-07-24 11:16:34 +01:00
// Save Key representing a principal.
if _ , err = e . Insert ( key ) ; err != nil {
return err
}
return nil
}
// CheckPrincipalKeyString strips spaces and returns an error if the given principal contains newlines
func CheckPrincipalKeyString ( user * User , content string ) ( _ string , err error ) {
if setting . SSH . Disabled {
return "" , ErrSSHDisabled { }
}
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 15:03:30 +08:00
emails , err := user_model . GetEmailAddresses ( user . ID )
2021-07-24 11:16:34 +01: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 19:32:56 +08:00
func ListPrincipalKeys ( uid int64 , listOptions db . ListOptions ) ( [ ] * PublicKey , error ) {
2021-09-23 16:45:36 +01:00
sess := db . GetEngine ( db . DefaultContext ) . Where ( "owner_id = ? AND type = ?" , uid , KeyTypePrincipal )
2021-07-24 11:16:34 +01:00
if listOptions . Page != 0 {
2021-09-24 19:32:56 +08:00
sess = db . SetSessionPagination ( sess , & listOptions )
2021-07-24 11:16:34 +01:00
keys := make ( [ ] * PublicKey , 0 , listOptions . PageSize )
return keys , sess . Find ( & keys )
}
keys := make ( [ ] * PublicKey , 0 , 5 )
return keys , sess . Find ( & keys )
}