Only check at least one email gpg key (#2266)

* Only require one email (possibly not yet validated)

* Update message error and check validation of commit

* Add integrations tests

* Complete integration for import

* Add pre-check/optimization

* Add some test (not finished)

* Finish

* Fix fixtures

* Fix typo

* Don't guess key ID
This commit is contained in:
Antoine GIRARD 2017-09-05 15:45:18 +02:00 committed by Lunny Xiao
parent 5f4210a9b0
commit 7c417bbb0d
36 changed files with 852 additions and 25 deletions

View file

@ -4,9 +4,7 @@
package models
import (
"fmt"
)
import "fmt"
// ErrNameReserved represents a "reserved name" error.
type ErrNameReserved struct {
@ -260,19 +258,19 @@ func (err ErrKeyNameAlreadyUsed) Error() string {
return fmt.Sprintf("public key already exists [owner_id: %d, name: %s]", err.OwnerID, err.Name)
}
// ErrGPGEmailNotFound represents a "ErrGPGEmailNotFound" kind of error.
type ErrGPGEmailNotFound struct {
Email string
// ErrGPGNoEmailFound represents a "ErrGPGNoEmailFound" kind of error.
type ErrGPGNoEmailFound struct {
FailedEmails []string
}
// IsErrGPGEmailNotFound checks if an error is a ErrGPGEmailNotFound.
func IsErrGPGEmailNotFound(err error) bool {
_, ok := err.(ErrGPGEmailNotFound)
// IsErrGPGNoEmailFound checks if an error is a ErrGPGNoEmailFound.
func IsErrGPGNoEmailFound(err error) bool {
_, ok := err.(ErrGPGNoEmailFound)
return ok
}
func (err ErrGPGEmailNotFound) Error() string {
return fmt.Sprintf("failed to found email or is not confirmed : %s", err.Email)
func (err ErrGPGNoEmailFound) Error() string {
return fmt.Sprintf("none of the emails attached to the GPG key could be found: %v", err.FailedEmails)
}
// ErrGPGKeyParsing represents a "ErrGPGKeyParsing" kind of error.

View file

@ -176,3 +176,15 @@
lower_name: repo15
name: repo15
is_bare: true
-
id: 16
owner_id: 2
lower_name: repo16
name: repo16
is_private: false
num_issues: 0
num_closed_issues: 0
num_pulls: 0
num_closed_pulls: 0
num_watches: 0

View file

@ -26,7 +26,7 @@
is_admin: false
avatar: avatar2
avatar_email: user2@example.com
num_repos: 3
num_repos: 4
num_stars: 2
num_followers: 2
num_following: 1

View file

@ -208,21 +208,27 @@ func parseGPGKey(ownerID int64, e *openpgp.Entity) (*GPGKey, error) {
if err != nil {
return nil, err
}
emails := make([]*EmailAddress, len(e.Identities))
n := 0
emails := make([]*EmailAddress, 0, len(e.Identities))
for _, ident := range e.Identities {
email := strings.ToLower(strings.TrimSpace(ident.UserId.Email))
for _, e := range userEmails {
if e.Email == email && e.IsActivated {
emails[n] = e
if e.Email == email {
emails = append(emails, e)
break
}
}
if emails[n] == nil {
return nil, ErrGPGEmailNotFound{ident.UserId.Email}
}
n++
}
//In the case no email as been found
if len(emails) == 0 {
failedEmails := make([]string, 0, len(e.Identities))
for _, ident := range e.Identities {
failedEmails = append(failedEmails, ident.UserId.Email)
}
return nil, ErrGPGNoEmailFound{failedEmails}
}
content, err := base64EncPubKey(pubkey)
if err != nil {
return nil, err
@ -380,8 +386,8 @@ func ParseCommitWithSignature(c *git.Commit) *CommitVerification {
}
//Find Committer account
committer, err := GetUserByEmail(c.Committer.Email)
if err != nil { //Skipping not user for commiter
committer, err := GetUserByEmail(c.Committer.Email) //This find the user by primary email or activated email so commit will not be valid if email is not
if err != nil { //Skipping not user for commiter
log.Error(3, "NoCommitterAccount: %v", err)
return &CommitVerification{
Verified: false,
@ -399,6 +405,18 @@ func ParseCommitWithSignature(c *git.Commit) *CommitVerification {
}
for _, k := range keys {
//Pre-check (& optimization) that emails attached to key can be attached to the commiter email and can validate
canValidate := false
for _, e := range k.Emails {
if e.IsActivated && e.Email == c.Committer.Email {
canValidate = true
break
}
}
if !canValidate {
continue //Skip this key
}
//Generating hash of commit
hash, err := populateHash(sig.Hash, []byte(c.Signature.Payload))
if err != nil { //Skipping ailed to generate hash