diff --git a/go.mod b/go.mod index 97fa29a8fc2a9..cfee14e8332ec 100644 --- a/go.mod +++ b/go.mod @@ -68,7 +68,7 @@ require ( github.com/mattn/go-isatty v0.0.16 github.com/mattn/go-sqlite3 v1.14.13 github.com/mholt/archiver/v3 v3.5.1 - github.com/microcosm-cc/bluemonday v1.0.19 + github.com/microcosm-cc/bluemonday v1.0.20 github.com/minio/minio-go/v7 v7.0.35 github.com/msteinert/pam v1.0.0 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 @@ -95,7 +95,7 @@ require ( go.jolheiser.com/hcaptcha v0.0.4 go.jolheiser.com/pwn v0.0.3 golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90 - golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b + golang.org/x/net v0.0.0-20220927171203-f486391704dc golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094 golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 golang.org/x/text v0.3.7 diff --git a/go.sum b/go.sum index aca2c4b991c0b..2cdcdb4c733e6 100644 --- a/go.sum +++ b/go.sum @@ -1069,8 +1069,8 @@ github.com/mholt/acmez v1.0.4 h1:N3cE4Pek+dSolbsofIkAYz6H1d3pE+2G0os7QHslf80= github.com/mholt/acmez v1.0.4/go.mod h1:qFGLZ4u+ehWINeJZjzPlsnjJBCPAADWTcIqE/7DAYQY= github.com/mholt/archiver/v3 v3.5.1 h1:rDjOBX9JSF5BvoJGvjqK479aL70qh9DIpZCl+k7Clwo= github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4= -github.com/microcosm-cc/bluemonday v1.0.19 h1:OI7hoF5FY4pFz2VA//RN8TfM0YJ2dJcl4P4APrCWy6c= -github.com/microcosm-cc/bluemonday v1.0.19/go.mod h1:QNzV2UbLK2/53oIIwTOyLUSABMkjZ4tqiyC1g/DyqxE= +github.com/microcosm-cc/bluemonday v1.0.20 h1:flpzsq4KU3QIYAYGV/szUat7H+GPOXR0B2JU5A1Wp8Y= +github.com/microcosm-cc/bluemonday v1.0.20/go.mod h1:yfBmMi8mxvaZut3Yytv+jTXRY8mxyjJ0/kQBTElld50= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= @@ -1710,8 +1710,9 @@ golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220630215102-69896b714898/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b h1:ZmngSVLe/wycRns9MKikG9OWIEjGcGAkacif7oYQaUY= golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20220927171203-f486391704dc h1:FxpXZdoBqT8RjqTy6i1E8nXHhW21wK7ptQ/EPIGxzPQ= +golang.org/x/net v0.0.0-20220927171203-f486391704dc/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= diff --git a/modules/packages/container/metadata.go b/modules/packages/container/metadata.go index 4222cdb30a781..fd38e67859915 100644 --- a/modules/packages/container/metadata.go +++ b/modules/packages/container/metadata.go @@ -95,7 +95,9 @@ func parseOCIImageConfig(r io.Reader) (*Metadata, error) { if i := strings.Index(cmd, "#(nop) "); i != -1 { cmd = strings.TrimSpace(cmd[i+7:]) } - imageLayers = append(imageLayers, cmd) + if cmd != "" { + imageLayers = append(imageLayers, cmd) + } } metadata := &Metadata{ diff --git a/modules/structs/repo.go b/modules/structs/repo.go index d3833105d7269..27e7f4618c677 100644 --- a/modules/structs/repo.go +++ b/modules/structs/repo.go @@ -151,13 +151,13 @@ type EditRepoOption struct { Template *bool `json:"template,omitempty"` // either `true` to enable issues for this repository or `false` to disable them. HasIssues *bool `json:"has_issues,omitempty"` - // set this structure to configure internal issue tracker (requires has_issues) + // set this structure to configure internal issue tracker InternalTracker *InternalTracker `json:"internal_tracker,omitempty"` - // set this structure to use external issue tracker (requires has_issues) + // set this structure to use external issue tracker ExternalTracker *ExternalTracker `json:"external_tracker,omitempty"` // either `true` to enable the wiki for this repository or `false` to disable it. HasWiki *bool `json:"has_wiki,omitempty"` - // set this structure to use external wiki instead of internal (requires has_wiki) + // set this structure to use external wiki instead of internal ExternalWiki *ExternalWiki `json:"external_wiki,omitempty"` // sets the default branch for this repository. DefaultBranch *string `json:"default_branch,omitempty"` @@ -165,25 +165,25 @@ type EditRepoOption struct { HasPullRequests *bool `json:"has_pull_requests,omitempty"` // either `true` to enable project unit, or `false` to disable them. HasProjects *bool `json:"has_projects,omitempty"` - // either `true` to ignore whitespace for conflicts, or `false` to not ignore whitespace. `has_pull_requests` must be `true`. + // either `true` to ignore whitespace for conflicts, or `false` to not ignore whitespace. IgnoreWhitespaceConflicts *bool `json:"ignore_whitespace_conflicts,omitempty"` - // either `true` to allow merging pull requests with a merge commit, or `false` to prevent merging pull requests with merge commits. `has_pull_requests` must be `true`. + // either `true` to allow merging pull requests with a merge commit, or `false` to prevent merging pull requests with merge commits. AllowMerge *bool `json:"allow_merge_commits,omitempty"` - // either `true` to allow rebase-merging pull requests, or `false` to prevent rebase-merging. `has_pull_requests` must be `true`. + // either `true` to allow rebase-merging pull requests, or `false` to prevent rebase-merging. AllowRebase *bool `json:"allow_rebase,omitempty"` - // either `true` to allow rebase with explicit merge commits (--no-ff), or `false` to prevent rebase with explicit merge commits. `has_pull_requests` must be `true`. + // either `true` to allow rebase with explicit merge commits (--no-ff), or `false` to prevent rebase with explicit merge commits. AllowRebaseMerge *bool `json:"allow_rebase_explicit,omitempty"` - // either `true` to allow squash-merging pull requests, or `false` to prevent squash-merging. `has_pull_requests` must be `true`. + // either `true` to allow squash-merging pull requests, or `false` to prevent squash-merging. AllowSquash *bool `json:"allow_squash_merge,omitempty"` - // either `true` to allow mark pr as merged manually, or `false` to prevent it. `has_pull_requests` must be `true`. + // either `true` to allow mark pr as merged manually, or `false` to prevent it. AllowManualMerge *bool `json:"allow_manual_merge,omitempty"` - // either `true` to enable AutodetectManualMerge, or `false` to prevent it. `has_pull_requests` must be `true`, Note: In some special cases, misjudgments can occur. + // either `true` to enable AutodetectManualMerge, or `false` to prevent it. Note: In some special cases, misjudgments can occur. AutodetectManualMerge *bool `json:"autodetect_manual_merge,omitempty"` - // either `true` to allow updating pull request branch by rebase, or `false` to prevent it. `has_pull_requests` must be `true`. + // either `true` to allow updating pull request branch by rebase, or `false` to prevent it. AllowRebaseUpdate *bool `json:"allow_rebase_update,omitempty"` // set to `true` to delete pr branch after merge by default DefaultDeleteBranchAfterMerge *bool `json:"default_delete_branch_after_merge,omitempty"` - // set to a merge style to be used by this repository: "merge", "rebase", "rebase-merge", or "squash". `has_pull_requests` must be `true`. + // set to a merge style to be used by this repository: "merge", "rebase", "rebase-merge", or "squash". DefaultMergeStyle *string `json:"default_merge_style,omitempty"` // set to `true` to archive this repository. Archived *bool `json:"archived,omitempty"` diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index b62395e546314..991ebf344f82b 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -1898,6 +1898,7 @@ settings.confirm_delete = Delete Repository settings.add_collaborator = Add Collaborator settings.add_collaborator_success = The collaborator has been added. settings.add_collaborator_inactive_user = Can not add an inactive user as a collaborator. +settings.add_collaborator_owner = Can not add an owner as a collaborator. settings.add_collaborator_duplicate = The collaborator is already added to this repository. settings.delete_collaborator = Remove settings.collaborator_deletion = Remove Collaborator diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index 6f40bb3e428b3..319c4c781a9cb 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -732,8 +732,13 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error { var units []repo_model.RepoUnit var deleteUnitTypes []unit_model.Type + currHasIssues := repo.UnitEnabledCtx(ctx, unit_model.TypeIssues) + newHasIssues := currHasIssues if opts.HasIssues != nil { - if *opts.HasIssues && opts.ExternalTracker != nil && !unit_model.TypeExternalTracker.UnitGlobalDisabled() { + newHasIssues = *opts.HasIssues + } + if currHasIssues || newHasIssues { + if newHasIssues && opts.ExternalTracker != nil && !unit_model.TypeExternalTracker.UnitGlobalDisabled() { // Check that values are valid if !validation.IsValidExternalURL(opts.ExternalTracker.ExternalTrackerURL) { err := fmt.Errorf("External tracker URL not valid") @@ -756,7 +761,7 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error { }, }) deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeIssues) - } else if *opts.HasIssues && opts.ExternalTracker == nil && !unit_model.TypeIssues.UnitGlobalDisabled() { + } else if newHasIssues && opts.ExternalTracker == nil && !unit_model.TypeIssues.UnitGlobalDisabled() { // Default to built-in tracker var config *repo_model.IssuesConfig @@ -783,7 +788,7 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error { Config: config, }) deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeExternalTracker) - } else if !*opts.HasIssues { + } else if !newHasIssues { if !unit_model.TypeExternalTracker.UnitGlobalDisabled() { deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeExternalTracker) } @@ -793,8 +798,13 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error { } } + currHasWiki := repo.UnitEnabledCtx(ctx, unit_model.TypeWiki) + newHasWiki := currHasWiki if opts.HasWiki != nil { - if *opts.HasWiki && opts.ExternalWiki != nil && !unit_model.TypeExternalWiki.UnitGlobalDisabled() { + newHasWiki = *opts.HasWiki + } + if currHasWiki || newHasWiki { + if newHasWiki && opts.ExternalWiki != nil && !unit_model.TypeExternalWiki.UnitGlobalDisabled() { // Check that values are valid if !validation.IsValidExternalURL(opts.ExternalWiki.ExternalWikiURL) { err := fmt.Errorf("External wiki URL not valid") @@ -810,7 +820,7 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error { }, }) deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeWiki) - } else if *opts.HasWiki && opts.ExternalWiki == nil && !unit_model.TypeWiki.UnitGlobalDisabled() { + } else if newHasWiki && opts.ExternalWiki == nil && !unit_model.TypeWiki.UnitGlobalDisabled() { config := &repo_model.UnitConfig{} units = append(units, repo_model.RepoUnit{ RepoID: repo.ID, @@ -818,7 +828,7 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error { Config: config, }) deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeExternalWiki) - } else if !*opts.HasWiki { + } else if !newHasWiki { if !unit_model.TypeExternalWiki.UnitGlobalDisabled() { deleteUnitTypes = append(deleteUnitTypes, unit_model.TypeExternalWiki) } @@ -828,8 +838,13 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error { } } + currHasPullRequests := repo.UnitEnabledCtx(ctx, unit_model.TypePullRequests) + newHasPullRequests := currHasPullRequests if opts.HasPullRequests != nil { - if *opts.HasPullRequests && !unit_model.TypePullRequests.UnitGlobalDisabled() { + newHasPullRequests = *opts.HasPullRequests + } + if currHasPullRequests || newHasPullRequests { + if newHasPullRequests && !unit_model.TypePullRequests.UnitGlobalDisabled() { // We do allow setting individual PR settings through the API, so // we get the config settings and then set them // if those settings were provided in the opts. @@ -889,7 +904,7 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error { Type: unit_model.TypePullRequests, Config: config, }) - } else if !*opts.HasPullRequests && !unit_model.TypePullRequests.UnitGlobalDisabled() { + } else if !newHasPullRequests && !unit_model.TypePullRequests.UnitGlobalDisabled() { deleteUnitTypes = append(deleteUnitTypes, unit_model.TypePullRequests) } } diff --git a/routers/web/repo/setting.go b/routers/web/repo/setting.go index 267940c8d2e04..e7abec0d3e895 100644 --- a/routers/web/repo/setting.go +++ b/routers/web/repo/setting.go @@ -917,6 +917,19 @@ func CollaborationPost(ctx *context.Context) { return } + // find the owner team of the organization the repo belongs too and + // check if the user we're trying to add is an owner. + if ctx.Repo.Repository.Owner.IsOrganization() { + if isOwner, err := organization.IsOrganizationOwner(ctx, ctx.Repo.Repository.Owner.ID, u.ID); err != nil { + ctx.ServerError("IsOrganizationOwner", err) + return + } else if isOwner { + ctx.Flash.Error(ctx.Tr("repo.settings.add_collaborator_owner")) + ctx.Redirect(setting.AppSubURL + ctx.Req.URL.EscapedPath()) + return + } + } + if err = repo_module.AddCollaborator(ctx.Repo.Repository, u); err != nil { ctx.ServerError("AddCollaborator", err) return diff --git a/services/auth/reverseproxy.go b/services/auth/reverseproxy.go index d9d1b63e8fea3..8dec1c8ea778f 100644 --- a/services/auth/reverseproxy.go +++ b/services/auth/reverseproxy.go @@ -37,11 +37,7 @@ type ReverseProxy struct{} // getUserName extracts the username from the "setting.ReverseProxyAuthUser" header func (r *ReverseProxy) getUserName(req *http.Request) string { - webAuthUser := strings.TrimSpace(req.Header.Get(setting.ReverseProxyAuthUser)) - if len(webAuthUser) == 0 { - return "" - } - return webAuthUser + return strings.TrimSpace(req.Header.Get(setting.ReverseProxyAuthUser)) } // Name represents the name of auth method @@ -49,14 +45,14 @@ func (r *ReverseProxy) Name() string { return ReverseProxyMethodName } -// Verify extracts the username from the "setting.ReverseProxyAuthUser" header +// getUserFromAuthUser extracts the username from the "setting.ReverseProxyAuthUser" header // of the request and returns the corresponding user object for that name. // Verification of header data is not performed as it should have already been done by -// the revese proxy. +// the reverse proxy. // If a username is available in the "setting.ReverseProxyAuthUser" header an existing // user object is returned (populated with username or email found in header). // Returns nil if header is empty. -func (r *ReverseProxy) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) *user_model.User { +func (r *ReverseProxy) getUserFromAuthUser(req *http.Request) *user_model.User { username := r.getUserName(req) if len(username) == 0 { return nil @@ -71,6 +67,54 @@ func (r *ReverseProxy) Verify(req *http.Request, w http.ResponseWriter, store Da } user = r.newUser(req) } + return user +} + +// getEmail extracts the email from the "setting.ReverseProxyAuthEmail" header +func (r *ReverseProxy) getEmail(req *http.Request) string { + return strings.TrimSpace(req.Header.Get(setting.ReverseProxyAuthEmail)) +} + +// getUserFromAuthEmail extracts the username from the "setting.ReverseProxyAuthEmail" header +// of the request and returns the corresponding user object for that email. +// Verification of header data is not performed as it should have already been done by +// the reverse proxy. +// If an email is available in the "setting.ReverseProxyAuthEmail" header an existing +// user object is returned (populated with the email found in header). +// Returns nil if header is empty or if "setting.EnableReverseProxyEmail" is disabled. +func (r *ReverseProxy) getUserFromAuthEmail(req *http.Request) *user_model.User { + if !setting.Service.EnableReverseProxyEmail { + return nil + } + email := r.getEmail(req) + if len(email) == 0 { + return nil + } + log.Trace("ReverseProxy Authorization: Found email: %s", email) + + user, err := user_model.GetUserByEmail(email) + if err != nil { + // Do not allow auto-registration, we don't have a username here + if !user_model.IsErrUserNotExist(err) { + log.Error("GetUserByEmail: %v", err) + } + return nil + } + return user +} + +// Verify attempts to load a user object based on headers sent by the reverse proxy. +// First it will attempt to load it based on the username (see docs for getUserFromAuthUser), +// and failing that it will attempt to load it based on the email (see docs for getUserFromAuthEmail). +// Returns nil if the headers are empty or the user is not found. +func (r *ReverseProxy) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) *user_model.User { + user := r.getUserFromAuthUser(req) + if user == nil { + user = r.getUserFromAuthEmail(req) + if user == nil { + return nil + } + } // Make sure requests to API paths, attachment downloads, git and LFS do not create a new session if !middleware.IsAPIPath(req) && !isAttachmentDownload(req) && !isGitRawReleaseOrLFSPath(req) { diff --git a/templates/package/content/container.tmpl b/templates/package/content/container.tmpl index 939dfe40208ae..a79963e732ba0 100644 --- a/templates/package/content/container.tmpl +++ b/templates/package/content/container.tmpl @@ -47,7 +47,7 @@ {{if .PackageDescriptor.Metadata.ImageLayers}}
{{.locale.Tr "packages.container.labels.key"}} | diff --git a/templates/repo/commit_page.tmpl b/templates/repo/commit_page.tmpl index 8ece768832fb7..da37aaa9b323f 100644 --- a/templates/repo/commit_page.tmpl +++ b/templates/repo/commit_page.tmpl @@ -1,7 +1,7 @@ {{template "base/head" .}}
---|