mirror of
https://github.com/go-gitea/gitea
synced 2025-07-22 18:28:37 +00:00
Add require signed commit for protected branch (#9708)
* Add require signed commit for protected branch * Fix fmt * Make editor show if they will be signed * bugfix * Add basic merge check and better information for CRUD * linting comment * Add descriptors to merge signing * Slight refactor * Slight improvement to appearances * Handle Merge API * manage CRUD API * Move error to error.go * Remove fix to delete.go * prep for merge * need to tolerate \r\n in message * check protected branch before trying to load it * Apply suggestions from code review Co-Authored-By: guillep2k <18600385+guillep2k@users.noreply.github.com> * fix commit-reader Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com>
This commit is contained in:
@@ -25,6 +25,7 @@ const (
|
||||
headSigned signingMode = "headsigned"
|
||||
commitsSigned signingMode = "commitssigned"
|
||||
approved signingMode = "approved"
|
||||
noKey signingMode = "nokey"
|
||||
)
|
||||
|
||||
func signingModeFromStrings(modeStrings []string) []signingMode {
|
||||
@@ -95,122 +96,140 @@ func PublicSigningKey(repoPath string) (string, error) {
|
||||
}
|
||||
|
||||
// SignInitialCommit determines if we should sign the initial commit to this repository
|
||||
func SignInitialCommit(repoPath string, u *User) (bool, string) {
|
||||
func SignInitialCommit(repoPath string, u *User) (bool, string, error) {
|
||||
rules := signingModeFromStrings(setting.Repository.Signing.InitialCommit)
|
||||
signingKey := signingKey(repoPath)
|
||||
if signingKey == "" {
|
||||
return false, ""
|
||||
return false, "", &ErrWontSign{noKey}
|
||||
}
|
||||
|
||||
for _, rule := range rules {
|
||||
switch rule {
|
||||
case never:
|
||||
return false, ""
|
||||
return false, "", &ErrWontSign{never}
|
||||
case always:
|
||||
break
|
||||
case pubkey:
|
||||
keys, err := ListGPGKeys(u.ID)
|
||||
if err != nil || len(keys) == 0 {
|
||||
return false, ""
|
||||
if err != nil {
|
||||
return false, "", err
|
||||
}
|
||||
if len(keys) == 0 {
|
||||
return false, "", &ErrWontSign{pubkey}
|
||||
}
|
||||
case twofa:
|
||||
twofa, err := GetTwoFactorByUID(u.ID)
|
||||
if err != nil || twofa == nil {
|
||||
return false, ""
|
||||
twofaModel, err := GetTwoFactorByUID(u.ID)
|
||||
if err != nil {
|
||||
return false, "", err
|
||||
}
|
||||
if twofaModel == nil {
|
||||
return false, "", &ErrWontSign{twofa}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true, signingKey
|
||||
return true, signingKey, nil
|
||||
}
|
||||
|
||||
// SignWikiCommit determines if we should sign the commits to this repository wiki
|
||||
func (repo *Repository) SignWikiCommit(u *User) (bool, string) {
|
||||
func (repo *Repository) SignWikiCommit(u *User) (bool, string, error) {
|
||||
rules := signingModeFromStrings(setting.Repository.Signing.Wiki)
|
||||
signingKey := signingKey(repo.WikiPath())
|
||||
if signingKey == "" {
|
||||
return false, ""
|
||||
return false, "", &ErrWontSign{noKey}
|
||||
}
|
||||
|
||||
for _, rule := range rules {
|
||||
switch rule {
|
||||
case never:
|
||||
return false, ""
|
||||
return false, "", &ErrWontSign{never}
|
||||
case always:
|
||||
break
|
||||
case pubkey:
|
||||
keys, err := ListGPGKeys(u.ID)
|
||||
if err != nil || len(keys) == 0 {
|
||||
return false, ""
|
||||
if err != nil {
|
||||
return false, "", err
|
||||
}
|
||||
if len(keys) == 0 {
|
||||
return false, "", &ErrWontSign{pubkey}
|
||||
}
|
||||
case twofa:
|
||||
twofa, err := GetTwoFactorByUID(u.ID)
|
||||
if err != nil || twofa == nil {
|
||||
return false, ""
|
||||
twofaModel, err := GetTwoFactorByUID(u.ID)
|
||||
if err != nil {
|
||||
return false, "", err
|
||||
}
|
||||
if twofaModel == nil {
|
||||
return false, "", &ErrWontSign{twofa}
|
||||
}
|
||||
case parentSigned:
|
||||
gitRepo, err := git.OpenRepository(repo.WikiPath())
|
||||
if err != nil {
|
||||
return false, ""
|
||||
return false, "", err
|
||||
}
|
||||
defer gitRepo.Close()
|
||||
commit, err := gitRepo.GetCommit("HEAD")
|
||||
if err != nil {
|
||||
return false, ""
|
||||
return false, "", err
|
||||
}
|
||||
if commit.Signature == nil {
|
||||
return false, ""
|
||||
return false, "", &ErrWontSign{parentSigned}
|
||||
}
|
||||
verification := ParseCommitWithSignature(commit)
|
||||
if !verification.Verified {
|
||||
return false, ""
|
||||
return false, "", &ErrWontSign{parentSigned}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true, signingKey
|
||||
return true, signingKey, nil
|
||||
}
|
||||
|
||||
// SignCRUDAction determines if we should sign a CRUD commit to this repository
|
||||
func (repo *Repository) SignCRUDAction(u *User, tmpBasePath, parentCommit string) (bool, string) {
|
||||
func (repo *Repository) SignCRUDAction(u *User, tmpBasePath, parentCommit string) (bool, string, error) {
|
||||
rules := signingModeFromStrings(setting.Repository.Signing.CRUDActions)
|
||||
signingKey := signingKey(repo.RepoPath())
|
||||
if signingKey == "" {
|
||||
return false, ""
|
||||
return false, "", &ErrWontSign{noKey}
|
||||
}
|
||||
|
||||
for _, rule := range rules {
|
||||
switch rule {
|
||||
case never:
|
||||
return false, ""
|
||||
return false, "", &ErrWontSign{never}
|
||||
case always:
|
||||
break
|
||||
case pubkey:
|
||||
keys, err := ListGPGKeys(u.ID)
|
||||
if err != nil || len(keys) == 0 {
|
||||
return false, ""
|
||||
if err != nil {
|
||||
return false, "", err
|
||||
}
|
||||
if len(keys) == 0 {
|
||||
return false, "", &ErrWontSign{pubkey}
|
||||
}
|
||||
case twofa:
|
||||
twofa, err := GetTwoFactorByUID(u.ID)
|
||||
if err != nil || twofa == nil {
|
||||
return false, ""
|
||||
twofaModel, err := GetTwoFactorByUID(u.ID)
|
||||
if err != nil {
|
||||
return false, "", err
|
||||
}
|
||||
if twofaModel == nil {
|
||||
return false, "", &ErrWontSign{twofa}
|
||||
}
|
||||
case parentSigned:
|
||||
gitRepo, err := git.OpenRepository(tmpBasePath)
|
||||
if err != nil {
|
||||
return false, ""
|
||||
return false, "", err
|
||||
}
|
||||
defer gitRepo.Close()
|
||||
commit, err := gitRepo.GetCommit(parentCommit)
|
||||
if err != nil {
|
||||
return false, ""
|
||||
return false, "", err
|
||||
}
|
||||
if commit.Signature == nil {
|
||||
return false, ""
|
||||
return false, "", &ErrWontSign{parentSigned}
|
||||
}
|
||||
verification := ParseCommitWithSignature(commit)
|
||||
if !verification.Verified {
|
||||
return false, ""
|
||||
return false, "", &ErrWontSign{parentSigned}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true, signingKey
|
||||
return true, signingKey, nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user