mirror of
				https://github.com/go-gitea/gitea
				synced 2025-11-03 21:08:25 +00:00 
			
		
		
		
	Backport #10425 Backport #10511 * Show Signer in commit lists and add basic trust (#10425) Show the avatar of the signer in the commit list pages as we do not enforce that the signer is an author or committer. This makes it clearer who has signed the commit. Also display commits signed by non-members differently from members and in particular make it clear when a non-member signer is different from the committer to help reduce the risk of spoofing. Signed-off-by: Andrew Thornton <art27@cantab.net> Fix the signing icon in the view_list.tmpl page (#10511) Co-Authored-By: silverwind <me@silverwind.io> Co-authored-by: guillep2k <18600385+guillep2k@users.noreply.github.com>
This commit is contained in:
		@@ -60,7 +60,7 @@ _Symbols used in table:_
 | 
				
			|||||||
| Git LFS 2.0 | ✓ | ✘ | ✓ | ✓ | ✓ | ⁄ | ✓ |
 | 
					| Git LFS 2.0 | ✓ | ✘ | ✓ | ✓ | ✓ | ⁄ | ✓ |
 | 
				
			||||||
| Group Milestones | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
 | 
					| Group Milestones | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
 | 
				
			||||||
| Granular user roles (Code, Issues, Wiki etc) | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
 | 
					| Granular user roles (Code, Issues, Wiki etc) | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
 | 
				
			||||||
| Verified Committer | ✘ | ✘ | ? | ✓ | ✓ | ✓ | ✘ |
 | 
					| Verified Committer | ⁄ | ✘ | ? | ✓ | ✓ | ✓ | ✘ |
 | 
				
			||||||
| GPG Signed Commits | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
 | 
					| GPG Signed Commits | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
 | 
				
			||||||
| Reject unsigned commits | [✘](https://github.com/go-gitea/gitea/issues/2770) | ✘ | ✓ | ✓ | ✓ | ✘ | ✓ |
 | 
					| Reject unsigned commits | [✘](https://github.com/go-gitea/gitea/issues/2770) | ✘ | ✓ | ✓ | ✓ | ✘ | ✓ |
 | 
				
			||||||
| Repository Activity page | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
 | 
					| Repository Activity page | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -369,6 +369,7 @@ type CommitVerification struct {
 | 
				
			|||||||
	CommittingUser *User
 | 
						CommittingUser *User
 | 
				
			||||||
	SigningEmail   string
 | 
						SigningEmail   string
 | 
				
			||||||
	SigningKey     *GPGKey
 | 
						SigningKey     *GPGKey
 | 
				
			||||||
 | 
						TrustStatus    string
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// SignCommit represents a commit with validation of signature.
 | 
					// SignCommit represents a commit with validation of signature.
 | 
				
			||||||
@@ -754,18 +755,54 @@ func verifyWithGPGSettings(gpgSettings *git.GPGSettings, sig *packet.Signature,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// ParseCommitsWithSignature checks if signaute of commits are corresponding to users gpg keys.
 | 
					// ParseCommitsWithSignature checks if signaute of commits are corresponding to users gpg keys.
 | 
				
			||||||
func ParseCommitsWithSignature(oldCommits *list.List) *list.List {
 | 
					func ParseCommitsWithSignature(oldCommits *list.List, repository *Repository) *list.List {
 | 
				
			||||||
	var (
 | 
						var (
 | 
				
			||||||
		newCommits = list.New()
 | 
							newCommits = list.New()
 | 
				
			||||||
		e          = oldCommits.Front()
 | 
							e          = oldCommits.Front()
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
 | 
						memberMap := map[int64]bool{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for e != nil {
 | 
						for e != nil {
 | 
				
			||||||
		c := e.Value.(UserCommit)
 | 
							c := e.Value.(UserCommit)
 | 
				
			||||||
		newCommits.PushBack(SignCommit{
 | 
							signCommit := SignCommit{
 | 
				
			||||||
			UserCommit:   &c,
 | 
								UserCommit:   &c,
 | 
				
			||||||
			Verification: ParseCommitWithSignature(c.Commit),
 | 
								Verification: ParseCommitWithSignature(c.Commit),
 | 
				
			||||||
		})
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							_ = CalculateTrustStatus(signCommit.Verification, repository, &memberMap)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							newCommits.PushBack(signCommit)
 | 
				
			||||||
		e = e.Next()
 | 
							e = e.Next()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return newCommits
 | 
						return newCommits
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CalculateTrustStatus will calculate the TrustStatus for a commit verification within a repository
 | 
				
			||||||
 | 
					func CalculateTrustStatus(verification *CommitVerification, repository *Repository, memberMap *map[int64]bool) (err error) {
 | 
				
			||||||
 | 
						if verification.Verified {
 | 
				
			||||||
 | 
							verification.TrustStatus = "trusted"
 | 
				
			||||||
 | 
							if verification.SigningUser.ID != 0 {
 | 
				
			||||||
 | 
								var isMember bool
 | 
				
			||||||
 | 
								if memberMap != nil {
 | 
				
			||||||
 | 
									var has bool
 | 
				
			||||||
 | 
									isMember, has = (*memberMap)[verification.SigningUser.ID]
 | 
				
			||||||
 | 
									if !has {
 | 
				
			||||||
 | 
										isMember, err = repository.IsOwnerMemberCollaborator(verification.SigningUser.ID)
 | 
				
			||||||
 | 
										(*memberMap)[verification.SigningUser.ID] = isMember
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									isMember, err = repository.IsOwnerMemberCollaborator(verification.SigningUser.ID)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if !isMember {
 | 
				
			||||||
 | 
									verification.TrustStatus = "untrusted"
 | 
				
			||||||
 | 
									if verification.CommittingUser.ID != verification.SigningUser.ID {
 | 
				
			||||||
 | 
										// The committing user and the signing user are not the same and are not the default key
 | 
				
			||||||
 | 
										// This should be marked as questionable unless the signing user is a collaborator/team member etc.
 | 
				
			||||||
 | 
										verification.TrustStatus = "unmatched"
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -202,3 +202,23 @@ func (repo *Repository) getRepoTeams(e Engine) (teams []*Team, err error) {
 | 
				
			|||||||
func (repo *Repository) GetRepoTeams() ([]*Team, error) {
 | 
					func (repo *Repository) GetRepoTeams() ([]*Team, error) {
 | 
				
			||||||
	return repo.getRepoTeams(x)
 | 
						return repo.getRepoTeams(x)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IsOwnerMemberCollaborator checks if a provided user is the owner, a collaborator or a member of a team in a repository
 | 
				
			||||||
 | 
					func (repo *Repository) IsOwnerMemberCollaborator(userID int64) (bool, error) {
 | 
				
			||||||
 | 
						if repo.OwnerID == userID {
 | 
				
			||||||
 | 
							return true, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						teamMember, err := x.Join("INNER", "team_repo", "team_repo.team_id = team_user.team_id").
 | 
				
			||||||
 | 
							Join("INNER", "team_unit", "team_unit.team_id = team_user.team_id").
 | 
				
			||||||
 | 
							Where("team_repo.repo_id = ?", repo.ID).
 | 
				
			||||||
 | 
							And("team_unit.`type` = ?", UnitTypeCode).
 | 
				
			||||||
 | 
							And("team_user.uid = ?", userID).Table("team_user").Exist(&TeamUser{})
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return false, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if teamMember {
 | 
				
			||||||
 | 
							return true, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return x.Get(&Collaboration{RepoID: repo.ID, UserID: userID})
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -797,6 +797,8 @@ commits.date = Date
 | 
				
			|||||||
commits.older = Older
 | 
					commits.older = Older
 | 
				
			||||||
commits.newer = Newer
 | 
					commits.newer = Newer
 | 
				
			||||||
commits.signed_by = Signed by
 | 
					commits.signed_by = Signed by
 | 
				
			||||||
 | 
					commits.signed_by_untrusted_user = Signed by untrusted user
 | 
				
			||||||
 | 
					commits.signed_by_untrusted_user_unmatched = Signed by untrusted user who does not match committer
 | 
				
			||||||
commits.gpg_key_id = GPG Key ID
 | 
					commits.gpg_key_id = GPG Key ID
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ext_issues = Ext. Issues
 | 
					ext_issues = Ext. Issues
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -65,7 +65,7 @@ func Commits(ctx *context.Context) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	commits = models.ValidateCommitsWithEmails(commits)
 | 
						commits = models.ValidateCommitsWithEmails(commits)
 | 
				
			||||||
	commits = models.ParseCommitsWithSignature(commits)
 | 
						commits = models.ParseCommitsWithSignature(commits, ctx.Repo.Repository)
 | 
				
			||||||
	commits = models.ParseCommitsWithStatus(commits, ctx.Repo.Repository)
 | 
						commits = models.ParseCommitsWithStatus(commits, ctx.Repo.Repository)
 | 
				
			||||||
	ctx.Data["Commits"] = commits
 | 
						ctx.Data["Commits"] = commits
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -134,7 +134,7 @@ func SearchCommits(ctx *context.Context) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	commits = models.ValidateCommitsWithEmails(commits)
 | 
						commits = models.ValidateCommitsWithEmails(commits)
 | 
				
			||||||
	commits = models.ParseCommitsWithSignature(commits)
 | 
						commits = models.ParseCommitsWithSignature(commits, ctx.Repo.Repository)
 | 
				
			||||||
	commits = models.ParseCommitsWithStatus(commits, ctx.Repo.Repository)
 | 
						commits = models.ParseCommitsWithStatus(commits, ctx.Repo.Repository)
 | 
				
			||||||
	ctx.Data["Commits"] = commits
 | 
						ctx.Data["Commits"] = commits
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -180,7 +180,7 @@ func FileHistory(ctx *context.Context) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	commits = models.ValidateCommitsWithEmails(commits)
 | 
						commits = models.ValidateCommitsWithEmails(commits)
 | 
				
			||||||
	commits = models.ParseCommitsWithSignature(commits)
 | 
						commits = models.ParseCommitsWithSignature(commits, ctx.Repo.Repository)
 | 
				
			||||||
	commits = models.ParseCommitsWithStatus(commits, ctx.Repo.Repository)
 | 
						commits = models.ParseCommitsWithStatus(commits, ctx.Repo.Repository)
 | 
				
			||||||
	ctx.Data["Commits"] = commits
 | 
						ctx.Data["Commits"] = commits
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -262,12 +262,18 @@ func Diff(ctx *context.Context) {
 | 
				
			|||||||
	setPathsCompareContext(ctx, parentCommit, commit, headTarget)
 | 
						setPathsCompareContext(ctx, parentCommit, commit, headTarget)
 | 
				
			||||||
	ctx.Data["Title"] = commit.Summary() + " · " + base.ShortSha(commitID)
 | 
						ctx.Data["Title"] = commit.Summary() + " · " + base.ShortSha(commitID)
 | 
				
			||||||
	ctx.Data["Commit"] = commit
 | 
						ctx.Data["Commit"] = commit
 | 
				
			||||||
	ctx.Data["Verification"] = models.ParseCommitWithSignature(commit)
 | 
						verification := models.ParseCommitWithSignature(commit)
 | 
				
			||||||
 | 
						ctx.Data["Verification"] = verification
 | 
				
			||||||
	ctx.Data["Author"] = models.ValidateCommitWithEmail(commit)
 | 
						ctx.Data["Author"] = models.ValidateCommitWithEmail(commit)
 | 
				
			||||||
	ctx.Data["Diff"] = diff
 | 
						ctx.Data["Diff"] = diff
 | 
				
			||||||
	ctx.Data["Parents"] = parents
 | 
						ctx.Data["Parents"] = parents
 | 
				
			||||||
	ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0
 | 
						ctx.Data["DiffNotAvailable"] = diff.NumFiles() == 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := models.CalculateTrustStatus(verification, ctx.Repo.Repository, nil); err != nil {
 | 
				
			||||||
 | 
							ctx.ServerError("CalculateTrustStatus", err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	note := &git.Note{}
 | 
						note := &git.Note{}
 | 
				
			||||||
	err = git.GetNote(ctx.Repo.GitRepo, commitID, note)
 | 
						err = git.GetNote(ctx.Repo.GitRepo, commitID, note)
 | 
				
			||||||
	if err == nil {
 | 
						if err == nil {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -316,7 +316,7 @@ func PrepareCompareDiff(
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	compareInfo.Commits = models.ValidateCommitsWithEmails(compareInfo.Commits)
 | 
						compareInfo.Commits = models.ValidateCommitsWithEmails(compareInfo.Commits)
 | 
				
			||||||
	compareInfo.Commits = models.ParseCommitsWithSignature(compareInfo.Commits)
 | 
						compareInfo.Commits = models.ParseCommitsWithSignature(compareInfo.Commits, headRepo)
 | 
				
			||||||
	compareInfo.Commits = models.ParseCommitsWithStatus(compareInfo.Commits, headRepo)
 | 
						compareInfo.Commits = models.ParseCommitsWithStatus(compareInfo.Commits, headRepo)
 | 
				
			||||||
	ctx.Data["Commits"] = compareInfo.Commits
 | 
						ctx.Data["Commits"] = compareInfo.Commits
 | 
				
			||||||
	ctx.Data["CommitCount"] = compareInfo.Commits.Len()
 | 
						ctx.Data["CommitCount"] = compareInfo.Commits.Len()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -477,7 +477,7 @@ func ViewPullCommits(ctx *context.Context) {
 | 
				
			|||||||
	ctx.Data["Reponame"] = ctx.Repo.Repository.Name
 | 
						ctx.Data["Reponame"] = ctx.Repo.Repository.Name
 | 
				
			||||||
	commits = prInfo.Commits
 | 
						commits = prInfo.Commits
 | 
				
			||||||
	commits = models.ValidateCommitsWithEmails(commits)
 | 
						commits = models.ValidateCommitsWithEmails(commits)
 | 
				
			||||||
	commits = models.ParseCommitsWithSignature(commits)
 | 
						commits = models.ParseCommitsWithSignature(commits, ctx.Repo.Repository)
 | 
				
			||||||
	commits = models.ParseCommitsWithStatus(commits, ctx.Repo.Repository)
 | 
						commits = models.ParseCommitsWithStatus(commits, ctx.Repo.Repository)
 | 
				
			||||||
	ctx.Data["Commits"] = commits
 | 
						ctx.Data["Commits"] = commits
 | 
				
			||||||
	ctx.Data["CommitCount"] = commits.Len()
 | 
						ctx.Data["CommitCount"] = commits.Len()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -181,7 +181,14 @@ func renderDirectory(ctx *context.Context, treeLink string) {
 | 
				
			|||||||
	// Show latest commit info of repository in table header,
 | 
						// Show latest commit info of repository in table header,
 | 
				
			||||||
	// or of directory if not in root directory.
 | 
						// or of directory if not in root directory.
 | 
				
			||||||
	ctx.Data["LatestCommit"] = latestCommit
 | 
						ctx.Data["LatestCommit"] = latestCommit
 | 
				
			||||||
	ctx.Data["LatestCommitVerification"] = models.ParseCommitWithSignature(latestCommit)
 | 
						verification := models.ParseCommitWithSignature(latestCommit)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := models.CalculateTrustStatus(verification, ctx.Repo.Repository, nil); err != nil {
 | 
				
			||||||
 | 
							ctx.ServerError("CalculateTrustStatus", err)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ctx.Data["LatestCommitVerification"] = verification
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx.Data["LatestCommitUser"] = models.ValidateCommitWithEmail(latestCommit)
 | 
						ctx.Data["LatestCommitUser"] = models.ValidateCommitWithEmail(latestCommit)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	statuses, err := models.GetLatestCommitStatus(ctx.Repo.Repository, ctx.Repo.Commit.ID.String(), 0)
 | 
						statuses, err := models.GetLatestCommitStatus(ctx.Repo.Repository, ctx.Repo.Commit.ID.String(), 0)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -284,7 +284,7 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry)
 | 
				
			|||||||
		return nil, nil
 | 
							return nil, nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	commitsHistory = models.ValidateCommitsWithEmails(commitsHistory)
 | 
						commitsHistory = models.ValidateCommitsWithEmails(commitsHistory)
 | 
				
			||||||
	commitsHistory = models.ParseCommitsWithSignature(commitsHistory)
 | 
						commitsHistory = models.ParseCommitsWithSignature(commitsHistory, ctx.Repo.Repository)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ctx.Data["Commits"] = commitsHistory
 | 
						ctx.Data["Commits"] = commitsHistory
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,22 @@
 | 
				
			|||||||
<div class="repository diff">
 | 
					<div class="repository diff">
 | 
				
			||||||
	{{template "repo/header" .}}
 | 
						{{template "repo/header" .}}
 | 
				
			||||||
	<div class="ui container {{if .IsSplitStyle}}fluid padded{{end}}">
 | 
						<div class="ui container {{if .IsSplitStyle}}fluid padded{{end}}">
 | 
				
			||||||
		<div class="ui top attached info clearing segment {{if .Commit.Signature}} isSigned {{if .Verification.Verified }} isVerified {{end}}{{end}}">
 | 
							{{$class := ""}}
 | 
				
			||||||
 | 
							{{if .Commit.Signature}}
 | 
				
			||||||
 | 
								{{$class = (printf "%s%s" $class " isSigned")}}
 | 
				
			||||||
 | 
								{{if .Verification.Verified}}
 | 
				
			||||||
 | 
									{{if eq .Verification.TrustStatus "trusted"}}
 | 
				
			||||||
 | 
										{{$class = (printf "%s%s" $class " isVerified")}}
 | 
				
			||||||
 | 
									{{else if eq .Verification.TrustStatus "untrusted"}}
 | 
				
			||||||
 | 
										{{$class = (printf "%s%s" $class " isVerifiedUntrusted")}}
 | 
				
			||||||
 | 
									{{else}}
 | 
				
			||||||
 | 
										{{$class = (printf "%s%s" $class " isVerifiedUnmatched")}}
 | 
				
			||||||
 | 
									{{end}}
 | 
				
			||||||
 | 
								{{else if .Verification.Warning}}
 | 
				
			||||||
 | 
									{{$class = (printf "%s%s" $class " isWarning")}}
 | 
				
			||||||
 | 
								{{end}}
 | 
				
			||||||
 | 
							{{end}}
 | 
				
			||||||
 | 
							<div class="ui top attached info clearing segment {{$class}}">
 | 
				
			||||||
			<a class="ui floated right blue tiny button" href="{{EscapePound .SourcePath}}">
 | 
								<a class="ui floated right blue tiny button" href="{{EscapePound .SourcePath}}">
 | 
				
			||||||
				{{.i18n.Tr "repo.diff.browse_source"}}
 | 
									{{.i18n.Tr "repo.diff.browse_source"}}
 | 
				
			||||||
			</a>
 | 
								</a>
 | 
				
			||||||
@@ -12,15 +27,15 @@
 | 
				
			|||||||
			{{end}}
 | 
								{{end}}
 | 
				
			||||||
			<span class="text grey"><i class="octicon octicon-git-branch"></i>{{.BranchName}}</span>
 | 
								<span class="text grey"><i class="octicon octicon-git-branch"></i>{{.BranchName}}</span>
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
		<div class="ui attached info segment {{if .Commit.Signature}} isSigned {{if .Verification.Verified }} isVerified {{end}}{{end}}">
 | 
							<div class="ui attached info segment {{$class}}">
 | 
				
			||||||
			<div class="ui stackable grid">
 | 
								<div class="ui stackable grid">
 | 
				
			||||||
				<div class="nine wide column">
 | 
									<div class="nine wide column">
 | 
				
			||||||
					{{if .Author}}
 | 
										{{if .Author}}
 | 
				
			||||||
						<img class="ui avatar image" src="{{.Author.RelAvatarLink}}" />
 | 
											<img class="ui avatar image" src="{{.Author.RelAvatarLink}}" />
 | 
				
			||||||
					{{if .Author.FullName}}
 | 
										{{if .Author.FullName}}
 | 
				
			||||||
					<a href="{{.Author.HomeLink}}"><strong>{{.Author.FullName}}</strong></a> {{if .IsSigned}}<{{.Commit.Author.Email}}>{{end}}
 | 
										<a href="{{.Author.HomeLink}}"><strong>{{.Author.FullName}}</strong> {{if .IsSigned}}<{{.Commit.Author.Email}}>{{end}}</a>
 | 
				
			||||||
					{{else}}
 | 
										{{else}}
 | 
				
			||||||
					<a href="{{.Author.HomeLink}}"><strong>{{.Commit.Author.Name}}</strong></a> {{if .IsSigned}}<{{.Commit.Author.Email}}>{{end}}
 | 
										<a href="{{.Author.HomeLink}}"><strong>{{.Commit.Author.Name}}</strong> {{if .IsSigned}}<{{.Commit.Author.Email}}>{{end}}</a>
 | 
				
			||||||
					{{end}}
 | 
										{{end}}
 | 
				
			||||||
					{{else}}
 | 
										{{else}}
 | 
				
			||||||
						<img class="ui avatar image" src="{{AvatarLink .Commit.Author.Email}}" />
 | 
											<img class="ui avatar image" src="{{AvatarLink .Commit.Author.Email}}" />
 | 
				
			||||||
@@ -30,7 +45,7 @@
 | 
				
			|||||||
						<span> </span>
 | 
											<span> </span>
 | 
				
			||||||
						{{if ne .Verification.CommittingUser.ID 0}}
 | 
											{{if ne .Verification.CommittingUser.ID 0}}
 | 
				
			||||||
							<img class="ui avatar image" src="{{.Verification.CommittingUser.RelAvatarLink}}" />
 | 
												<img class="ui avatar image" src="{{.Verification.CommittingUser.RelAvatarLink}}" />
 | 
				
			||||||
							<a href="{{.Verification.CommittingUser.HomeLink}}"><strong>{{.Commit.Committer.Name}}</strong></a> <{{.Commit.Committer.Email}}>
 | 
												<a href="{{.Verification.CommittingUser.HomeLink}}"><strong>{{.Commit.Committer.Name}}</strong> <{{.Commit.Committer.Email}}></a> 
 | 
				
			||||||
						{{else}}
 | 
											{{else}}
 | 
				
			||||||
							<img class="ui avatar image" src="{{AvatarLink .Commit.Committer.Email}}" />
 | 
												<img class="ui avatar image" src="{{AvatarLink .Commit.Committer.Email}}" />
 | 
				
			||||||
							<strong>{{.Commit.Committer.Name}}</strong>
 | 
												<strong>{{.Commit.Committer.Name}}</strong>
 | 
				
			||||||
@@ -58,40 +73,42 @@
 | 
				
			|||||||
			</div><!-- end grid -->
 | 
								</div><!-- end grid -->
 | 
				
			||||||
		</div>
 | 
							</div>
 | 
				
			||||||
		{{if .Commit.Signature}}
 | 
							{{if .Commit.Signature}}
 | 
				
			||||||
			{{if .Verification.Verified }}
 | 
								<div class="ui bottom attached message {{$class}}">
 | 
				
			||||||
				<div class="ui bottom attached positive message">
 | 
									{{if .Verification.Verified }}
 | 
				
			||||||
					{{if ne .Verification.SigningUser.ID 0}}
 | 
										{{if ne .Verification.SigningUser.ID 0}}
 | 
				
			||||||
						<i class="green lock icon"></i>
 | 
											<i class="lock icon"></i>
 | 
				
			||||||
						<span>{{.i18n.Tr "repo.commits.signed_by"}}:</span>
 | 
											{{if eq .Verification.TrustStatus "trusted"}}
 | 
				
			||||||
 | 
												<span class="ui text">{{.i18n.Tr "repo.commits.signed_by"}}:</span>
 | 
				
			||||||
 | 
											{{else if eq .Verification.TrustStatus "untrusted"}}
 | 
				
			||||||
 | 
												<span class="ui text">{{.i18n.Tr "repo.commits.signed_by_untrusted_user"}}:</span>
 | 
				
			||||||
 | 
											{{else}}
 | 
				
			||||||
 | 
												<span class="ui text">{{.i18n.Tr "repo.commits.signed_by_untrusted_user_unmatched"}}:</span>
 | 
				
			||||||
 | 
											{{end}}
 | 
				
			||||||
						<img class="ui avatar image" src="{{.Verification.SigningUser.RelAvatarLink}}" />
 | 
											<img class="ui avatar image" src="{{.Verification.SigningUser.RelAvatarLink}}" />
 | 
				
			||||||
						<a href="{{.Verification.SigningUser.HomeLink}}"><strong>{{.Verification.SigningUser.Name}}</strong></a> <{{.Verification.SigningEmail}}>
 | 
											<a href="{{.Verification.SigningUser.HomeLink}}"><strong>{{.Verification.SigningUser.Name}}</strong> <{{.Verification.SigningEmail}}></a>
 | 
				
			||||||
						<span class="pull-right"><span>{{.i18n.Tr "repo.commits.gpg_key_id"}}:</span> {{.Verification.SigningKey.KeyID}}</span>
 | 
											<span class="pull-right"><span class="ui text">{{.i18n.Tr "repo.commits.gpg_key_id"}}:</span> {{.Verification.SigningKey.KeyID}}</span>
 | 
				
			||||||
					{{else}}
 | 
										{{else}}
 | 
				
			||||||
						<i class="icons" title="{{.i18n.Tr "gpg.default_key"}}">
 | 
											<i class="icons" title="{{.i18n.Tr "gpg.default_key"}}">
 | 
				
			||||||
							<i class="green lock icon"></i>
 | 
												<i class="lock icon"></i>
 | 
				
			||||||
							<i class="tiny inverted cog icon centerlock"></i>
 | 
												<i class="tiny inverted cog icon centerlock"></i>
 | 
				
			||||||
						</i>
 | 
											</i>
 | 
				
			||||||
						<span>{{.i18n.Tr "repo.commits.signed_by"}}:</span>
 | 
											<span class="ui text">{{.i18n.Tr "repo.commits.signed_by"}}:</span>
 | 
				
			||||||
						<img class="ui avatar image" src="{{AvatarLink .Verification.SigningEmail}}" />
 | 
											<img class="ui avatar image" src="{{AvatarLink .Verification.SigningEmail}}" />
 | 
				
			||||||
						<strong>{{.Verification.SigningUser.Name}}</strong> <{{.Verification.SigningEmail}}>
 | 
											<strong>{{.Verification.SigningUser.Name}}</strong> <{{.Verification.SigningEmail}}>
 | 
				
			||||||
						<span class="pull-right"><span>{{.i18n.Tr "repo.commits.gpg_key_id"}}:</span> <i class="cogs icon" title="{{.i18n.Tr "gpg.default_key"}}"></i>{{.Verification.SigningKey.KeyID}}</span>
 | 
											<span class="pull-right"><span class="ui text">{{.i18n.Tr "repo.commits.gpg_key_id"}}:</span> <i class="cogs icon" title="{{.i18n.Tr "gpg.default_key"}}"></i>{{.Verification.SigningKey.KeyID}}</span>
 | 
				
			||||||
					{{end}}
 | 
										{{end}}
 | 
				
			||||||
				</div>
 | 
									{{else if .Verification.Warning}}
 | 
				
			||||||
			{{else if .Verification.Warning}}
 | 
										<i class="unlock icon"></i>
 | 
				
			||||||
				<div class="ui bottom attached message">
 | 
										<span class="ui text">{{.i18n.Tr .Verification.Reason}}</span>
 | 
				
			||||||
				  <i class="red unlock icon"></i>
 | 
										<span class="pull-right"><span class="ui text">{{.i18n.Tr "repo.commits.gpg_key_id"}}:</span> <i class="warning icon"></i>{{.Verification.SigningKey.KeyID}}</span>
 | 
				
			||||||
				  <span class="red text">{{.i18n.Tr .Verification.Reason}}</span>
 | 
									{{else}}
 | 
				
			||||||
				  <span class="pull-right"><span class="red text">{{.i18n.Tr "repo.commits.gpg_key_id"}}:</span> <i class="red warning icon"></i>{{.Verification.SigningKey.KeyID}}</span>
 | 
									  <i class="unlock icon"></i>
 | 
				
			||||||
				</div>
 | 
					 | 
				
			||||||
			{{else}}
 | 
					 | 
				
			||||||
				<div class="ui bottom attached message">
 | 
					 | 
				
			||||||
				  <i class="grey unlock icon"></i>
 | 
					 | 
				
			||||||
				  {{.i18n.Tr .Verification.Reason}}
 | 
									  {{.i18n.Tr .Verification.Reason}}
 | 
				
			||||||
				  {{if and .Verification.SigningKey (ne .Verification.SigningKey.KeyID "")}}
 | 
									  {{if and .Verification.SigningKey (ne .Verification.SigningKey.KeyID "")}}
 | 
				
			||||||
					<span class="pull-right"><span class="red text">{{.i18n.Tr "repo.commits.gpg_key_id"}}:</span> <i class="red warning icon"></i>{{.Verification.SigningKey.KeyID}}</span>
 | 
										<span class="pull-right"><span class="ui text">{{.i18n.Tr "repo.commits.gpg_key_id"}}:</span> <i class="warning icon"></i>{{.Verification.SigningKey.KeyID}}</span>
 | 
				
			||||||
				  {{end}}
 | 
									  {{end}}
 | 
				
			||||||
				</div>
 | 
									{{end}}
 | 
				
			||||||
			{{end}}
 | 
								</div>
 | 
				
			||||||
		{{end}}
 | 
							{{end}}
 | 
				
			||||||
		{{if .Note}}
 | 
							{{if .Note}}
 | 
				
			||||||
			<div class="ui top attached info segment message git-notes">
 | 
								<div class="ui top attached info segment message git-notes">
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,7 +28,13 @@
 | 
				
			|||||||
							{{if .Signature}}
 | 
												{{if .Signature}}
 | 
				
			||||||
								{{$class = (printf "%s%s" $class " isSigned")}}
 | 
													{{$class = (printf "%s%s" $class " isSigned")}}
 | 
				
			||||||
								{{if .Verification.Verified}}
 | 
													{{if .Verification.Verified}}
 | 
				
			||||||
									{{$class = (printf "%s%s" $class " isVerified")}}
 | 
														{{if eq .Verification.TrustStatus "trusted"}}
 | 
				
			||||||
 | 
															{{$class = (printf "%s%s" $class " isVerified")}}
 | 
				
			||||||
 | 
														{{else if eq .Verification.TrustStatus "untrusted"}}
 | 
				
			||||||
 | 
															{{$class = (printf "%s%s" $class " isVerifiedUntrusted")}}
 | 
				
			||||||
 | 
														{{else}}
 | 
				
			||||||
 | 
															{{$class = (printf "%s%s" $class " isVerifiedUnmatched")}}
 | 
				
			||||||
 | 
														{{end}}
 | 
				
			||||||
								{{else if .Verification.Warning}}
 | 
													{{else if .Verification.Warning}}
 | 
				
			||||||
									{{$class = (printf "%s%s" $class " isWarning")}}
 | 
														{{$class = (printf "%s%s" $class " isWarning")}}
 | 
				
			||||||
								{{end}}
 | 
													{{end}}
 | 
				
			||||||
@@ -38,20 +44,22 @@
 | 
				
			|||||||
							{{else}}
 | 
												{{else}}
 | 
				
			||||||
								<span class="{{$class}}">
 | 
													<span class="{{$class}}">
 | 
				
			||||||
							{{end}}
 | 
												{{end}}
 | 
				
			||||||
								{{ShortSha .ID.String}}
 | 
													<span class="shortsha">{{ShortSha .ID.String}}</span>
 | 
				
			||||||
								{{if .Signature}}
 | 
													{{if .Signature}}
 | 
				
			||||||
									<div class="ui detail icon button">
 | 
														<div class="ui detail icon button">
 | 
				
			||||||
										{{if .Verification.Verified}}
 | 
															{{if .Verification.Verified}}
 | 
				
			||||||
											{{if ne .Verification.SigningUser.ID 0}}
 | 
																<div title="{{if eq .Verification.TrustStatus "trusted"}}{{else if eq .Verification.TrustStatus "untrusted"}}{{$.i18n.Tr "repo.commits.signed_by_untrusted_user"}}: {{else}}{{$.i18n.Tr "repo.commits.signed_by_untrusted_user_unmatched"}}: {{end}}{{.Verification.Reason}}">
 | 
				
			||||||
												<i title="{{.Verification.Reason}}" class="lock green icon"></i>
 | 
																	{{if ne .Verification.SigningUser.ID 0}}
 | 
				
			||||||
											{{else}}
 | 
																		<i class="lock icon"></i>
 | 
				
			||||||
												<i title="{{.Verification.Reason}}" class="icons">
 | 
																		<img class="ui signature avatar image" src="{{.Verification.SigningUser.RelAvatarLink}}" />
 | 
				
			||||||
													<i class="green lock icon"></i>
 | 
																	{{else}}
 | 
				
			||||||
													<i class="tiny inverted cog icon centerlock"></i>
 | 
																		<i title="{{.Verification.Reason}}" class="icons">
 | 
				
			||||||
												</i>
 | 
																			<i class="lock icon"></i>
 | 
				
			||||||
											{{end}}
 | 
																			<i class="tiny inverted cog icon centerlock"></i>
 | 
				
			||||||
										{{else if .Verification.Warning}}
 | 
																		</i>
 | 
				
			||||||
											<i title="{{$.i18n.Tr .Verification.Reason}}" class="red unlock icon"></i>
 | 
																		<img class="ui signature avatar image" src="{{AvatarLink .Verification.SigningEmail}}" />
 | 
				
			||||||
 | 
																	{{end}}
 | 
				
			||||||
 | 
																</div>
 | 
				
			||||||
										{{else}}
 | 
															{{else}}
 | 
				
			||||||
											<i title="{{$.i18n.Tr .Verification.Reason}}" class="unlock icon"></i>
 | 
																<i title="{{$.i18n.Tr .Verification.Reason}}" class="unlock icon"></i>
 | 
				
			||||||
										{{end}}
 | 
															{{end}}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,17 +15,28 @@
 | 
				
			|||||||
						<strong>{{.LatestCommit.Author.Name}}</strong>
 | 
											<strong>{{.LatestCommit.Author.Name}}</strong>
 | 
				
			||||||
					{{end}}
 | 
										{{end}}
 | 
				
			||||||
				{{end}}
 | 
									{{end}}
 | 
				
			||||||
				<a rel="nofollow" class="ui sha label {{if .LatestCommit.Signature}} isSigned {{if .LatestCommitVerification.Verified }} isVerified {{end}}{{end}}" href="{{.RepoLink}}/commit/{{.LatestCommit.ID}}">
 | 
									<a rel="nofollow" class="ui sha label {{if .LatestCommit.Signature}} isSigned {{if .LatestCommitVerification.Verified }} isVerified{{if eq .LatestCommitVerification.TrustStatus "trusted"}}{{else if eq .LatestCommitVerification.TrustStatus "untrusted"}}Untrusted{{else}}Unmatched{{end}}{{else if .LatestCommitVerification.Warning}} isWarning{{end}}{{end}}" href="{{.RepoLink}}/commit/{{.LatestCommit.ID}}">
 | 
				
			||||||
						{{ShortSha .LatestCommit.ID.String}}
 | 
										<span class="shortsha">{{ShortSha .LatestCommit.ID.String}}</span>
 | 
				
			||||||
 | 
										<div class="ui detail icon button">
 | 
				
			||||||
						{{if .LatestCommit.Signature}}
 | 
											{{if .LatestCommit.Signature}}
 | 
				
			||||||
							<div class="ui detail icon button">
 | 
												{{if .LatestCommitVerification.Verified}}
 | 
				
			||||||
								{{if .LatestCommitVerification.Verified}}
 | 
													<div title="{{if eq .LatestCommitVerification.TrustStatus "trusted"}}{{else if eq .LatestCommitVerification.TrustStatus "untrusted"}}{{.i18n.Tr "repo.commits.signed_by_untrusted_user"}}: {{else}}{{.i18n.Tr "repo.commits.signed_by_untrusted_user_unmatched"}}: {{end}}{{.LatestCommitVerification.Reason}}">
 | 
				
			||||||
									<i title="{{.LatestCommitVerification.Reason}}" class="lock green icon"></i>
 | 
														{{if ne .LatestCommitVerification.SigningUser.ID 0}}
 | 
				
			||||||
								{{else}}
 | 
															<i class="lock icon"></i>
 | 
				
			||||||
									<i title="{{$.i18n.Tr .LatestCommitVerification.Reason}}" class="unlock icon"></i>
 | 
															<img class="ui signature avatar image" src="{{.LatestCommitVerification.SigningUser.RelAvatarLink}}" />
 | 
				
			||||||
								{{end}}
 | 
														{{else}}
 | 
				
			||||||
							</div>
 | 
															<i title="{{.LatestCommitVerification.Reason}}" class="icons">
 | 
				
			||||||
 | 
																<i class="lock icon"></i>
 | 
				
			||||||
 | 
																<i class="tiny inverted cog icon centerlock"></i>
 | 
				
			||||||
 | 
															</i>
 | 
				
			||||||
 | 
															<img class="ui signature avatar image" src="{{AvatarLink .LatestCommitVerification.SigningEmail}}" />
 | 
				
			||||||
 | 
														{{end}}
 | 
				
			||||||
 | 
													</div>
 | 
				
			||||||
 | 
												{{else}}
 | 
				
			||||||
 | 
													<i title="{{$.i18n.Tr .LatestCommitVerification.Reason}}" class="unlock icon"></i>
 | 
				
			||||||
 | 
												{{end}}
 | 
				
			||||||
						{{end}}
 | 
											{{end}}
 | 
				
			||||||
 | 
										</div>
 | 
				
			||||||
				</a>
 | 
									</a>
 | 
				
			||||||
				{{template "repo/commit_status" .LatestCommitStatus}}
 | 
									{{template "repo/commit_status" .LatestCommitStatus}}
 | 
				
			||||||
				{{ $commitLink:= printf "%s/commit/%s" .RepoLink .LatestCommit.ID }}
 | 
									{{ $commitLink:= printf "%s/commit/%s" .RepoLink .LatestCommit.ID }}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -471,6 +471,10 @@ code,
 | 
				
			|||||||
            color: #fbbd08 !important;
 | 
					            color: #fbbd08 !important;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        &.orange {
 | 
				
			||||||
 | 
					            color: #f2711c !important;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        &.gold {
 | 
					        &.gold {
 | 
				
			||||||
            color: #a1882b !important;
 | 
					            color: #a1882b !important;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -668,6 +672,10 @@ code,
 | 
				
			|||||||
            background-color: #fbbf09 !important;
 | 
					            background-color: #fbbf09 !important;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        &.orange {
 | 
				
			||||||
 | 
					            background-color: #f2711c !important;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        &.gold {
 | 
					        &.gold {
 | 
				
			||||||
            background-color: #a1882b !important;
 | 
					            background-color: #a1882b !important;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -719,6 +727,10 @@ code,
 | 
				
			|||||||
            border-color: #fbbd08 !important;
 | 
					            border-color: #fbbd08 !important;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        &.orange {
 | 
				
			||||||
 | 
					            border-color: #f2711c !important;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        &.gold {
 | 
					        &.gold {
 | 
				
			||||||
            border-color: #a1882b !important;
 | 
					            border-color: #a1882b !important;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -1041,7 +1053,7 @@ i.icons .icon:first-child {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
i.icon.centerlock {
 | 
					i.icon.centerlock {
 | 
				
			||||||
    top: 1.5em;
 | 
					    top: 1.45em;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.ui.label > .detail .icons {
 | 
					.ui.label > .detail .icons {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1222,7 +1222,7 @@
 | 
				
			|||||||
                    text-align: center;
 | 
					                    text-align: center;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                width: 140px;
 | 
					                width: 175px;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1243,21 +1243,49 @@
 | 
				
			|||||||
    #repo-files-table .sha.label {
 | 
					    #repo-files-table .sha.label {
 | 
				
			||||||
        border: 1px solid #bbbbbb;
 | 
					        border: 1px solid #bbbbbb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        .ui.signature.avatar {
 | 
				
			||||||
 | 
					            height: 16px;
 | 
				
			||||||
 | 
					            margin-bottom: 0;
 | 
				
			||||||
 | 
					            width: auto;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        .detail.icon {
 | 
					        .detail.icon {
 | 
				
			||||||
            background: #fafafa;
 | 
					            background: #fafafa;
 | 
				
			||||||
            margin: -6px -10px -4px 0;
 | 
					            margin: -6px -10px -4px 0;
 | 
				
			||||||
            padding: 5px 3px 5px 6px;
 | 
					            padding: 5px 4px 5px 6px;
 | 
				
			||||||
            border-left: 1px solid #bbbbbb;
 | 
					            border-left: 1px solid #bbbbbb;
 | 
				
			||||||
 | 
					            border-top: 0;
 | 
				
			||||||
 | 
					            border-right: 0;
 | 
				
			||||||
 | 
					            border-bottom: 0;
 | 
				
			||||||
            border-top-left-radius: 0;
 | 
					            border-top-left-radius: 0;
 | 
				
			||||||
            border-bottom-left-radius: 0;
 | 
					            border-bottom-left-radius: 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            img {
 | 
				
			||||||
 | 
					                margin-right: 0;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            > div {
 | 
				
			||||||
 | 
					                display: inline-flex;
 | 
				
			||||||
 | 
					                align-items: center;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        &.isSigned.isWarning {
 | 
					        &.isSigned.isWarning {
 | 
				
			||||||
            border: 1px solid #db2828;
 | 
					            border: 1px solid #db2828;
 | 
				
			||||||
            background: fade(#db2828, 10%);
 | 
					            background: fade(#db2828, 10%);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            .shortsha {
 | 
				
			||||||
 | 
					                display: inline-block;
 | 
				
			||||||
 | 
					                padding-top: 1px;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            .detail.icon {
 | 
					            .detail.icon {
 | 
				
			||||||
                border-left: 1px solid fade(#db2828, 50%);
 | 
					                border-left: 1px solid #db2828;
 | 
				
			||||||
 | 
					                color: #db2828;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            &:hover {
 | 
				
			||||||
 | 
					                background: fade(#db2828, 30%) !important;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1265,14 +1293,58 @@
 | 
				
			|||||||
            border: 1px solid #21ba45;
 | 
					            border: 1px solid #21ba45;
 | 
				
			||||||
            background: fade(#21ba45, 10%);
 | 
					            background: fade(#21ba45, 10%);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            .shortsha {
 | 
				
			||||||
 | 
					                display: inline-block;
 | 
				
			||||||
 | 
					                padding-top: 1px;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            .detail.icon {
 | 
					            .detail.icon {
 | 
				
			||||||
                border-left: 1px solid #21ba45;
 | 
					                border-left: 1px solid #21ba45;
 | 
				
			||||||
 | 
					                color: #21ba45;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            &:hover {
 | 
					            &:hover {
 | 
				
			||||||
                background: fade(#21ba45, 30%) !important;
 | 
					                background: fade(#21ba45, 30%) !important;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        &.isSigned.isVerifiedUntrusted {
 | 
				
			||||||
 | 
					            border: 1px solid #fbbd08;
 | 
				
			||||||
 | 
					            background: fade(#fbbd08, 10%);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            .shortsha {
 | 
				
			||||||
 | 
					                display: inline-block;
 | 
				
			||||||
 | 
					                padding-top: 1px;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            .detail.icon {
 | 
				
			||||||
 | 
					                border-left: 1px solid #fbbd08;
 | 
				
			||||||
 | 
					                color: #fbbd08;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            &:hover {
 | 
				
			||||||
 | 
					                background: fade(#fbbd08, 30%) !important;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        &.isSigned.isVerifiedUnmatched {
 | 
				
			||||||
 | 
					            border: 1px solid #f2711c;
 | 
				
			||||||
 | 
					            background: fade(#f2711c, 10%);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            .shortsha {
 | 
				
			||||||
 | 
					                display: inline-block;
 | 
				
			||||||
 | 
					                padding-top: 1px;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            .detail.icon {
 | 
				
			||||||
 | 
					                border-left: 1px solid #f2711c;
 | 
				
			||||||
 | 
					                color: #f2711c;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            &:hover {
 | 
				
			||||||
 | 
					                background: fade(#f2711c, 30%) !important;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .diff-detail-box {
 | 
					    .diff-detail-box {
 | 
				
			||||||
@@ -1872,21 +1944,114 @@
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .ui.attached.isSigned.isVerified {
 | 
					    .ui.attached.isSigned.isWarning {
 | 
				
			||||||
        &:not(.positive) {
 | 
					        border-left: 1px solid #c29393;
 | 
				
			||||||
            border-left: 1px solid #a3c293;
 | 
					        border-right: 1px solid #c29393;
 | 
				
			||||||
            border-right: 1px solid #a3c293;
 | 
					
 | 
				
			||||||
 | 
					        &.top,
 | 
				
			||||||
 | 
					        &.message {
 | 
				
			||||||
 | 
					            border-top: 1px solid #c29393;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        &.top:not(.positive) {
 | 
					        &.message {
 | 
				
			||||||
 | 
					            box-shadow: none;
 | 
				
			||||||
 | 
					            background-color: #fff5f5;
 | 
				
			||||||
 | 
					            color: #d95c5c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            .ui.text {
 | 
				
			||||||
 | 
					                color: #d64444;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        &:last-child,
 | 
				
			||||||
 | 
					        &.bottom {
 | 
				
			||||||
 | 
					            border-bottom: 1px solid #c29393;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .ui.attached.isSigned:not(.isWarning) .pull-right {
 | 
				
			||||||
 | 
					        padding-top: 5px;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .ui.attached.isSigned.isVerified {
 | 
				
			||||||
 | 
					        border-left: 1px solid #a3c293;
 | 
				
			||||||
 | 
					        border-right: 1px solid #a3c293;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        &.top,
 | 
				
			||||||
 | 
					        &.message {
 | 
				
			||||||
            border-top: 1px solid #a3c293;
 | 
					            border-top: 1px solid #a3c293;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        &:not(.positive):last-child {
 | 
					        &.message {
 | 
				
			||||||
 | 
					            box-shadow: none;
 | 
				
			||||||
 | 
					            background-color: #fcfff5;
 | 
				
			||||||
 | 
					            color: #6cc644;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            .pull-right {
 | 
				
			||||||
 | 
					                color: #000;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            .ui.text {
 | 
				
			||||||
 | 
					                color: #21ba45;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        &:last-child,
 | 
				
			||||||
 | 
					        &.bottom {
 | 
				
			||||||
            border-bottom: 1px solid #a3c293;
 | 
					            border-bottom: 1px solid #a3c293;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .ui.attached.isSigned.isVerifiedUntrusted {
 | 
				
			||||||
 | 
					        border-left: 1px solid #c2c193;
 | 
				
			||||||
 | 
					        border-right: 1px solid #c2c193;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        &.top,
 | 
				
			||||||
 | 
					        &.message {
 | 
				
			||||||
 | 
					            border-top: 1px solid #c2c193;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        &.message {
 | 
				
			||||||
 | 
					            box-shadow: none;
 | 
				
			||||||
 | 
					            background-color: #fffff5;
 | 
				
			||||||
 | 
					            color: #fbbd08;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            .ui.text {
 | 
				
			||||||
 | 
					                color: #d2ab00;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        &:last-child,
 | 
				
			||||||
 | 
					        &.bottom {
 | 
				
			||||||
 | 
					            border-bottom: 1px solid #c2c193;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    .ui.attached.isSigned.isVerifiedUnmatched {
 | 
				
			||||||
 | 
					        border-left: 1px solid #c2a893;
 | 
				
			||||||
 | 
					        border-right: 1px solid #c2a893;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        &.top,
 | 
				
			||||||
 | 
					        &.message {
 | 
				
			||||||
 | 
					            border-top: 1px solid #c2a893;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        &.message {
 | 
				
			||||||
 | 
					            box-shadow: none;
 | 
				
			||||||
 | 
					            background-color: #fffaf5;
 | 
				
			||||||
 | 
					            color: #f2711c;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            .ui.text {
 | 
				
			||||||
 | 
					                color: #ee5f00;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        &:last-child,
 | 
				
			||||||
 | 
					        &.bottom {
 | 
				
			||||||
 | 
					            border-bottom: 1px solid #c2a893;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    .ui.segment.sub-menu {
 | 
					    .ui.segment.sub-menu {
 | 
				
			||||||
        padding: 7px;
 | 
					        padding: 7px;
 | 
				
			||||||
        line-height: 0;
 | 
					        line-height: 0;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1136,6 +1136,64 @@ a.ui.labels .label:hover {
 | 
				
			|||||||
    border-left-color: #888;
 | 
					    border-left-color: #888;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.repository .ui.attached.message.isSigned.isVerified {
 | 
				
			||||||
 | 
					    background-color: #394829;
 | 
				
			||||||
 | 
					    color: #9e9e9e;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &.message {
 | 
				
			||||||
 | 
					        color: #87ab63;
 | 
				
			||||||
 | 
					        .ui.text {
 | 
				
			||||||
 | 
					            color: #9e9e9e;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .pull-right {
 | 
				
			||||||
 | 
					            color: #87ab63;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.repository .ui.attached.message.isSigned.isVerifiedUntrusted {
 | 
				
			||||||
 | 
					    background-color: #4a3903;
 | 
				
			||||||
 | 
					    color: #9e9e9e;
 | 
				
			||||||
 | 
					    &.message {
 | 
				
			||||||
 | 
					        color: #c2c193;
 | 
				
			||||||
 | 
					        .ui.text {
 | 
				
			||||||
 | 
					            color: #9e9e9e;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .pull-right,
 | 
				
			||||||
 | 
					        a {
 | 
				
			||||||
 | 
					            color: #c2c193;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.repository .ui.attached.message.isSigned.isVerifiedUnmatched {
 | 
				
			||||||
 | 
					    background-color: #4e3321;
 | 
				
			||||||
 | 
					    color: #9e9e9e;
 | 
				
			||||||
 | 
					    &.message {
 | 
				
			||||||
 | 
					        color: #c2a893;
 | 
				
			||||||
 | 
					        .ui.text {
 | 
				
			||||||
 | 
					            color: #9e9e9e;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .pull-right,
 | 
				
			||||||
 | 
					        a {
 | 
				
			||||||
 | 
					            color: #c2a893;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.repository .ui.attached.message.isSigned.isWarning {
 | 
				
			||||||
 | 
					    background-color: rgba(80, 23, 17, 0.6);
 | 
				
			||||||
 | 
					    &.message {
 | 
				
			||||||
 | 
					        color: #d07d7d;
 | 
				
			||||||
 | 
					        .ui.text {
 | 
				
			||||||
 | 
					            color: #d07d7d;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        .pull-right {
 | 
				
			||||||
 | 
					            color: #9e9e9e;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.repository .label.list .item {
 | 
					.repository .label.list .item {
 | 
				
			||||||
    border-bottom: 1px dashed #4c505c;
 | 
					    border-bottom: 1px dashed #4c505c;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1146,6 +1204,11 @@ a.ui.labels .label:hover {
 | 
				
			|||||||
    color: #87ab63 !important;
 | 
					    color: #87ab63 !important;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.ui.text.yellow,
 | 
				
			||||||
 | 
					.yellow.icon.icon.icon {
 | 
				
			||||||
 | 
					    color: #e4ac07 !important;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.repository .diff-file-box .code-diff-split tbody tr.add-code td:nth-child(1),
 | 
					.repository .diff-file-box .code-diff-split tbody tr.add-code td:nth-child(1),
 | 
				
			||||||
.repository .diff-file-box .code-diff-split tbody tr.add-code td:nth-child(2),
 | 
					.repository .diff-file-box .code-diff-split tbody tr.add-code td:nth-child(2),
 | 
				
			||||||
.repository .diff-file-box .code-diff-split tbody tr.add-code td:nth-child(3),
 | 
					.repository .diff-file-box .code-diff-split tbody tr.add-code td:nth-child(3),
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user