| Git LFS 2.0 | ✓ | ✘ | ✓ | ✓ | ✓ | ⁄ | ✓ |
| Group Milestones | ✘ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
| Granular user roles (Code, Issues, Wiki etc) | ✓ | ✘ | ✘ | ✓ | ✓ | ✘ | ✘ |
-| Verified Committer | â\9c\98 | ✘ | ? | ✓ | ✓ | ✓ | ✘ |
+| Verified Committer | â\81\84 | ✘ | ? | ✓ | ✓ | ✓ | ✘ |
| GPG Signed Commits | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Reject unsigned commits | [✘](https://github.com/go-gitea/gitea/issues/2770) | ✘ | ✓ | ✓ | ✓ | ✘ | ✓ |
| Repository Activity page | ✓ | ✘ | ✓ | ✓ | ✓ | ✓ | ✓ |
CommittingUser *User
SigningEmail string
SigningKey *GPGKey
+ TrustStatus string
}
// SignCommit represents a commit with validation of signature.
}
// 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 (
newCommits = list.New()
e = oldCommits.Front()
)
+ memberMap := map[int64]bool{}
+
for e != nil {
c := e.Value.(UserCommit)
- newCommits.PushBack(SignCommit{
+ signCommit := SignCommit{
UserCommit: &c,
Verification: ParseCommitWithSignature(c.Commit),
- })
+ }
+
+ _ = CalculateTrustStatus(signCommit.Verification, repository, &memberMap)
+
+ newCommits.PushBack(signCommit)
e = e.Next()
}
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
+}
func (repo *Repository) GetRepoTeams() ([]*Team, error) {
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})
+}
commits.older = Older
commits.newer = Newer
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
ext_issues = Ext. Issues
return
}
commits = models.ValidateCommitsWithEmails(commits)
- commits = models.ParseCommitsWithSignature(commits)
+ commits = models.ParseCommitsWithSignature(commits, ctx.Repo.Repository)
commits = models.ParseCommitsWithStatus(commits, ctx.Repo.Repository)
ctx.Data["Commits"] = commits
return
}
commits = models.ValidateCommitsWithEmails(commits)
- commits = models.ParseCommitsWithSignature(commits)
+ commits = models.ParseCommitsWithSignature(commits, ctx.Repo.Repository)
commits = models.ParseCommitsWithStatus(commits, ctx.Repo.Repository)
ctx.Data["Commits"] = commits
return
}
commits = models.ValidateCommitsWithEmails(commits)
- commits = models.ParseCommitsWithSignature(commits)
+ commits = models.ParseCommitsWithSignature(commits, ctx.Repo.Repository)
commits = models.ParseCommitsWithStatus(commits, ctx.Repo.Repository)
ctx.Data["Commits"] = commits
setPathsCompareContext(ctx, parentCommit, commit, headTarget)
ctx.Data["Title"] = commit.Summary() + " · " + base.ShortSha(commitID)
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["Diff"] = diff
ctx.Data["Parents"] = parents
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{}
err = git.GetNote(ctx.Repo.GitRepo, commitID, note)
if err == nil {
}
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)
ctx.Data["Commits"] = compareInfo.Commits
ctx.Data["CommitCount"] = compareInfo.Commits.Len()
ctx.Data["Reponame"] = ctx.Repo.Repository.Name
commits = prInfo.Commits
commits = models.ValidateCommitsWithEmails(commits)
- commits = models.ParseCommitsWithSignature(commits)
+ commits = models.ParseCommitsWithSignature(commits, ctx.Repo.Repository)
commits = models.ParseCommitsWithStatus(commits, ctx.Repo.Repository)
ctx.Data["Commits"] = commits
ctx.Data["CommitCount"] = commits.Len()
// Show latest commit info of repository in table header,
// or of directory if not in root directory.
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)
statuses, err := models.GetLatestCommitStatus(ctx.Repo.Repository, ctx.Repo.Commit.ID.String(), 0)
return nil, nil
}
commitsHistory = models.ValidateCommitsWithEmails(commitsHistory)
- commitsHistory = models.ParseCommitsWithSignature(commitsHistory)
+ commitsHistory = models.ParseCommitsWithSignature(commitsHistory, ctx.Repo.Repository)
ctx.Data["Commits"] = commitsHistory
<div class="repository diff">
{{template "repo/header" .}}
<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}}">
{{.i18n.Tr "repo.diff.browse_source"}}
</a>
{{end}}
<span class="text grey"><i class="octicon octicon-git-branch"></i>{{.BranchName}}</span>
</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="nine wide column">
{{if .Author}}
<img class="ui avatar image" src="{{.Author.RelAvatarLink}}" />
{{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}}
- <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}}
{{else}}
<img class="ui avatar image" src="{{AvatarLink .Commit.Author.Email}}" />
<span> </span>
{{if ne .Verification.CommittingUser.ID 0}}
<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}}
<img class="ui avatar image" src="{{AvatarLink .Commit.Committer.Email}}" />
<strong>{{.Commit.Committer.Name}}</strong>
</div><!-- end grid -->
</div>
{{if .Commit.Signature}}
- {{if .Verification.Verified }}
- <div class="ui bottom attached positive message">
+ <div class="ui bottom attached message {{$class}}">
+ {{if .Verification.Verified }}
{{if ne .Verification.SigningUser.ID 0}}
- <i class="green lock icon"></i>
- <span>{{.i18n.Tr "repo.commits.signed_by"}}:</span>
+ <i class="lock icon"></i>
+ {{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}}" />
- <a href="{{.Verification.SigningUser.HomeLink}}"><strong>{{.Verification.SigningUser.Name}}</strong></a> <{{.Verification.SigningEmail}}>
- <span class="pull-right"><span>{{.i18n.Tr "repo.commits.gpg_key_id"}}:</span> {{.Verification.SigningKey.KeyID}}</span>
+ <a href="{{.Verification.SigningUser.HomeLink}}"><strong>{{.Verification.SigningUser.Name}}</strong> <{{.Verification.SigningEmail}}></a>
+ <span class="pull-right"><span class="ui text">{{.i18n.Tr "repo.commits.gpg_key_id"}}:</span> {{.Verification.SigningKey.KeyID}}</span>
{{else}}
<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>
- <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}}" />
<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}}
- </div>
- {{else if .Verification.Warning}}
- <div class="ui bottom attached message">
- <i class="red unlock icon"></i>
- <span class="red text">{{.i18n.Tr .Verification.Reason}}</span>
- <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>
- </div>
- {{else}}
- <div class="ui bottom attached message">
- <i class="grey unlock icon"></i>
+ {{else if .Verification.Warning}}
+ <i class="unlock icon"></i>
+ <span class="ui text">{{.i18n.Tr .Verification.Reason}}</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>
+ {{else}}
+ <i class="unlock icon"></i>
{{.i18n.Tr .Verification.Reason}}
{{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}}
- </div>
- {{end}}
+ {{end}}
+ </div>
{{end}}
{{if .Note}}
<div class="ui top attached info segment message git-notes">
{{if .Signature}}
{{$class = (printf "%s%s" $class " isSigned")}}
{{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}}
{{$class = (printf "%s%s" $class " isWarning")}}
{{end}}
{{else}}
<span class="{{$class}}">
{{end}}
- {{ShortSha .ID.String}}
+ <span class="shortsha">{{ShortSha .ID.String}}</span>
{{if .Signature}}
<div class="ui detail icon button">
{{if .Verification.Verified}}
- {{if ne .Verification.SigningUser.ID 0}}
- <i title="{{.Verification.Reason}}" class="lock green icon"></i>
- {{else}}
- <i title="{{.Verification.Reason}}" class="icons">
- <i class="green lock icon"></i>
- <i class="tiny inverted cog icon centerlock"></i>
- </i>
- {{end}}
- {{else if .Verification.Warning}}
- <i title="{{$.i18n.Tr .Verification.Reason}}" class="red unlock icon"></i>
+ <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}}">
+ {{if ne .Verification.SigningUser.ID 0}}
+ <i class="lock icon"></i>
+ <img class="ui signature avatar image" src="{{.Verification.SigningUser.RelAvatarLink}}" />
+ {{else}}
+ <i title="{{.Verification.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 .Verification.SigningEmail}}" />
+ {{end}}
+ </div>
{{else}}
<i title="{{$.i18n.Tr .Verification.Reason}}" class="unlock icon"></i>
{{end}}
<strong>{{.LatestCommit.Author.Name}}</strong>
{{end}}
{{end}}
- <a rel="nofollow" class="ui sha label {{if .LatestCommit.Signature}} isSigned {{if .LatestCommitVerification.Verified }} isVerified {{end}}{{end}}" href="{{.RepoLink}}/commit/{{.LatestCommit.ID}}">
- {{ShortSha .LatestCommit.ID.String}}
+ <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}}">
+ <span class="shortsha">{{ShortSha .LatestCommit.ID.String}}</span>
+ <div class="ui detail icon button">
{{if .LatestCommit.Signature}}
- <div class="ui detail icon button">
- {{if .LatestCommitVerification.Verified}}
- <i title="{{.LatestCommitVerification.Reason}}" class="lock green icon"></i>
- {{else}}
- <i title="{{$.i18n.Tr .LatestCommitVerification.Reason}}" class="unlock icon"></i>
- {{end}}
- </div>
+ {{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}}">
+ {{if ne .LatestCommitVerification.SigningUser.ID 0}}
+ <i class="lock icon"></i>
+ <img class="ui signature avatar image" src="{{.LatestCommitVerification.SigningUser.RelAvatarLink}}" />
+ {{else}}
+ <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}}
+ </div>
</a>
{{template "repo/commit_status" .LatestCommitStatus}}
{{ $commitLink:= printf "%s/commit/%s" .RepoLink .LatestCommit.ID }}
color: #fbbd08 !important;
}
+ &.orange {
+ color: #f2711c !important;
+ }
+
&.gold {
color: #a1882b !important;
}
background-color: #fbbf09 !important;
}
+ &.orange {
+ background-color: #f2711c !important;
+ }
+
&.gold {
background-color: #a1882b !important;
}
border-color: #fbbd08 !important;
}
+ &.orange {
+ border-color: #f2711c !important;
+ }
+
&.gold {
border-color: #a1882b !important;
}
}
i.icon.centerlock {
- top: 1.5em;
+ top: 1.45em;
}
.ui.label > .detail .icons {
text-align: center;
}
- width: 140px;
+ width: 175px;
}
}
#repo-files-table .sha.label {
border: 1px solid #bbbbbb;
+ .ui.signature.avatar {
+ height: 16px;
+ margin-bottom: 0;
+ width: auto;
+ }
+
.detail.icon {
background: #fafafa;
margin: -6px -10px -4px 0;
- padding: 5px 3px 5px 6px;
+ padding: 5px 4px 5px 6px;
border-left: 1px solid #bbbbbb;
+ border-top: 0;
+ border-right: 0;
+ border-bottom: 0;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
+
+ img {
+ margin-right: 0;
+ }
+
+ > div {
+ display: inline-flex;
+ align-items: center;
+ }
}
&.isSigned.isWarning {
border: 1px solid #db2828;
background: fade(#db2828, 10%);
+ .shortsha {
+ display: inline-block;
+ padding-top: 1px;
+ }
+
.detail.icon {
- border-left: 1px solid fade(#db2828, 50%);
+ border-left: 1px solid #db2828;
+ color: #db2828;
+ }
+
+ &:hover {
+ background: fade(#db2828, 30%) !important;
}
}
border: 1px solid #21ba45;
background: fade(#21ba45, 10%);
+ .shortsha {
+ display: inline-block;
+ padding-top: 1px;
+ }
+
.detail.icon {
border-left: 1px solid #21ba45;
+ color: #21ba45;
}
&:hover {
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 {
}
}
- .ui.attached.isSigned.isVerified {
- &:not(.positive) {
- border-left: 1px solid #a3c293;
- border-right: 1px solid #a3c293;
+ .ui.attached.isSigned.isWarning {
+ border-left: 1px solid #c29393;
+ border-right: 1px solid #c29393;
+
+ &.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;
}
- &: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;
}
}
+ .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 {
padding: 7px;
line-height: 0;
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 {
border-bottom: 1px dashed #4c505c;
}
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(2),
.repository .diff-file-box .code-diff-split tbody tr.add-code td:nth-child(3),