Add golangci #6418

Merged
kolaente merged 119 commits from golanci into master 2019-06-12 19:41:29 +00:00
19 changed files with 437 additions and 12 deletions
Showing only changes of commit bac180a9ff - Show all commits

View File

@ -362,6 +362,17 @@ also set the `resetBytes` to the cached `resetBytes`.
The `colorBytes` and `resetBytes` are not exported to prevent
accidental overwriting of internal values.
## ColorFormat & ColorFormatted
Structs may implement the `log.ColorFormatted` interface by implementing the `ColorFormat(fmt.State)` function.
If a `log.ColorFormatted` struct is logged with `%-v` format, its `ColorFormat` will be used instead of the usual `%v`. The full `fmt.State` will be passed to allow implementers to look at additional flags.
In order to help implementers provide `ColorFormat` methods. There is a
`log.ColorFprintf(...)` function in the log module that will wrap values in `log.ColoredValue` and recognise `%-v`.
In general it is recommended not to make the results of this function too verbose to help increase its versatility. Usually this should simply be an `ID`:`Name`. If you wish to make a more verbose result, it is recommended to use `%-+v` as your marker.
## Log Spoofing protection
In order to protect the logs from being spoofed with cleverly
@ -392,5 +403,5 @@ func newNewoneLogService() {
}
```
You should then add `newOneLogService` to `NewServices()` in
You should then add `newOneLogService` to `NewServices()` in
`modules/setting/setting.go`

View File

@ -1,10 +1,15 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Copyright 2019 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 "fmt"
import (
"fmt"
"code.gitea.io/gitea/modules/log"
)
// AccessMode specifies the users access mode
type AccessMode int
@ -37,6 +42,13 @@ func (mode AccessMode) String() string {
}
}
// ColorFormat provides a ColorFormatted version of this AccessMode
func (mode AccessMode) ColorFormat(s fmt.State) {
log.ColorFprintf(s, "%d:%s",
log.NewColoredIDValue(mode),
mode)
}
// ParseAccessMode returns corresponding access mode to given permission string.
func ParseAccessMode(permission string) AccessMode {
switch permission {

View File

@ -34,6 +34,16 @@ type Team struct {
Units []*TeamUnit `xorm:"-"`
}
// ColorFormat provides a basic color format for a Team
func (t *Team) ColorFormat(s fmt.State) {
log.ColorFprintf(s, "%d:%s (OrgID: %d) %-v",
log.NewColoredIDValue(t.ID),
t.Name,
log.NewColoredIDValue(t.OrgID),
t.Authorize)
}
// GetUnits return a list of available units for a team
func (t *Team) GetUnits() error {
return t.getUnits(x)

View File

@ -17,6 +17,7 @@ import (
"path"
"path/filepath"
"sort"
"strconv"
"strings"
"time"
@ -209,6 +210,24 @@ type Repository struct {
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"`
}
// ColorFormat returns a colored string to represent this repo
func (repo *Repository) ColorFormat(s fmt.State) {
var ownerName interface{}
if repo.OwnerName != "" {
ownerName = repo.OwnerName
} else if repo.Owner != nil {
ownerName = repo.Owner.Name
} else {
ownerName = log.NewColoredIDValue(strconv.FormatInt(repo.OwnerID, 10))
}
log.ColorFprintf(s, "%d:%s/%s",
log.NewColoredIDValue(repo.ID),
ownerName,
repo.Name)
}
// AfterLoad is invoked from XORM after setting the values of all fields of this object.
func (repo *Repository) AfterLoad() {
// FIXME: use models migration to solve all at once.

View File

@ -4,6 +4,12 @@
package models
import (
"fmt"
"code.gitea.io/gitea/modules/log"
)
// Permission contains all the permissions related variables to a repository for a user
type Permission struct {
AccessMode AccessMode
@ -90,12 +96,67 @@ func (p *Permission) CanWriteIssuesOrPulls(isPull bool) bool {
return p.CanWrite(UnitTypeIssues)
}
// ColorFormat writes a colored string for these Permissions
func (p *Permission) ColorFormat(s fmt.State) {
noColor := log.ColorBytes(log.Reset)
format := "AccessMode: %-v, %d Units, %d UnitsMode(s): [ "
args := []interface{}{
p.AccessMode,
log.NewColoredValueBytes(len(p.Units), &noColor),
log.NewColoredValueBytes(len(p.UnitsMode), &noColor),
}
if s.Flag('+') {
for i, unit := range p.Units {
config := ""
if unit.Config != nil {
configBytes, err := unit.Config.ToDB()
config = string(configBytes)
if err != nil {
config = string(err.Error())
}
}
format += "\nUnits[%d]: ID: %d RepoID: %d Type: %-v Config: %s"
args = append(args,
log.NewColoredValueBytes(i, &noColor),
log.NewColoredIDValue(unit.ID),
log.NewColoredIDValue(unit.RepoID),
unit.Type,
config)
}
for key, value := range p.UnitsMode {
format += "\nUnitMode[%-v]: %-v"
args = append(args,
key,
value)
}
} else {
format += "..."
}
format += " ]"
log.ColorFprintf(s, format, args...)
}
// GetUserRepoPermission returns the user permissions to the repository
func GetUserRepoPermission(repo *Repository, user *User) (Permission, error) {
return getUserRepoPermission(x, repo, user)
}
func getUserRepoPermission(e Engine, repo *Repository, user *User) (perm Permission, err error) {
if log.IsTrace() {
defer func() {
if user == nil {
log.Trace("Permission Loaded for anonymous user in %-v:\nPermissions: %-+v",
repo,
perm)
return
}
log.Trace("Permission Loaded for %-v in %-v:\nPermissions: %-+v",
user,
repo,
perm)
}()
}
// anonymous user visit private repo.
// TODO: anonymous user visit public unit of private repo???
if user == nil && repo.IsPrivate {

View File

@ -5,7 +5,10 @@
package models
import (
"fmt"
"strings"
"code.gitea.io/gitea/modules/log"
)
// UnitType is Unit's Type
@ -22,6 +25,33 @@ const (
UnitTypeExternalTracker // 7 ExternalTracker
)
func (u UnitType) String() string {
switch u {
case UnitTypeCode:
return "UnitTypeCode"
case UnitTypeIssues:
return "UnitTypeIssues"
case UnitTypePullRequests:
return "UnitTypePullRequests"
case UnitTypeReleases:
return "UnitTypeReleases"
case UnitTypeWiki:
return "UnitTypeWiki"
case UnitTypeExternalWiki:
return "UnitTypeExternalWiki"
case UnitTypeExternalTracker:
return "UnitTypeExternalTracker"
}
return fmt.Sprintf("Unknown UnitType %d", u)
}
// ColorFormat provides a ColorFormatted version of this UnitType
func (u UnitType) ColorFormat(s fmt.State) {
log.ColorFprintf(s, "%d:%s",
log.NewColoredIDValue(u),
u)
}
var (
// allRepUnitTypes contains all the unit types
allRepUnitTypes = []UnitType{

View File

@ -146,6 +146,13 @@ type User struct {
Theme string `xorm:"NOT NULL DEFAULT ''"`
}
// ColorFormat writes a colored string to identify this struct
func (u *User) ColorFormat(s fmt.State) {
log.ColorFprintf(s, "%d:%s",
log.NewColoredIDValue(u.ID),
log.NewColoredValue(u.Name))
}
// BeforeUpdate is invoked from XORM before updating this object.
func (u *User) BeforeUpdate() {
if u.MaxRepoCreation < -1 {

View File

@ -6,6 +6,8 @@ package context
import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/log"
macaron "gopkg.in/macaron.v1"
)
@ -45,6 +47,22 @@ func RequireRepoWriterOr(unitTypes ...models.UnitType) macaron.Handler {
func RequireRepoReader(unitType models.UnitType) macaron.Handler {
return func(ctx *Context) {
if !ctx.Repo.CanRead(unitType) {
if log.IsTrace() {
if ctx.IsSigned {
log.Trace("Permission Denied: User %-v cannot read %-v in Repo %-v\n"+
"User in Repo has Permissions: %-+v",
ctx.User,
unitType,
ctx.Repo.Repository,
ctx.Repo.Permission)
} else {
log.Trace("Permission Denied: Anonymous user cannot read %-v in Repo %-v\n"+
"Anonymous user in Repo has Permissions: %-+v",
unitType,
ctx.Repo.Repository,
ctx.Repo.Permission)
}
}
ctx.NotFound(ctx.Req.RequestURI, nil)
return
}
@ -59,6 +77,25 @@ func RequireRepoReaderOr(unitTypes ...models.UnitType) macaron.Handler {
return
}
}
if log.IsTrace() {
var format string
var args []interface{}
if ctx.IsSigned {
format = "Permission Denied: User %-v cannot read ["
args = append(args, ctx.User)
} else {
format = "Permission Denied: Anonymous user cannot read ["
}
for _, unit := range unitTypes {
format += "%-v, "
args = append(args, unit)
}
format = format[:len(format)-2] + "] in Repo %-v\n" +
"User in Repo has Permissions: %-+v"
args = append(args, ctx.Repo.Repository, ctx.Repo.Permission)
log.Trace(format, args...)
}
ctx.NotFound(ctx.Req.RequestURI, nil)
}
}

View File

@ -7,6 +7,7 @@ package log
import (
"fmt"
"io"
"reflect"
"strconv"
"strings"
)
@ -195,11 +196,12 @@ normalLoop:
lasti := i
if c.mode == escapeAll {
for i < end && (bytes[i] >= ' ' || bytes[i] == '\n') {
for i < end && (bytes[i] >= ' ' || bytes[i] == '\n' || bytes[i] == '\t') {
i++
}
} else {
for i < end && bytes[i] >= ' ' {
// Allow tabs if we're not escaping everything
for i < end && (bytes[i] >= ' ' || bytes[i] == '\t') {
i++
}
}
@ -266,6 +268,39 @@ normalLoop:
return totalWritten, nil
}
// ColorSprintf returns a colored string from a format and arguments
// arguments will be wrapped in ColoredValues to protect against color spoofing
func ColorSprintf(format string, args ...interface{}) string {
if len(args) > 0 {
v := make([]interface{}, len(args))
for i := 0; i < len(v); i++ {
v[i] = NewColoredValuePointer(&args[i])
}
return fmt.Sprintf(format, v...)
}
return fmt.Sprintf(format)
}
// ColorFprintf will write to the provided writer similar to ColorSprintf
func ColorFprintf(w io.Writer, format string, args ...interface{}) (int, error) {
if len(args) > 0 {
v := make([]interface{}, len(args))
for i := 0; i < len(v); i++ {
v[i] = NewColoredValuePointer(&args[i])
Review

It seems this change is unnecessary.

It seems this change is unnecessary.
kolaente commented 2019-06-10 18:46:49 +00:00 (Migrated from github.com)
Review

Kind of, fmt.Fprintf(w, format) would not print anything IIRC since there is no format string. fmt.Fprintf(w, "%s", format) adds this format string. But since all this is doing is returning the error, I adjusted it to just fmt.Fprint(w, format).

Kind of, `fmt.Fprintf(w, format)` would not print anything IIRC since there is no format string. `fmt.Fprintf(w, "%s", format)` adds this format string. But since all this is doing is returning the error, I adjusted it to just `fmt.Fprint(w, format)`.
Review

I don't think fmt.Fprintf(w, format) will not print anything, see https://play.golang.org/p/sjVCTMbTarA

I don't think `fmt.Fprintf(w, format)` will not print anything, see https://play.golang.org/p/sjVCTMbTarA
}
return fmt.Fprintf(w, format, v...)
}
return fmt.Fprintf(w, format)
}
// ColorFormatted structs provide their own colored string when formatted with ColorSprintf
type ColorFormatted interface {
// ColorFormat provides the colored representation of the value
ColorFormat(s fmt.State)
}
var colorFormattedType = reflect.TypeOf((*ColorFormatted)(nil)).Elem()
// ColoredValue will Color the provided value
type ColoredValue struct {
colorBytes *[]byte
@ -316,8 +351,33 @@ func NewColoredValueBytes(value interface{}, colorBytes *[]byte) *ColoredValue {
}
}
// Format will format the provided value and protect against ANSI spoofing within the value
// NewColoredIDValue is a helper function to create a ColoredValue from a Value
// The Value will be colored with FgCyan
// If a ColoredValue is provided it is not changed
func NewColoredIDValue(value interface{}) *ColoredValue {
return NewColoredValueBytes(&value, &fgCyanBytes)
}
// Format will format the provided value and protect against ANSI color spoofing within the value
// If the wrapped value is ColorFormatted and the format is "%-v" then its ColorString will
// be used. It is presumed that this ColorString is safe.
func (cv *ColoredValue) Format(s fmt.State, c rune) {
if c == 'v' && s.Flag('-') {
if val, ok := (*cv.Value).(ColorFormatted); ok {
val.ColorFormat(s)
return
}
v := reflect.ValueOf(*cv.Value)
t := v.Type()
if reflect.PtrTo(t).Implements(colorFormattedType) {
vp := reflect.New(t)
vp.Elem().Set(v)
val := vp.Interface().(ColorFormatted)
val.ColorFormat(s)
return
}
}
s.Write([]byte(*cv.colorBytes))
fmt.Fprintf(&protectedANSIWriter{w: s}, fmtString(s, c), *(cv.Value))
s.Write([]byte(*cv.resetBytes))

View File

@ -69,11 +69,7 @@ func (l *Logger) Log(skip int, level Level, format string, v ...interface{}) err
}
msg := format
if len(v) > 0 {
args := make([]interface{}, len(v))
for i := 0; i < len(args); i++ {
args[i] = NewColoredValuePointer(&v[i])
}
msg = fmt.Sprintf(format, args...)
msg = ColorSprintf(format, v...)
}
stack := ""
if l.GetStacktraceLevel() <= level {

View File

@ -206,6 +206,7 @@ sign_up_successful=Konto wurde erfolgreich erstellt.
confirmation_mail_sent_prompt=Eine neue Bestätigungs-E-Mail wurde an <b>%s</b> gesendet. Bitte überprüfe dein Postfach innerhalb der nächsten %s, um die Registrierung abzuschließen.
must_change_password=Aktualisiere dein Passwort
allow_password_change=Verlange vom Benutzer das Passwort zu ändern (empfohlen)
reset_password_mail_sent_prompt=Eine Bestätigungs-E-Mail wurde an<b>%s</b> gesendet. Bitte überprüfe dein Postfach innerhalb von %s um den Wiederherstellungsprozess abzuschließen.
active_your_account=Aktiviere dein Konto
account_activated=Konto wurde aktiviert
prohibit_login=Anmelden verboten
@ -214,7 +215,11 @@ resent_limit_prompt=Du hast bereits eine Aktivierungs-E-Mail angefordert. Bitte
has_unconfirmed_mail=Hallo %s, du hast eine unbestätigte E-Mail-Adresse (<b>%s</b>). Wenn du keine Bestätigungs-E-Mail erhalten hast oder eine neue senden möchtest, klicke bitte auf den folgenden Button.
resend_mail=Aktivierungs-E-Mail erneut verschicken
email_not_associate=Diese E-Mail-Adresse ist mit keinem Konto verknüpft.
send_reset_mail=Wiederherstellungs-E-Mail senden
reset_password=Kontowiederherstellung
invalid_code=Dein Bestätigungs-Code ist ungültig oder abgelaufen.
reset_password_helper=Konto wiederherstellen
reset_password_wrong_user=Du bist angemeldet als %s, aber der Link zur Kontowiederherstellung ist für %s
password_too_short=Das Passwort muss mindestens %d Zeichen lang sein.
non_local_account=Benutzer, die nicht von Gitea verwaltet werden können ihre Passwörter nicht über das Web Interface ändern.
verify=Verifizieren
@ -237,6 +242,7 @@ openid_connect_desc=Die gewählte OpenID-URI ist unbekannt. Ordne sie hier einem
openid_register_title=Neues Konto einrichten
openid_register_desc=Die gewählte OpenID-URI ist unbekannt. Ordne sie hier einem neuen Account zu.
openid_signin_desc=Gib deine OpenID-URI ein. Zum Beispiel: https://anne.me, bob.openid.org.cn oder gnusocial.net/carry.
disable_forgot_password_mail=Die Kontowiederherstellung ist deaktiviert. Bitte wende dich an den Administrator.
email_domain_blacklisted=Du kannst dich nicht mit deiner E-Mail-Adresse registrieren.
authorize_application=Anwendung autorisieren
authroize_redirect_notice=Wenn du diese Anwendung autorisierst, wirst du zu %s weitergeleitet.
@ -249,6 +255,7 @@ authorization_failed_desc=Die Autorisierung ist fehlgeschlagen, da wir eine ung
[mail]
activate_account=Bitte aktiviere dein Konto
activate_email=Bestätige deine E-Mail-Adresse
reset_password=Stelle dein Konto wieder her
register_success=Registrierung erfolgreich
register_notify=Willkommen bei Gitea
@ -643,6 +650,8 @@ video_not_supported_in_browser=Dein Browser unterstützt das HTML5 'video'-Tag n
audio_not_supported_in_browser=Dein Browser unterstützt den HTML5 'audio'-Tag nicht.
stored_lfs=Gespeichert mit Git LFS
commit_graph=Commit graph
blame=Blame
normal_view=Normale Ansicht
editor.new_file=Neue Datei
editor.upload_file=Datei hochladen
@ -678,6 +687,7 @@ editor.directory_is_a_file=Der Verzeichnisname „%s“ wird bereits als Dateina
editor.file_is_a_symlink='%s' ist ein symbolischer Link. Symbolische Links können mit dem Web Editor nicht bearbeitet werden
editor.filename_is_a_directory=Der Dateiname „%s“ wird bereits als Verzeichnisname in diesem Repository verwendet.
editor.file_editing_no_longer_exists=Die bearbeitete Datei „%s“ existiert nicht mehr in diesem Repository.
editor.file_deleting_no_longer_exists=Die Datei '%s' existiert in diesem Repository nicht mehr.
editor.file_changed_while_editing=Der Inhalt der Datei hat sich seit dem Beginn der Bearbeitung geändert. <a target="_blank" rel="noopener noreferrer" href="%s">Hier klicken</a>, um die Änderungen anzusehen, oder <strong>Änderungen erneut comitten</strong>, um sie zu überschreiben.
editor.file_already_exists=Eine Datei mit dem Namen „%s“ ist bereits in diesem Repository vorhanden.
editor.no_changes_to_show=Keine Änderungen vorhanden.
@ -933,6 +943,7 @@ pulls.tab_conversation=Diskussion
pulls.tab_commits=Commits
pulls.tab_files=Geänderte Dateien
pulls.reopen_to_merge=Bitte diesen Pull-Request wieder öffnen, um die Merge-Operation auszuführen.
pulls.cant_reopen_deleted_branch=Dieser Pull-Request kann nicht wieder geöffnet werden, da die Branche bereits gelöscht wurde.
pulls.merged=Zusammengeführt
pulls.has_merged=Der Pull-Request wurde zusammengeführt.
pulls.title_wip_desc=`<a href="#">Beginne den Titel mit <strong>%s</strong></a> um zu verhindern, dass der Pull Request versehentlich zusammengeführt wird.`
@ -1202,6 +1213,8 @@ settings.slack_domain=Domain
settings.slack_channel=Kanal
settings.add_discord_hook_desc=<a href="%s">Discord</a>-Integration zu deinem Repository hinzufügen.
settings.add_dingtalk_hook_desc=<a href="%s">Dingtalk</a>-Integration zu deinem Repository hinzufügen.
settings.add_telegram_hook_desc=<a href="%s">Telegram</a>-Integration zu deinem Repository hinzufügen.
settings.add_msteams_hook_desc=<a href="%s">"Microsoft Teams"</a>-Integration zu deinem Repository hinzufügen.
settings.deploy_keys=Deploy-Schlüssel
settings.add_deploy_key=Deploy-Schlüssel hinzufügen
settings.deploy_key_desc=Deploy-Keys haben nur Lesezugriff auf das Repository.
@ -1249,6 +1262,8 @@ settings.choose_branch=Wähle einen Branch …
settings.no_protected_branch=Es gibt keine geschützten Branches.
settings.edit_protected_branch=Bearbeiten
settings.protected_branch_required_approvals_min=Die Anzahl der erforderlichen Zustimmungen darf nicht negativ sein.
settings.bot_token=Bot-Token
settings.chat_id=Chat-ID
settings.archive.button=Repo archivieren
settings.archive.header=Dieses Repo archivieren
settings.archive.text=Durch die Archivierung des Repos wird es vollständig schreibgeschützt. Es wird auf dem Dashboard versteckt, nimmt keine Commits an und es können keine Issues oder Pull-Requests erstellt werden.
@ -1684,6 +1699,7 @@ config.mail_notify=E-Mail-Benachrichtigungen aktivieren
config.disable_key_size_check=Prüfung der Mindestschlüssellänge deaktiveren
config.enable_captcha=CAPTCHA aktivieren
config.active_code_lives=Aktivierungscode-Lebensdauer
config.reset_password_code_lives=Kontowiederherstellungs-Code Ablaufzeit
config.default_keep_email_private=E-Mail-Adressen standardmäßig verbergen
config.default_allow_create_organization=Erstellen von Organisationen standardmäßig erlauben
config.enable_timetracking=Zeiterfassung aktivieren

View File

@ -650,6 +650,8 @@ video_not_supported_in_browser=Seu navegador não suporta a tag 'video' do HTML5
audio_not_supported_in_browser=Seu navegador não suporta a tag 'audio' do HTML5.
stored_lfs=Armazenado com Git LFS
commit_graph=Gráfico de commits
blame=Anotar
normal_view=Visão normal
editor.new_file=Novo arquivo
editor.upload_file=Enviar arquivo
@ -941,6 +943,7 @@ pulls.tab_conversation=Conversação
pulls.tab_commits=Commits
pulls.tab_files=Arquivos alterados
pulls.reopen_to_merge=Por favor reabra este pull request para aplicar o merge.
pulls.cant_reopen_deleted_branch=Este pull request não pode ser reaberto porque o branch foi excluído.
pulls.merged=Merge aplicado
pulls.has_merged=O merge deste pull request foi aplicado.
pulls.title_wip_desc=`<a href="#">Inicie o título com o prefixo <strong>%s</strong></a> para prevenir o merge do pull request até que o mesmo esteja pronto.`

View File

@ -369,6 +369,22 @@ func orgAssignment(args ...bool) macaron.Handler {
func mustEnableIssues(ctx *context.APIContext) {
if !ctx.Repo.CanRead(models.UnitTypeIssues) {
if log.IsTrace() {
if ctx.IsSigned {
log.Trace("Permission Denied: User %-v cannot read %-v in Repo %-v\n"+
"User in Repo has Permissions: %-+v",
ctx.User,
models.UnitTypeIssues,
ctx.Repo.Repository,
ctx.Repo.Permission)
} else {
log.Trace("Permission Denied: Anonymous user cannot read %-v in Repo %-v\n"+
"Anonymous user in Repo has Permissions: %-+v",
models.UnitTypeIssues,
ctx.Repo.Repository,
ctx.Repo.Permission)
}
}
ctx.NotFound()
return
}
@ -376,6 +392,22 @@ func mustEnableIssues(ctx *context.APIContext) {
func mustAllowPulls(ctx *context.APIContext) {
if !(ctx.Repo.Repository.CanEnablePulls() && ctx.Repo.CanRead(models.UnitTypePullRequests)) {
if ctx.Repo.Repository.CanEnablePulls() && log.IsTrace() {
if ctx.IsSigned {
log.Trace("Permission Denied: User %-v cannot read %-v in Repo %-v\n"+
"User in Repo has Permissions: %-+v",
ctx.User,
models.UnitTypePullRequests,
ctx.Repo.Repository,
ctx.Repo.Permission)
} else {
log.Trace("Permission Denied: Anonymous user cannot read %-v in Repo %-v\n"+
"Anonymous user in Repo has Permissions: %-+v",
models.UnitTypePullRequests,
ctx.Repo.Repository,
ctx.Repo.Permission)
}
}
ctx.NotFound()
return
}
@ -384,6 +416,24 @@ func mustAllowPulls(ctx *context.APIContext) {
func mustEnableIssuesOrPulls(ctx *context.APIContext) {
if !ctx.Repo.CanRead(models.UnitTypeIssues) &&
!(ctx.Repo.Repository.CanEnablePulls() && ctx.Repo.CanRead(models.UnitTypePullRequests)) {
if ctx.Repo.Repository.CanEnablePulls() && log.IsTrace() {
if ctx.IsSigned {
log.Trace("Permission Denied: User %-v cannot read %-v and %-v in Repo %-v\n"+
"User in Repo has Permissions: %-+v",
ctx.User,
models.UnitTypeIssues,
models.UnitTypePullRequests,
ctx.Repo.Repository,
ctx.Repo.Permission)
} else {
log.Trace("Permission Denied: Anonymous user cannot read %-v and %-v in Repo %-v\n"+
"Anonymous user in Repo has Permissions: %-+v",
models.UnitTypeIssues,
models.UnitTypePullRequests,
ctx.Repo.Repository,
ctx.Repo.Permission)
}
}
ctx.NotFound()
return
}

View File

@ -680,7 +680,12 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption)
return nil, nil, nil, nil, "", ""
}
if !perm.CanReadIssuesOrPulls(true) {
log.Trace("ParseCompareInfo[%d]: cannot create/read pull requests", baseRepo.ID)
if log.IsTrace() {
log.Trace("Permission Denied: User %-v cannot create/read pull requests in Repo %-v\nUser in headRepo has Permissions: %-+v",
ctx.User,
headRepo,
perm)
}
ctx.NotFound()
return nil, nil, nil, nil, "", ""
}

View File

@ -1171,6 +1171,24 @@ func NewComment(ctx *context.Context, form auth.CreateCommentForm) {
}
if !ctx.IsSigned || (ctx.User.ID != issue.PosterID && !ctx.Repo.CanReadIssuesOrPulls(issue.IsPull)) {
if log.IsTrace() {
if ctx.IsSigned {
issueType := "issues"
if issue.IsPull {
issueType = "pulls"
}
log.Trace("Permission Denied: User %-v not the Poster (ID: %d) and cannot read %s in Repo %-v.\n"+
"User in Repo has Permissions: %-+v",
ctx.User,
log.NewColoredIDValue(issue.PosterID),
issueType,
ctx.Repo.Repository,
ctx.Repo.Permission)
} else {
log.Trace("Permission Denied: Not logged in")
}
}
ctx.Error(403)
}
@ -1362,6 +1380,24 @@ func ChangeIssueReaction(ctx *context.Context, form auth.ReactionForm) {
}
if !ctx.IsSigned || (ctx.User.ID != issue.PosterID && !ctx.Repo.CanReadIssuesOrPulls(issue.IsPull)) {
if log.IsTrace() {
if ctx.IsSigned {
issueType := "issues"
if issue.IsPull {
issueType = "pulls"
}
log.Trace("Permission Denied: User %-v not the Poster (ID: %d) and cannot read %s in Repo %-v.\n"+
"User in Repo has Permissions: %-+v",
ctx.User,
log.NewColoredIDValue(issue.PosterID),
issueType,
ctx.Repo.Repository,
ctx.Repo.Permission)
} else {
log.Trace("Permission Denied: Not logged in")
}
}
ctx.Error(403)
return
}
@ -1441,6 +1477,24 @@ func ChangeCommentReaction(ctx *context.Context, form auth.ReactionForm) {
}
if !ctx.IsSigned || (ctx.User.ID != comment.PosterID && !ctx.Repo.CanReadIssuesOrPulls(comment.Issue.IsPull)) {
if log.IsTrace() {
if ctx.IsSigned {
issueType := "issues"
if comment.Issue.IsPull {
issueType = "pulls"
}
log.Trace("Permission Denied: User %-v not the Poster (ID: %d) and cannot read %s in Repo %-v.\n"+
"User in Repo has Permissions: %-+v",
ctx.User,
log.NewColoredIDValue(comment.Issue.PosterID),
issueType,
ctx.Repo.Repository,
ctx.Repo.Permission)
} else {
log.Trace("Permission Denied: Not logged in")
}
}
ctx.Error(403)
return
} else if comment.Type != models.CommentTypeComment && comment.Type != models.CommentTypeCode {

View File

@ -11,6 +11,7 @@ import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
)
// IssueWatch sets issue watching
@ -21,6 +22,23 @@ func IssueWatch(ctx *context.Context) {
}
if !ctx.IsSigned || (ctx.User.ID != issue.PosterID && !ctx.Repo.CanReadIssuesOrPulls(issue.IsPull)) {
if log.IsTrace() {
if ctx.IsSigned {
issueType := "issues"
if issue.IsPull {
issueType = "pulls"
}
log.Trace("Permission Denied: User %-v not the Poster (ID: %d) and cannot read %s in Repo %-v.\n"+
"User in Repo has Permissions: %-+v",
ctx.User,
log.NewColoredIDValue(issue.PosterID),
issueType,
ctx.Repo.Repository,
ctx.Repo.Permission)
} else {
log.Trace("Permission Denied: Not logged in")
}
}
ctx.Error(403)
return
}

View File

@ -64,6 +64,18 @@ func getForkRepository(ctx *context.Context) *models.Repository {
}
if forkRepo.IsEmpty || !perm.CanRead(models.UnitTypeCode) {
if log.IsTrace() {
if forkRepo.IsEmpty {
log.Trace("Empty fork repository %-v", forkRepo)
} else {
log.Trace("Permission Denied: User %-v cannot read %-v of forkRepo %-v\n"+
"User in forkRepo has Permissions: %-+v",
ctx.User,
models.UnitTypeCode,
ctx.Repo,
perm)
}
}
ctx.NotFound("getForkRepository", nil)
return nil
}
@ -704,7 +716,12 @@ func ParseCompareInfo(ctx *context.Context) (*models.User, *models.Repository, *
return nil, nil, nil, nil, "", ""
}
if !perm.CanReadIssuesOrPulls(true) {
log.Trace("ParseCompareInfo[%d]: cannot create/read pull requests", baseRepo.ID)
if log.IsTrace() {
log.Trace("Permission Denied: User: %-v cannot create/read pull requests in Repo: %-v\nUser in headRepo has Permissions: %-+v",
ctx.User,
headRepo,
perm)
}
ctx.NotFound("ParseCompareInfo", nil)
return nil, nil, nil, nil, "", ""
}

View File

@ -16,6 +16,7 @@ import (
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/markup/markdown"
"code.gitea.io/gitea/modules/util"
@ -32,6 +33,15 @@ const (
func MustEnableWiki(ctx *context.Context) {
if !ctx.Repo.CanRead(models.UnitTypeWiki) &&
!ctx.Repo.CanRead(models.UnitTypeExternalWiki) {
if log.IsTrace() {
log.Trace("Permission Denied: User %-v cannot read %-v or %-v of repo %-v\n"+
"User in repo has Permissions: %-+v",
ctx.User,
models.UnitTypeWiki,
models.UnitTypeExternalWiki,
ctx.Repo.Repository,
ctx.Repo.Permission)
}
ctx.NotFound("MustEnableWiki", nil)
return
}

View File

@ -14,6 +14,7 @@ import (
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
@ -308,6 +309,14 @@ func Issues(ctx *context.Context) {
return
}
if !perm.CanRead(models.UnitTypeIssues) {
if log.IsTrace() {
log.Trace("Permission Denied: User %-v cannot read %-v of repo %-v\n"+
"User in repo has Permissions: %-+v",
ctxUser,
models.UnitTypeIssues,
repo,
perm)
}
ctx.Status(404)
return
}