mirror of
https://github.com/go-gitea/gitea.git
synced 2025-07-22 00:01:17 -04:00
Compare commits
6 Commits
e378545f30
...
1bf5527eac
Author | SHA1 | Date | |
---|---|---|---|
|
1bf5527eac | ||
|
80715ae5c7 | ||
|
dcb648ee71 | ||
|
0ba4ecc3bd | ||
|
4776fde9e1 | ||
|
dc52f26d46 |
@ -62,7 +62,7 @@ func runListAuth(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
authSources, err := auth_model.Sources(ctx)
|
||||
authSources, err := auth_model.FindSources(ctx, auth_model.FindSourcesOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ func GetStatistic(ctx context.Context) (stats Statistic) {
|
||||
stats.Counter.Follow, _ = e.Count(new(user_model.Follow))
|
||||
stats.Counter.Mirror, _ = e.Count(new(repo_model.Mirror))
|
||||
stats.Counter.Release, _ = e.Count(new(repo_model.Release))
|
||||
stats.Counter.AuthSource = auth.CountSources(ctx)
|
||||
stats.Counter.AuthSource = auth.CountSources(ctx, auth.FindSourcesOptions{})
|
||||
stats.Counter.Webhook, _ = e.Count(new(webhook.Webhook))
|
||||
stats.Counter.Milestone, _ = e.Count(new(issues_model.Milestone))
|
||||
stats.Counter.Label, _ = e.Count(new(issues_model.Label))
|
||||
|
@ -631,15 +631,6 @@ func (err ErrOAuthApplicationNotFound) Unwrap() error {
|
||||
return util.ErrNotExist
|
||||
}
|
||||
|
||||
// GetActiveOAuth2ProviderSources returns all actived LoginOAuth2 sources
|
||||
func GetActiveOAuth2ProviderSources(ctx context.Context) ([]*Source, error) {
|
||||
sources := make([]*Source, 0, 1)
|
||||
if err := db.GetEngine(ctx).Where("is_active = ? and type = ?", true, OAuth2).Find(&sources); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return sources, nil
|
||||
}
|
||||
|
||||
// GetActiveOAuth2SourceByName returns a OAuth2 AuthSource based on the given name
|
||||
func GetActiveOAuth2SourceByName(ctx context.Context, name string) (*Source, error) {
|
||||
authSource := new(Source)
|
||||
|
@ -14,6 +14,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"xorm.io/builder"
|
||||
"xorm.io/xorm"
|
||||
"xorm.io/xorm/convert"
|
||||
)
|
||||
@ -240,37 +241,26 @@ func CreateSource(ctx context.Context, source *Source) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Sources returns a slice of all login sources found in DB.
|
||||
func Sources(ctx context.Context) ([]*Source, error) {
|
||||
type FindSourcesOptions struct {
|
||||
IsActive util.OptionalBool
|
||||
LoginType Type
|
||||
}
|
||||
|
||||
func (opts FindSourcesOptions) ToConds() builder.Cond {
|
||||
conds := builder.NewCond()
|
||||
if !opts.IsActive.IsNone() {
|
||||
conds = conds.And(builder.Eq{"is_active": opts.IsActive.IsTrue()})
|
||||
}
|
||||
if opts.LoginType != NoType {
|
||||
conds = conds.And(builder.Eq{"`type`": opts.LoginType})
|
||||
}
|
||||
return conds
|
||||
}
|
||||
|
||||
// FindSources returns a slice of login sources found in DB according to given conditions.
|
||||
func FindSources(ctx context.Context, opts FindSourcesOptions) ([]*Source, error) {
|
||||
auths := make([]*Source, 0, 6)
|
||||
return auths, db.GetEngine(ctx).Find(&auths)
|
||||
}
|
||||
|
||||
// SourcesByType returns all sources of the specified type
|
||||
func SourcesByType(ctx context.Context, loginType Type) ([]*Source, error) {
|
||||
sources := make([]*Source, 0, 1)
|
||||
if err := db.GetEngine(ctx).Where("type = ?", loginType).Find(&sources); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return sources, nil
|
||||
}
|
||||
|
||||
// AllActiveSources returns all active sources
|
||||
func AllActiveSources(ctx context.Context) ([]*Source, error) {
|
||||
sources := make([]*Source, 0, 5)
|
||||
if err := db.GetEngine(ctx).Where("is_active = ?", true).Find(&sources); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return sources, nil
|
||||
}
|
||||
|
||||
// ActiveSources returns all active sources of the specified type
|
||||
func ActiveSources(ctx context.Context, tp Type) ([]*Source, error) {
|
||||
sources := make([]*Source, 0, 1)
|
||||
if err := db.GetEngine(ctx).Where("is_active = ? and type = ?", true, tp).Find(&sources); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return sources, nil
|
||||
return auths, db.GetEngine(ctx).Where(opts.ToConds()).Find(&auths)
|
||||
}
|
||||
|
||||
// IsSSPIEnabled returns true if there is at least one activated login
|
||||
@ -279,7 +269,10 @@ func IsSSPIEnabled(ctx context.Context) bool {
|
||||
if !db.HasEngine {
|
||||
return false
|
||||
}
|
||||
sources, err := ActiveSources(ctx, SSPI)
|
||||
sources, err := FindSources(ctx, FindSourcesOptions{
|
||||
IsActive: util.OptionalBoolTrue,
|
||||
LoginType: SSPI,
|
||||
})
|
||||
if err != nil {
|
||||
log.Error("ActiveSources: %v", err)
|
||||
return false
|
||||
@ -354,8 +347,8 @@ func UpdateSource(ctx context.Context, source *Source) error {
|
||||
}
|
||||
|
||||
// CountSources returns number of login sources.
|
||||
func CountSources(ctx context.Context) int64 {
|
||||
count, _ := db.GetEngine(ctx).Count(new(Source))
|
||||
func CountSources(ctx context.Context, opts FindSourcesOptions) int64 {
|
||||
count, _ := db.GetEngine(ctx).Where(opts.ToConds()).Count(new(Source))
|
||||
return count
|
||||
}
|
||||
|
||||
|
@ -142,22 +142,14 @@ type Issue struct {
|
||||
}
|
||||
|
||||
var (
|
||||
issueTasksPat *regexp.Regexp
|
||||
issueTasksDonePat *regexp.Regexp
|
||||
)
|
||||
|
||||
const (
|
||||
issueTasksRegexpStr = `(^\s*[-*]\s\[[\sxX]\]\s.)|(\n\s*[-*]\s\[[\sxX]\]\s.)`
|
||||
issueTasksDoneRegexpStr = `(^\s*[-*]\s\[[xX]\]\s.)|(\n\s*[-*]\s\[[xX]\]\s.)`
|
||||
issueTasksPat = regexp.MustCompile(`(^\s*[-*]\s\[[\sxX]\]\s.)|(\n\s*[-*]\s\[[\sxX]\]\s.)`)
|
||||
issueTasksDonePat = regexp.MustCompile(`(^\s*[-*]\s\[[xX]\]\s.)|(\n\s*[-*]\s\[[xX]\]\s.)`)
|
||||
)
|
||||
|
||||
// IssueIndex represents the issue index table
|
||||
type IssueIndex db.ResourceIndex
|
||||
|
||||
func init() {
|
||||
issueTasksPat = regexp.MustCompile(issueTasksRegexpStr)
|
||||
issueTasksDonePat = regexp.MustCompile(issueTasksDoneRegexpStr)
|
||||
|
||||
db.RegisterModel(new(Issue))
|
||||
db.RegisterModel(new(IssueIndex))
|
||||
}
|
||||
|
@ -1786,6 +1786,8 @@ pulls.status_checks_failure = Some checks failed
|
||||
pulls.status_checks_error = Some checks reported errors
|
||||
pulls.status_checks_requested = Required
|
||||
pulls.status_checks_details = Details
|
||||
pulls.status_checks_hide_all = Hide all checks
|
||||
pulls.status_checks_show_all = Show all checks
|
||||
pulls.update_branch = Update branch by merge
|
||||
pulls.update_branch_rebase = Update branch by rebase
|
||||
pulls.update_branch_success = Branch update was successful
|
||||
|
@ -77,20 +77,24 @@ milestones=Míľniky
|
||||
|
||||
ok=OK
|
||||
cancel=Zrušiť
|
||||
retry=Opakovať
|
||||
save=Uložiť
|
||||
add=Pridať
|
||||
add_all=Pridať všetko
|
||||
remove=Odstrániť
|
||||
remove_all=Odstrániť všetko
|
||||
remove_label_str=Odstrániť položku „%s“
|
||||
edit=Upraviť
|
||||
|
||||
enabled=Povolené
|
||||
|
||||
copy=Kopírovať
|
||||
copy_url=Kopírovať URL
|
||||
copy_content=Kopírovať obsah
|
||||
copy_branch=Kopírovať meno vetvy
|
||||
copy_success=Skopírované!
|
||||
copy_error=Kopírovanie zlyhalo
|
||||
copy_type_unsupported=Tento typ súboru nie je možné skopírovať
|
||||
|
||||
write=Zapísať
|
||||
preview=Náhľad
|
||||
|
@ -48,13 +48,13 @@ func Authentications(ctx *context.Context) {
|
||||
ctx.Data["PageIsAdminAuthentications"] = true
|
||||
|
||||
var err error
|
||||
ctx.Data["Sources"], err = auth.Sources(ctx)
|
||||
ctx.Data["Sources"], err = auth.FindSources(ctx, auth.FindSourcesOptions{})
|
||||
if err != nil {
|
||||
ctx.ServerError("auth.Sources", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["Total"] = auth.CountSources(ctx)
|
||||
ctx.Data["Total"] = auth.CountSources(ctx, auth.FindSourcesOptions{})
|
||||
ctx.HTML(http.StatusOK, tplAuths)
|
||||
}
|
||||
|
||||
@ -99,7 +99,7 @@ func NewAuthSource(ctx *context.Context) {
|
||||
ctx.Data["AuthSources"] = authSources
|
||||
ctx.Data["SecurityProtocols"] = securityProtocols
|
||||
ctx.Data["SMTPAuths"] = smtp.Authenticators
|
||||
oauth2providers := oauth2.GetOAuth2Providers()
|
||||
oauth2providers := oauth2.GetSupportedOAuth2Providers()
|
||||
ctx.Data["OAuth2Providers"] = oauth2providers
|
||||
|
||||
ctx.Data["SSPIAutoCreateUsers"] = true
|
||||
@ -242,7 +242,7 @@ func NewAuthSourcePost(ctx *context.Context) {
|
||||
ctx.Data["AuthSources"] = authSources
|
||||
ctx.Data["SecurityProtocols"] = securityProtocols
|
||||
ctx.Data["SMTPAuths"] = smtp.Authenticators
|
||||
oauth2providers := oauth2.GetOAuth2Providers()
|
||||
oauth2providers := oauth2.GetSupportedOAuth2Providers()
|
||||
ctx.Data["OAuth2Providers"] = oauth2providers
|
||||
|
||||
ctx.Data["SSPIAutoCreateUsers"] = true
|
||||
@ -284,7 +284,7 @@ func NewAuthSourcePost(ctx *context.Context) {
|
||||
ctx.RenderWithErr(err.Error(), tplAuthNew, form)
|
||||
return
|
||||
}
|
||||
existing, err := auth.SourcesByType(ctx, auth.SSPI)
|
||||
existing, err := auth.FindSources(ctx, auth.FindSourcesOptions{LoginType: auth.SSPI})
|
||||
if err != nil || len(existing) > 0 {
|
||||
ctx.Data["Err_Type"] = true
|
||||
ctx.RenderWithErr(ctx.Tr("admin.auths.login_source_of_type_exist"), tplAuthNew, form)
|
||||
@ -334,7 +334,7 @@ func EditAuthSource(ctx *context.Context) {
|
||||
|
||||
ctx.Data["SecurityProtocols"] = securityProtocols
|
||||
ctx.Data["SMTPAuths"] = smtp.Authenticators
|
||||
oauth2providers := oauth2.GetOAuth2Providers()
|
||||
oauth2providers := oauth2.GetSupportedOAuth2Providers()
|
||||
ctx.Data["OAuth2Providers"] = oauth2providers
|
||||
|
||||
source, err := auth.GetSourceByID(ctx, ctx.ParamsInt64(":authid"))
|
||||
@ -368,7 +368,7 @@ func EditAuthSourcePost(ctx *context.Context) {
|
||||
ctx.Data["PageIsAdminAuthentications"] = true
|
||||
|
||||
ctx.Data["SMTPAuths"] = smtp.Authenticators
|
||||
oauth2providers := oauth2.GetOAuth2Providers()
|
||||
oauth2providers := oauth2.GetSupportedOAuth2Providers()
|
||||
ctx.Data["OAuth2Providers"] = oauth2providers
|
||||
|
||||
source, err := auth.GetSourceByID(ctx, ctx.ParamsInt64(":authid"))
|
||||
|
@ -90,7 +90,9 @@ func NewUser(ctx *context.Context) {
|
||||
|
||||
ctx.Data["login_type"] = "0-0"
|
||||
|
||||
sources, err := auth.Sources(ctx)
|
||||
sources, err := auth.FindSources(ctx, auth.FindSourcesOptions{
|
||||
IsActive: util.OptionalBoolTrue,
|
||||
})
|
||||
if err != nil {
|
||||
ctx.ServerError("auth.Sources", err)
|
||||
return
|
||||
@ -109,7 +111,9 @@ func NewUserPost(ctx *context.Context) {
|
||||
ctx.Data["DefaultUserVisibilityMode"] = setting.Service.DefaultUserVisibilityMode
|
||||
ctx.Data["AllowedUserVisibilityModes"] = setting.Service.AllowedUserVisibilityModesSlice.ToVisibleTypeSlice()
|
||||
|
||||
sources, err := auth.Sources(ctx)
|
||||
sources, err := auth.FindSources(ctx, auth.FindSourcesOptions{
|
||||
IsActive: util.OptionalBoolTrue,
|
||||
})
|
||||
if err != nil {
|
||||
ctx.ServerError("auth.Sources", err)
|
||||
return
|
||||
@ -230,7 +234,7 @@ func prepareUserInfo(ctx *context.Context) *user_model.User {
|
||||
ctx.Data["LoginSource"] = &auth.Source{}
|
||||
}
|
||||
|
||||
sources, err := auth.Sources(ctx)
|
||||
sources, err := auth.FindSources(ctx, auth.FindSourcesOptions{})
|
||||
if err != nil {
|
||||
ctx.ServerError("auth.Sources", err)
|
||||
return nil
|
||||
|
@ -160,12 +160,11 @@ func SignIn(ctx *context.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
orderedOAuth2Names, oauth2Providers, err := oauth2.GetActiveOAuth2Providers(ctx)
|
||||
oauth2Providers, err := oauth2.GetOAuth2Providers(ctx, util.OptionalBoolTrue)
|
||||
if err != nil {
|
||||
ctx.ServerError("UserSignIn", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["OrderedOAuth2Names"] = orderedOAuth2Names
|
||||
ctx.Data["OAuth2Providers"] = oauth2Providers
|
||||
ctx.Data["Title"] = ctx.Tr("sign_in")
|
||||
ctx.Data["SignInLink"] = setting.AppSubURL + "/user/login"
|
||||
@ -184,12 +183,11 @@ func SignIn(ctx *context.Context) {
|
||||
func SignInPost(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("sign_in")
|
||||
|
||||
orderedOAuth2Names, oauth2Providers, err := oauth2.GetActiveOAuth2Providers(ctx)
|
||||
oauth2Providers, err := oauth2.GetOAuth2Providers(ctx, util.OptionalBoolTrue)
|
||||
if err != nil {
|
||||
ctx.ServerError("UserSignIn", err)
|
||||
return
|
||||
}
|
||||
ctx.Data["OrderedOAuth2Names"] = orderedOAuth2Names
|
||||
ctx.Data["OAuth2Providers"] = oauth2Providers
|
||||
ctx.Data["Title"] = ctx.Tr("sign_in")
|
||||
ctx.Data["SignInLink"] = setting.AppSubURL + "/user/login"
|
||||
@ -408,13 +406,12 @@ func SignUp(ctx *context.Context) {
|
||||
|
||||
ctx.Data["SignUpLink"] = setting.AppSubURL + "/user/sign_up"
|
||||
|
||||
orderedOAuth2Names, oauth2Providers, err := oauth2.GetActiveOAuth2Providers(ctx)
|
||||
oauth2Providers, err := oauth2.GetOAuth2Providers(ctx, util.OptionalBoolTrue)
|
||||
if err != nil {
|
||||
ctx.ServerError("UserSignUp", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["OrderedOAuth2Names"] = orderedOAuth2Names
|
||||
ctx.Data["OAuth2Providers"] = oauth2Providers
|
||||
context.SetCaptchaData(ctx)
|
||||
|
||||
@ -438,13 +435,12 @@ func SignUpPost(ctx *context.Context) {
|
||||
|
||||
ctx.Data["SignUpLink"] = setting.AppSubURL + "/user/sign_up"
|
||||
|
||||
orderedOAuth2Names, oauth2Providers, err := oauth2.GetActiveOAuth2Providers(ctx)
|
||||
oauth2Providers, err := oauth2.GetOAuth2Providers(ctx, util.OptionalBoolTrue)
|
||||
if err != nil {
|
||||
ctx.ServerError("UserSignUp", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["OrderedOAuth2Names"] = orderedOAuth2Names
|
||||
ctx.Data["OAuth2Providers"] = oauth2Providers
|
||||
context.SetCaptchaData(ctx)
|
||||
|
||||
|
43
routers/web/githttp.go
Normal file
43
routers/web/githttp.go
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package web
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
"code.gitea.io/gitea/routers/web/repo"
|
||||
context_service "code.gitea.io/gitea/services/context"
|
||||
)
|
||||
|
||||
func requireSignIn(ctx *context.Context) {
|
||||
if !setting.Service.RequireSignInView {
|
||||
return
|
||||
}
|
||||
|
||||
// rely on the results of Contexter
|
||||
if !ctx.IsSigned {
|
||||
// TODO: support digit auth - which would be Authorization header with digit
|
||||
ctx.Resp.Header().Set("WWW-Authenticate", `Basic realm="Gitea"`)
|
||||
ctx.Error(http.StatusUnauthorized)
|
||||
}
|
||||
}
|
||||
|
||||
func gitHTTPRouters(m *web.Route) {
|
||||
m.Group("", func() {
|
||||
m.PostOptions("/git-upload-pack", repo.ServiceUploadPack)
|
||||
m.PostOptions("/git-receive-pack", repo.ServiceReceivePack)
|
||||
m.GetOptions("/info/refs", repo.GetInfoRefs)
|
||||
m.GetOptions("/HEAD", repo.GetTextFile("HEAD"))
|
||||
m.GetOptions("/objects/info/alternates", repo.GetTextFile("objects/info/alternates"))
|
||||
m.GetOptions("/objects/info/http-alternates", repo.GetTextFile("objects/info/http-alternates"))
|
||||
m.GetOptions("/objects/info/packs", repo.GetInfoPacks)
|
||||
m.GetOptions("/objects/info/{file:[^/]*}", repo.GetTextFile(""))
|
||||
m.GetOptions("/objects/{head:[0-9a-f]{2}}/{hash:[0-9a-f]{38}}", repo.GetLooseObject)
|
||||
m.GetOptions("/objects/pack/pack-{file:[0-9a-f]{40}}.pack", repo.GetPackFile)
|
||||
m.GetOptions("/objects/pack/pack-{file:[0-9a-f]{40}}.idx", repo.GetIdxFile)
|
||||
}, ignSignInAndCsrf, requireSignIn, repo.HTTPGitEnabledHandler, repo.CorsHandler(), context_service.UserAssignmentWeb())
|
||||
}
|
@ -6,12 +6,14 @@ package security
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"sort"
|
||||
|
||||
auth_model "code.gitea.io/gitea/models/auth"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/services/auth/source/oauth2"
|
||||
)
|
||||
|
||||
@ -105,11 +107,31 @@ func loadSecurityData(ctx *context.Context) {
|
||||
}
|
||||
ctx.Data["AccountLinks"] = sources
|
||||
|
||||
orderedOAuth2Names, oauth2Providers, err := oauth2.GetActiveOAuth2Providers(ctx)
|
||||
authSources, err := auth_model.FindSources(ctx, auth_model.FindSourcesOptions{
|
||||
IsActive: util.OptionalBoolNone,
|
||||
LoginType: auth_model.OAuth2,
|
||||
})
|
||||
if err != nil {
|
||||
ctx.ServerError("GetActiveOAuth2Providers", err)
|
||||
ctx.ServerError("FindSources", err)
|
||||
return
|
||||
}
|
||||
|
||||
var orderedOAuth2Names []string
|
||||
oauth2Providers := make(map[string]oauth2.Provider)
|
||||
for _, source := range authSources {
|
||||
provider, err := oauth2.CreateProviderFromSource(source)
|
||||
if err != nil {
|
||||
ctx.ServerError("CreateProviderFromSource", err)
|
||||
return
|
||||
}
|
||||
oauth2Providers[source.Name] = provider
|
||||
if source.IsActive {
|
||||
orderedOAuth2Names = append(orderedOAuth2Names, source.Name)
|
||||
}
|
||||
}
|
||||
|
||||
sort.Strings(orderedOAuth2Names)
|
||||
|
||||
ctx.Data["OrderedOAuth2Names"] = orderedOAuth2Names
|
||||
ctx.Data["OAuth2Providers"] = oauth2Providers
|
||||
|
||||
|
@ -276,6 +276,8 @@ func Routes() *web.Route {
|
||||
return routes
|
||||
}
|
||||
|
||||
var ignSignInAndCsrf = verifyAuthWithOptions(&common.VerifyOptions{DisableCSRF: true})
|
||||
|
||||
// registerRoutes register routes
|
||||
func registerRoutes(m *web.Route) {
|
||||
reqSignIn := verifyAuthWithOptions(&common.VerifyOptions{SignInRequired: true})
|
||||
@ -283,7 +285,7 @@ func registerRoutes(m *web.Route) {
|
||||
// TODO: rename them to "optSignIn", which means that the "sign-in" could be optional, depends on the VerifyOptions (RequireSignInView)
|
||||
ignSignIn := verifyAuthWithOptions(&common.VerifyOptions{SignInRequired: setting.Service.RequireSignInView})
|
||||
ignExploreSignIn := verifyAuthWithOptions(&common.VerifyOptions{SignInRequired: setting.Service.RequireSignInView || setting.Service.Explore.RequireSigninView})
|
||||
ignSignInAndCsrf := verifyAuthWithOptions(&common.VerifyOptions{DisableCSRF: true})
|
||||
|
||||
validation.AddBindingRules()
|
||||
|
||||
linkAccountEnabled := func(ctx *context.Context) {
|
||||
@ -1512,19 +1514,7 @@ func registerRoutes(m *web.Route) {
|
||||
})
|
||||
}, ignSignInAndCsrf, lfsServerEnabled)
|
||||
|
||||
m.Group("", func() {
|
||||
m.PostOptions("/git-upload-pack", repo.ServiceUploadPack)
|
||||
m.PostOptions("/git-receive-pack", repo.ServiceReceivePack)
|
||||
m.GetOptions("/info/refs", repo.GetInfoRefs)
|
||||
m.GetOptions("/HEAD", repo.GetTextFile("HEAD"))
|
||||
m.GetOptions("/objects/info/alternates", repo.GetTextFile("objects/info/alternates"))
|
||||
m.GetOptions("/objects/info/http-alternates", repo.GetTextFile("objects/info/http-alternates"))
|
||||
m.GetOptions("/objects/info/packs", repo.GetInfoPacks)
|
||||
m.GetOptions("/objects/info/{file:[^/]*}", repo.GetTextFile(""))
|
||||
m.GetOptions("/objects/{head:[0-9a-f]{2}}/{hash:[0-9a-f]{38}}", repo.GetLooseObject)
|
||||
m.GetOptions("/objects/pack/pack-{file:[0-9a-f]{40}}.pack", repo.GetPackFile)
|
||||
m.GetOptions("/objects/pack/pack-{file:[0-9a-f]{40}}.idx", repo.GetIdxFile)
|
||||
}, ignSignInAndCsrf, repo.HTTPGitEnabledHandler, repo.CorsHandler(), context_service.UserAssignmentWeb())
|
||||
gitHTTPRouters(m)
|
||||
})
|
||||
})
|
||||
// ***** END: Repository *****
|
||||
|
@ -11,6 +11,7 @@ import (
|
||||
"code.gitea.io/gitea/models/db"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
"code.gitea.io/gitea/services/auth/source/oauth2"
|
||||
"code.gitea.io/gitea/services/auth/source/smtp"
|
||||
|
||||
@ -85,7 +86,9 @@ func UserSignIn(ctx context.Context, username, password string) (*user_model.Use
|
||||
}
|
||||
}
|
||||
|
||||
sources, err := auth.AllActiveSources(ctx)
|
||||
sources, err := auth.FindSources(ctx, auth.FindSourcesOptions{
|
||||
IsActive: util.OptionalBoolTrue,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"code.gitea.io/gitea/models/auth"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/gorilla/sessions"
|
||||
@ -63,7 +64,13 @@ func ResetOAuth2(ctx context.Context) error {
|
||||
|
||||
// initOAuth2Sources is used to load and register all active OAuth2 providers
|
||||
func initOAuth2Sources(ctx context.Context) error {
|
||||
authSources, _ := auth.GetActiveOAuth2ProviderSources(ctx)
|
||||
authSources, err := auth.FindSources(ctx, auth.FindSourcesOptions{
|
||||
IsActive: util.OptionalBoolTrue,
|
||||
LoginType: auth.OAuth2,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, source := range authSources {
|
||||
oauth2Source, ok := source.Cfg.(*Source)
|
||||
if !ok {
|
||||
|
@ -15,6 +15,7 @@ import (
|
||||
"code.gitea.io/gitea/models/auth"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"github.com/markbates/goth"
|
||||
)
|
||||
@ -80,10 +81,10 @@ func RegisterGothProvider(provider GothProvider) {
|
||||
gothProviders[provider.Name()] = provider
|
||||
}
|
||||
|
||||
// GetOAuth2Providers returns the map of unconfigured OAuth2 providers
|
||||
// GetSupportedOAuth2Providers returns the map of unconfigured OAuth2 providers
|
||||
// key is used as technical name (like in the callbackURL)
|
||||
// values to display
|
||||
func GetOAuth2Providers() []Provider {
|
||||
func GetSupportedOAuth2Providers() []Provider {
|
||||
providers := make([]Provider, 0, len(gothProviders))
|
||||
|
||||
for _, provider := range gothProviders {
|
||||
@ -95,33 +96,39 @@ func GetOAuth2Providers() []Provider {
|
||||
return providers
|
||||
}
|
||||
|
||||
// GetActiveOAuth2Providers returns the map of configured active OAuth2 providers
|
||||
// key is used as technical name (like in the callbackURL)
|
||||
// values to display
|
||||
func GetActiveOAuth2Providers(ctx context.Context) ([]string, map[string]Provider, error) {
|
||||
// Maybe also separate used and unused providers so we can force the registration of only 1 active provider for each type
|
||||
|
||||
authSources, err := auth.GetActiveOAuth2ProviderSources(ctx)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var orderedKeys []string
|
||||
providers := make(map[string]Provider)
|
||||
for _, source := range authSources {
|
||||
func CreateProviderFromSource(source *auth.Source) (Provider, error) {
|
||||
oauth2Cfg, ok := source.Cfg.(*Source)
|
||||
if !ok {
|
||||
log.Error("Invalid OAuth2 source config: %v", oauth2Cfg)
|
||||
continue
|
||||
return nil, fmt.Errorf("invalid OAuth2 source config: %v", oauth2Cfg)
|
||||
}
|
||||
gothProv := gothProviders[oauth2Cfg.Provider]
|
||||
providers[source.Name] = &AuthSourceProvider{GothProvider: gothProv, sourceName: source.Name, iconURL: oauth2Cfg.IconURL}
|
||||
orderedKeys = append(orderedKeys, source.Name)
|
||||
return &AuthSourceProvider{GothProvider: gothProv, sourceName: source.Name, iconURL: oauth2Cfg.IconURL}, nil
|
||||
}
|
||||
|
||||
// GetOAuth2Providers returns the list of configured OAuth2 providers
|
||||
func GetOAuth2Providers(ctx context.Context, isActive util.OptionalBool) ([]Provider, error) {
|
||||
authSources, err := auth.FindSources(ctx, auth.FindSourcesOptions{
|
||||
IsActive: isActive,
|
||||
LoginType: auth.OAuth2,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sort.Strings(orderedKeys)
|
||||
providers := make([]Provider, 0, len(authSources))
|
||||
for _, source := range authSources {
|
||||
provider, err := CreateProviderFromSource(source)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
providers = append(providers, provider)
|
||||
}
|
||||
|
||||
return orderedKeys, providers, nil
|
||||
sort.Slice(providers, func(i, j int) bool {
|
||||
return providers[i].Name() < providers[j].Name()
|
||||
})
|
||||
|
||||
return providers, nil
|
||||
}
|
||||
|
||||
// RegisterProviderWithGothic register a OAuth2 provider in goth lib
|
||||
|
@ -130,7 +130,10 @@ func (s *SSPI) Verify(req *http.Request, w http.ResponseWriter, store DataStore,
|
||||
|
||||
// getConfig retrieves the SSPI configuration from login sources
|
||||
func (s *SSPI) getConfig(ctx context.Context) (*sspi.Source, error) {
|
||||
sources, err := auth.ActiveSources(ctx, auth.SSPI)
|
||||
sources, err := auth.FindSources(ctx, auth.FindSourcesOptions{
|
||||
IsActive: util.OptionalBoolTrue,
|
||||
LoginType: auth.SSPI,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ import (
|
||||
func SyncExternalUsers(ctx context.Context, updateExisting bool) error {
|
||||
log.Trace("Doing: SyncExternalUsers")
|
||||
|
||||
ls, err := auth.Sources(ctx)
|
||||
ls, err := auth.FindSources(ctx, auth.FindSourcesOptions{})
|
||||
if err != nil {
|
||||
log.Error("SyncExternalUsers: %v", err)
|
||||
return err
|
||||
|
@ -19,7 +19,7 @@
|
||||
{{end}}
|
||||
<div class="ui top attached header clearing segment gt-relative commit-header {{$class}}">
|
||||
<div class="gt-df gt-mb-4 gt-fw">
|
||||
<h3 class="gt-mb-0 gt-f1"><span class="commit-summary" title="{{.Commit.Summary}}">{{RenderCommitMessage $.Context .Commit.Message $.RepoLink ($.Repository.ComposeMetas ctx)}}</span>{{template "repo/commit_statuses" dict "Status" .CommitStatus "Statuses" .CommitStatuses "root" $}}</h3>
|
||||
<h3 class="gt-mb-0 gt-f1"><span class="commit-summary" title="{{.Commit.Summary}}">{{RenderCommitMessage $.Context .Commit.Message $.RepoLink ($.Repository.ComposeMetas ctx)}}</span>{{template "repo/commit_statuses" dict "Status" .CommitStatus "Statuses" .CommitStatuses}}</h3>
|
||||
{{if not $.PageIsWiki}}
|
||||
<div>
|
||||
<a class="ui primary tiny button" href="{{.SourcePath}}">
|
||||
|
@ -8,15 +8,7 @@
|
||||
{{template "repo/commit_status" .Status}}
|
||||
</span>
|
||||
{{end}}
|
||||
<div class="tippy-target ui relaxed list divided">
|
||||
{{range .Statuses}}
|
||||
<div class="ui item singular-status gt-df">
|
||||
{{template "repo/commit_status" .}}
|
||||
<span class="ui gt-ml-3 gt-f1">{{.Context}} <span class="text grey">{{.Description}}</span></span>
|
||||
{{if .TargetURL}}
|
||||
<a class="gt-ml-3" href="{{.TargetURL}}" target="_blank" rel="noopener noreferrer">{{ctx.Locale.Tr "repo.pulls.status_checks_details"}}</a>
|
||||
{{end}}
|
||||
</div>
|
||||
{{end}}
|
||||
<div class="tippy-target">
|
||||
{{template "repo/pulls/status" (dict "CommitStatuses" .Statuses "CommitStatus" .Status)}}
|
||||
</div>
|
||||
{{end}}
|
||||
|
@ -66,7 +66,7 @@
|
||||
{{if IsMultilineCommitMessage .Message}}
|
||||
<button class="ui button js-toggle-commit-body ellipsis-button" aria-expanded="false">...</button>
|
||||
{{end}}
|
||||
{{template "repo/commit_statuses" dict "Status" .Status "Statuses" .Statuses "root" $}}
|
||||
{{template "repo/commit_statuses" dict "Status" .Status "Statuses" .Statuses}}
|
||||
{{if IsMultilineCommitMessage .Message}}
|
||||
<pre class="commit-body gt-hidden">{{RenderCommitBody $.Context .Message $commitRepoLink ($.Repository.ComposeMetas ctx)}}</pre>
|
||||
{{end}}
|
||||
|
@ -14,7 +14,7 @@
|
||||
{{$commitLink:= printf "%s/commit/%s" $.comment.Issue.PullRequest.BaseRepo.Link (PathEscape .ID.String)}}
|
||||
|
||||
<span class="shabox gt-df gt-ac gt-float-right">
|
||||
{{template "repo/commit_statuses" dict "Status" .Status "Statuses" .Statuses "root" $.root}}
|
||||
{{template "repo/commit_statuses" dict "Status" .Status "Statuses" .Statuses}}
|
||||
{{$class := "ui sha label"}}
|
||||
{{if .Signature}}
|
||||
{{$class = (print $class " isSigned")}}
|
||||
|
@ -49,6 +49,13 @@
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
{{$tasks := .GetTasks}}
|
||||
{{if gt $tasks 0}}
|
||||
<div class="meta gt-my-2">
|
||||
{{svg "octicon-checklist" 16 "gt-mr-2 gt-vm"}}
|
||||
<span class="gt-vm">{{.GetTasksDone}} / {{$tasks}}</span>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
{{if or .Labels .Assignees}}
|
||||
|
@ -20,7 +20,14 @@
|
||||
{{- else if .Issue.PullRequest.CanAutoMerge}}green
|
||||
{{- else}}red{{end}}">{{svg "octicon-git-merge" 40}}</div>
|
||||
<div class="content">
|
||||
{{template "repo/pulls/status" .}}
|
||||
<div class="ui attached segment fitted">
|
||||
{{template "repo/pulls/status" (dict
|
||||
"CommitStatus" .LatestCommitStatus
|
||||
"CommitStatuses" .LatestCommitStatuses
|
||||
"ShowHideChecks" true
|
||||
"is_context_required" .is_context_required
|
||||
)}}
|
||||
</div>
|
||||
{{$showGeneralMergeForm := false}}
|
||||
<div class="ui attached merge-section segment {{if not $.LatestCommitStatus}}no-header{{end}} flex-items-block">
|
||||
{{if .Issue.PullRequest.HasMerged}}
|
||||
|
@ -1,27 +1,43 @@
|
||||
{{if $.LatestCommitStatus}}
|
||||
{{if not $.Issue.PullRequest.HasMerged}}
|
||||
<div class="ui top attached header">
|
||||
{{if eq .LatestCommitStatus.State "pending"}}
|
||||
{{/*
|
||||
Template Attributes:
|
||||
* CommitStatus: summary of all commit status state
|
||||
* CommitStatuses: all commit status elements
|
||||
* ShowHideChecks: whether use a button to show/hide the checks
|
||||
* is_context_required: Used in pull request commit status check table
|
||||
*/}}
|
||||
|
||||
{{if .CommitStatus}}
|
||||
<div class="commit-status-panel">
|
||||
<div class="ui top attached header commit-status-header">
|
||||
{{if eq .CommitStatus.State "pending"}}
|
||||
{{ctx.Locale.Tr "repo.pulls.status_checking"}}
|
||||
{{else if eq .LatestCommitStatus.State "success"}}
|
||||
{{else if eq .CommitStatus.State "success"}}
|
||||
{{ctx.Locale.Tr "repo.pulls.status_checks_success"}}
|
||||
{{else if eq .LatestCommitStatus.State "warning"}}
|
||||
{{else if eq .CommitStatus.State "warning"}}
|
||||
{{ctx.Locale.Tr "repo.pulls.status_checks_warning"}}
|
||||
{{else if eq .LatestCommitStatus.State "failure"}}
|
||||
{{else if eq .CommitStatus.State "failure"}}
|
||||
{{ctx.Locale.Tr "repo.pulls.status_checks_failure"}}
|
||||
{{else if eq .LatestCommitStatus.State "error"}}
|
||||
{{else if eq .CommitStatus.State "error"}}
|
||||
{{ctx.Locale.Tr "repo.pulls.status_checks_error"}}
|
||||
{{else}}
|
||||
{{ctx.Locale.Tr "repo.pulls.status_checking"}}
|
||||
{{end}}
|
||||
|
||||
{{if .ShowHideChecks}}
|
||||
<div class="ui right">
|
||||
<button class="commit-status-hide-checks btn interact-fg"
|
||||
data-show-all="{{ctx.Locale.Tr "repo.pulls.status_checks_show_all"}}"
|
||||
data-hide-all="{{ctx.Locale.Tr "repo.pulls.status_checks_hide_all"}}">
|
||||
{{ctx.Locale.Tr "repo.pulls.status_checks_hide_all"}}</button>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
|
||||
{{range $.LatestCommitStatuses}}
|
||||
<div class="ui attached segment pr-status">
|
||||
<div class="commit-status-list">
|
||||
{{range .CommitStatuses}}
|
||||
<div class="commit-status-item">
|
||||
{{template "repo/commit_status" .}}
|
||||
<div class="status-context">
|
||||
<span>{{.Context}} <span class="text grey">{{.Description}}</span></span>
|
||||
<div class="status-context gt-ellipsis">{{.Context}} <span class="text light-2">{{.Description}}</span></div>
|
||||
<div class="ui status-details">
|
||||
{{if $.is_context_required}}
|
||||
{{if (call $.is_context_required .Context)}}<div class="ui label">{{ctx.Locale.Tr "repo.pulls.status_checks_requested"}}</div>{{end}}
|
||||
@ -29,6 +45,7 @@
|
||||
<span>{{if .TargetURL}}<a href="{{.TargetURL}}">{{ctx.Locale.Tr "repo.pulls.status_checks_details"}}</a>{{end}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
|
@ -24,7 +24,7 @@
|
||||
{{template "repo/shabox_badge" dict "root" $ "verification" .LatestCommitVerification}}
|
||||
{{end}}
|
||||
</a>
|
||||
{{template "repo/commit_statuses" dict "Status" .LatestCommitStatus "Statuses" .LatestCommitStatuses "root" $}}
|
||||
{{template "repo/commit_statuses" dict "Status" .LatestCommitStatus "Statuses" .LatestCommitStatuses}}
|
||||
{{$commitLink:= printf "%s/commit/%s" .RepoLink (PathEscape .LatestCommit.ID.String)}}
|
||||
<span class="grey commit-summary" title="{{.LatestCommit.Summary}}"><span class="message-wrapper">{{RenderCommitMessageLinkSubject $.Context .LatestCommit.Message $.RepoLink $commitLink ($.Repository.ComposeMetas ctx)}}</span>
|
||||
{{if IsMultilineCommitMessage .LatestCommit.Message}}
|
||||
|
@ -16,7 +16,7 @@
|
||||
<a class="gt-no-underline issue-title" href="{{if .Link}}{{.Link}}{{else}}{{$.Link}}/{{.Index}}{{end}}">{{RenderEmoji $.Context .Title | RenderCodeBlock}}</a>
|
||||
{{if .IsPull}}
|
||||
{{if (index $.CommitStatuses .PullRequest.ID)}}
|
||||
{{template "repo/commit_statuses" dict "Status" (index $.CommitLastStatus .PullRequest.ID) "Statuses" (index $.CommitStatuses .PullRequest.ID) "root" $}}
|
||||
{{template "repo/commit_statuses" dict "Status" (index $.CommitLastStatus .PullRequest.ID) "Statuses" (index $.CommitStatuses .PullRequest.ID)}}
|
||||
{{end}}
|
||||
{{end}}
|
||||
<span class="labels-list gt-ml-2">
|
||||
|
@ -52,16 +52,15 @@
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
{{if and .OrderedOAuth2Names .OAuth2Providers}}
|
||||
{{if .OAuth2Providers}}
|
||||
<div class="divider divider-text">
|
||||
{{ctx.Locale.Tr "sign_in_or"}}
|
||||
</div>
|
||||
<div id="oauth2-login-navigator" class="gt-py-2">
|
||||
<div class="gt-df gt-fc gt-jc">
|
||||
<div id="oauth2-login-navigator-inner" class="gt-df gt-fc gt-fw gt-ac gt-gap-3">
|
||||
{{range $key := .OrderedOAuth2Names}}
|
||||
{{$provider := index $.OAuth2Providers $key}}
|
||||
<a class="{{$provider.Name}} ui button gt-df gt-ac gt-jc gt-py-3 oauth-login-link" href="{{AppSubUrl}}/user/oauth2/{{$key}}">
|
||||
{{range $provider := .OAuth2Providers}}
|
||||
<a class="{{$provider.Name}} ui button gt-df gt-ac gt-jc gt-py-3 oauth-login-link" href="{{AppSubUrl}}/user/oauth2/{{$provider.Name}}">
|
||||
{{$provider.IconHTML 28}}
|
||||
{{ctx.Locale.Tr "sign_in_with_provider" $provider.DisplayName}}
|
||||
</a>
|
||||
|
@ -56,16 +56,15 @@
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
||||
{{if and .OrderedOAuth2Names .OAuth2Providers}}
|
||||
{{if .OAuth2Providers}}
|
||||
<div class="divider divider-text">
|
||||
{{ctx.Locale.Tr "sign_in_or"}}
|
||||
</div>
|
||||
<div id="oauth2-login-navigator" class="gt-py-2">
|
||||
<div class="gt-df gt-fc gt-jc">
|
||||
<div id="oauth2-login-navigator-inner" class="gt-df gt-fc gt-fw gt-ac gt-gap-3">
|
||||
{{range $key := .OrderedOAuth2Names}}
|
||||
{{$provider := index $.OAuth2Providers $key}}
|
||||
<a class="{{$provider.Name}} ui button gt-df gt-ac gt-jc gt-py-3 oauth-login-link" href="{{AppSubUrl}}/user/oauth2/{{$key}}">
|
||||
{{range $provider := .OAuth2Providers}}
|
||||
<a class="{{$provider.Name}} ui button gt-df gt-ac gt-jc gt-py-3 oauth-login-link" href="{{AppSubUrl}}/user/oauth2/{{$provider.Name}}">
|
||||
{{$provider.IconHTML 28}}
|
||||
{{ctx.Locale.Tr "sign_in_with_provider" $provider.DisplayName}}
|
||||
</a>
|
||||
|
@ -1,5 +1,5 @@
|
||||
.divider {
|
||||
margin: 1rem 0;
|
||||
margin: 10px 0;
|
||||
height: 0;
|
||||
font-weight: var(--font-weight-medium);
|
||||
text-transform: uppercase;
|
||||
@ -15,7 +15,7 @@
|
||||
.divider.divider-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 7px 0;
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
.divider.divider-text::before,
|
||||
|
@ -6,7 +6,7 @@
|
||||
}
|
||||
|
||||
[data-tippy-root] {
|
||||
max-width: calc(100vw - 10px);
|
||||
max-width: calc(100vw - 32px);
|
||||
}
|
||||
|
||||
.tippy-box {
|
||||
@ -18,37 +18,59 @@
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.tippy-content {
|
||||
position: relative;
|
||||
padding: 1rem; /* if you need different padding, use different data-theme */
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* tooltip theme for text tooltips */
|
||||
|
||||
.tippy-box[data-theme="tooltip"] {
|
||||
background-color: var(--color-tooltip-bg);
|
||||
color: var(--color-tooltip-text);
|
||||
border: none;
|
||||
}
|
||||
|
||||
.tippy-box[data-theme="tooltip"] .tippy-content {
|
||||
padding: 0.5rem 1rem;
|
||||
}
|
||||
|
||||
.tippy-box[data-theme="tooltip"] .tippy-svg-arrow-inner,
|
||||
.tippy-box[data-theme="tooltip"] .tippy-svg-arrow-outer {
|
||||
fill: var(--color-tooltip-bg);
|
||||
}
|
||||
|
||||
/* menu theme for .ui.menu */
|
||||
|
||||
.tippy-box[data-theme="menu"] {
|
||||
background-color: var(--color-menu);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.tippy-box[data-theme="form-fetch-error"] {
|
||||
border-color: var(--color-error-border);
|
||||
background-color: var(--color-error-bg);
|
||||
color: var(--color-error-text);
|
||||
}
|
||||
|
||||
.tippy-content {
|
||||
position: relative;
|
||||
padding: 1rem;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.tippy-box[data-theme="tooltip"] .tippy-content {
|
||||
padding: 0.5rem 1rem;
|
||||
}
|
||||
|
||||
.tippy-box[data-theme="menu"] .tippy-content {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.tippy-box[data-theme="menu"] .tippy-svg-arrow-inner {
|
||||
fill: var(--color-menu);
|
||||
}
|
||||
|
||||
/* box-with-header theme to look like .ui.attached.segment. can contain .ui.attached.header */
|
||||
|
||||
.tippy-box[data-theme="box-with-header"] .tippy-content {
|
||||
background: var(--color-box-body);
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.tippy-box[data-theme="box-with-header"][data-placement^="top"] .tippy-svg-arrow-inner {
|
||||
fill: var(--color-box-body);
|
||||
}
|
||||
|
||||
.tippy-box[data-theme="box-with-header"][data-placement^="bottom"] .tippy-svg-arrow-inner {
|
||||
fill: var(--color-box-header);
|
||||
}
|
||||
|
||||
.tippy-box[data-placement^="top"] > .tippy-svg-arrow {
|
||||
bottom: 0;
|
||||
}
|
||||
@ -107,12 +129,3 @@
|
||||
.tippy-svg-arrow-inner {
|
||||
fill: var(--color-body);
|
||||
}
|
||||
|
||||
.tippy-box[data-theme="tooltip"] .tippy-svg-arrow-inner,
|
||||
.tippy-box[data-theme="tooltip"] .tippy-svg-arrow-outer {
|
||||
fill: var(--color-tooltip-bg);
|
||||
}
|
||||
|
||||
.tippy-box[data-theme="menu"] .tippy-svg-arrow-inner {
|
||||
fill: var(--color-menu);
|
||||
}
|
||||
|
@ -3074,43 +3074,49 @@ tbody.commit-list {
|
||||
}
|
||||
}
|
||||
|
||||
.pr-status {
|
||||
padding: 0 !important; /* To clear fomantic's padding on .ui.segment elements */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.commit-status-header {
|
||||
border: none !important; /* reset the default ".ui.attached.header" styles, to use the outer border */
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.pr-status .commit-status {
|
||||
margin: 1em;
|
||||
.commit-status-list {
|
||||
max-height: 195px; /* fit exactly 4 items */
|
||||
overflow-x: hidden;
|
||||
transition: max-height .2s;
|
||||
}
|
||||
|
||||
.commit-status-item {
|
||||
padding: 14px 10px !important;
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
border-top: 1px solid var(--color-secondary);
|
||||
}
|
||||
|
||||
.commit-status-item .commit-status {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.pr-status .status-context {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
.commit-status-item .status-context {
|
||||
color: var(--color-text);
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.pr-status .status-context > span {
|
||||
padding: 1em 0;
|
||||
}
|
||||
|
||||
.pr-status .status-details {
|
||||
.commit-status-item .status-details {
|
||||
display: flex;
|
||||
padding-right: 0.5em;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
@media (max-width: 767.98px) {
|
||||
.pr-status .status-details {
|
||||
.commit-status-item .status-details {
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.pr-status .status-details > span {
|
||||
.commit-status-item .status-details > span {
|
||||
padding-right: 0.5em; /* To match the alignment with the "required" label */
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
align-items: flex-start;
|
||||
padding: 1em 0;
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.flex-item .flex-item-leading {
|
||||
|
@ -66,6 +66,7 @@ export function initCommitStatuses() {
|
||||
placement: top ? 'top-start' : 'bottom-start',
|
||||
interactive: true,
|
||||
role: 'dialog',
|
||||
theme: 'box-with-header',
|
||||
});
|
||||
});
|
||||
}
|
||||
|
12
web_src/js/features/repo-issue-pr-status.js
Normal file
12
web_src/js/features/repo-issue-pr-status.js
Normal file
@ -0,0 +1,12 @@
|
||||
export function initRepoPullRequestCommitStatus() {
|
||||
for (const btn of document.querySelectorAll('.commit-status-hide-checks')) {
|
||||
const panel = btn.closest('.commit-status-panel');
|
||||
const list = panel.querySelector('.commit-status-list');
|
||||
btn.addEventListener('click', () => {
|
||||
list.style.maxHeight = list.style.maxHeight ? '' : '0px'; // toggle
|
||||
list.style.overflow = 'hidden'; // hide scrollbar when hiding
|
||||
btn.textContent = btn.getAttribute(list.style.maxHeight ? 'data-show-all' : 'data-hide-all');
|
||||
});
|
||||
list.addEventListener('animationend', () => list.style.overflow = '');
|
||||
}
|
||||
}
|
@ -20,6 +20,7 @@ import {initCommentContent, initMarkupContent} from '../markup/content.js';
|
||||
import {initCompReactionSelector} from './comp/ReactionSelector.js';
|
||||
import {initRepoSettingBranches} from './repo-settings.js';
|
||||
import {initRepoPullRequestMergeForm} from './repo-issue-pr-form.js';
|
||||
import {initRepoPullRequestCommitStatus} from './repo-issue-pr-status.js';
|
||||
import {hideElem, showElem} from '../utils/dom.js';
|
||||
import {getComboMarkdownEditor, initComboMarkdownEditor} from './comp/ComboMarkdownEditor.js';
|
||||
import {attachRefIssueContextPopup} from './contextpopup.js';
|
||||
@ -546,6 +547,7 @@ export function initRepository() {
|
||||
initCompReactionSelector($(document));
|
||||
|
||||
initRepoPullRequestMergeForm();
|
||||
initRepoPullRequestCommitStatus();
|
||||
}
|
||||
|
||||
// Pull request
|
||||
|
@ -34,7 +34,7 @@ export function createTippy(target, opts = {}) {
|
||||
},
|
||||
arrow: `<svg width="16" height="7"><path d="m0 7 8-7 8 7Z" class="tippy-svg-arrow-outer"/><path d="m0 8 8-7 8 7Z" class="tippy-svg-arrow-inner"/></svg>`,
|
||||
role: 'menu', // HTML role attribute, only tooltips should use "tooltip"
|
||||
theme: other.role || 'menu', // CSS theme, we support either "tooltip" or "menu"
|
||||
theme: other.role || 'menu', // CSS theme, either "tooltip", "menu" or "box-with-header"
|
||||
plugins: [followCursor],
|
||||
...other,
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user