mirror of
https://github.com/go-gitea/gitea.git
synced 2025-07-19 00:01:16 -04:00
Compare commits
10 Commits
5ef5a0ade6
...
15fa0383fb
Author | SHA1 | Date | |
---|---|---|---|
|
15fa0383fb | ||
|
98f02203f9 | ||
|
673cf6af76 | ||
|
e74a3b18af | ||
|
e5e1d842c0 | ||
|
70f8d10fc5 | ||
|
5600504eed | ||
|
9e446dbf04 | ||
|
3b2da7e4ae | ||
|
ee27b94b2c |
@ -18,6 +18,7 @@ plugins:
|
|||||||
- eslint-plugin-regexp
|
- eslint-plugin-regexp
|
||||||
- eslint-plugin-sonarjs
|
- eslint-plugin-sonarjs
|
||||||
- eslint-plugin-unicorn
|
- eslint-plugin-unicorn
|
||||||
|
- eslint-plugin-vitest-globals
|
||||||
- eslint-plugin-wc
|
- eslint-plugin-wc
|
||||||
|
|
||||||
env:
|
env:
|
||||||
@ -45,6 +46,9 @@ overrides:
|
|||||||
- files: ["*.config.*"]
|
- files: ["*.config.*"]
|
||||||
rules:
|
rules:
|
||||||
import/no-unused-modules: [0]
|
import/no-unused-modules: [0]
|
||||||
|
- files: ["**/*.test.*", "web_src/js/test/setup.js"]
|
||||||
|
env:
|
||||||
|
vitest-globals/env: true
|
||||||
- files: ["web_src/js/modules/fetch.js", "web_src/js/standalone/**/*"]
|
- files: ["web_src/js/modules/fetch.js", "web_src/js/standalone/**/*"]
|
||||||
rules:
|
rules:
|
||||||
no-restricted-syntax: [2, WithStatement, ForInStatement, LabeledStatement, SequenceExpression]
|
no-restricted-syntax: [2, WithStatement, ForInStatement, LabeledStatement, SequenceExpression]
|
||||||
|
617
cmd/admin.go
617
cmd/admin.go
@ -6,26 +6,13 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"text/tabwriter"
|
|
||||||
|
|
||||||
asymkey_model "code.gitea.io/gitea/models/asymkey"
|
|
||||||
auth_model "code.gitea.io/gitea/models/auth"
|
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/graceful"
|
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
repo_module "code.gitea.io/gitea/modules/repository"
|
repo_module "code.gitea.io/gitea/modules/repository"
|
||||||
"code.gitea.io/gitea/modules/util"
|
|
||||||
auth_service "code.gitea.io/gitea/services/auth"
|
|
||||||
"code.gitea.io/gitea/services/auth/source/oauth2"
|
|
||||||
"code.gitea.io/gitea/services/auth/source/smtp"
|
|
||||||
repo_service "code.gitea.io/gitea/services/repository"
|
|
||||||
|
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
@ -59,28 +46,16 @@ var (
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
microcmdRegenHooks = &cli.Command{
|
|
||||||
Name: "hooks",
|
|
||||||
Usage: "Regenerate git-hooks",
|
|
||||||
Action: runRegenerateHooks,
|
|
||||||
}
|
|
||||||
|
|
||||||
microcmdRegenKeys = &cli.Command{
|
|
||||||
Name: "keys",
|
|
||||||
Usage: "Regenerate authorized_keys file",
|
|
||||||
Action: runRegenerateKeys,
|
|
||||||
}
|
|
||||||
|
|
||||||
subcmdAuth = &cli.Command{
|
subcmdAuth = &cli.Command{
|
||||||
Name: "auth",
|
Name: "auth",
|
||||||
Usage: "Modify external auth providers",
|
Usage: "Modify external auth providers",
|
||||||
Subcommands: []*cli.Command{
|
Subcommands: []*cli.Command{
|
||||||
microcmdAuthAddOauth,
|
microcmdAuthAddOauth,
|
||||||
microcmdAuthUpdateOauth,
|
microcmdAuthUpdateOauth,
|
||||||
cmdAuthAddLdapBindDn,
|
microcmdAuthAddLdapBindDn,
|
||||||
cmdAuthUpdateLdapBindDn,
|
microcmdAuthUpdateLdapBindDn,
|
||||||
cmdAuthAddLdapSimpleAuth,
|
microcmdAuthAddLdapSimpleAuth,
|
||||||
cmdAuthUpdateLdapSimpleAuth,
|
microcmdAuthUpdateLdapSimpleAuth,
|
||||||
microcmdAuthAddSMTP,
|
microcmdAuthAddSMTP,
|
||||||
microcmdAuthUpdateSMTP,
|
microcmdAuthUpdateSMTP,
|
||||||
microcmdAuthList,
|
microcmdAuthList,
|
||||||
@ -88,170 +63,6 @@ var (
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
microcmdAuthList = &cli.Command{
|
|
||||||
Name: "list",
|
|
||||||
Usage: "List auth sources",
|
|
||||||
Action: runListAuth,
|
|
||||||
Flags: []cli.Flag{
|
|
||||||
&cli.IntFlag{
|
|
||||||
Name: "min-width",
|
|
||||||
Usage: "Minimal cell width including any padding for the formatted table",
|
|
||||||
Value: 0,
|
|
||||||
},
|
|
||||||
&cli.IntFlag{
|
|
||||||
Name: "tab-width",
|
|
||||||
Usage: "width of tab characters in formatted table (equivalent number of spaces)",
|
|
||||||
Value: 8,
|
|
||||||
},
|
|
||||||
&cli.IntFlag{
|
|
||||||
Name: "padding",
|
|
||||||
Usage: "padding added to a cell before computing its width",
|
|
||||||
Value: 1,
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "pad-char",
|
|
||||||
Usage: `ASCII char used for padding if padchar == '\\t', the Writer will assume that the width of a '\\t' in the formatted output is tabwidth, and cells are left-aligned independent of align_left (for correct-looking results, tabwidth must correspond to the tab width in the viewer displaying the result)`,
|
|
||||||
Value: "\t",
|
|
||||||
},
|
|
||||||
&cli.BoolFlag{
|
|
||||||
Name: "vertical-bars",
|
|
||||||
Usage: "Set to true to print vertical bars between columns",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
idFlag = &cli.Int64Flag{
|
|
||||||
Name: "id",
|
|
||||||
Usage: "ID of authentication source",
|
|
||||||
}
|
|
||||||
|
|
||||||
microcmdAuthDelete = &cli.Command{
|
|
||||||
Name: "delete",
|
|
||||||
Usage: "Delete specific auth source",
|
|
||||||
Flags: []cli.Flag{idFlag},
|
|
||||||
Action: runDeleteAuth,
|
|
||||||
}
|
|
||||||
|
|
||||||
oauthCLIFlags = []cli.Flag{
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "name",
|
|
||||||
Value: "",
|
|
||||||
Usage: "Application Name",
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "provider",
|
|
||||||
Value: "",
|
|
||||||
Usage: "OAuth2 Provider",
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "key",
|
|
||||||
Value: "",
|
|
||||||
Usage: "Client ID (Key)",
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "secret",
|
|
||||||
Value: "",
|
|
||||||
Usage: "Client Secret",
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "auto-discover-url",
|
|
||||||
Value: "",
|
|
||||||
Usage: "OpenID Connect Auto Discovery URL (only required when using OpenID Connect as provider)",
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "use-custom-urls",
|
|
||||||
Value: "false",
|
|
||||||
Usage: "Use custom URLs for GitLab/GitHub OAuth endpoints",
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "custom-tenant-id",
|
|
||||||
Value: "",
|
|
||||||
Usage: "Use custom Tenant ID for OAuth endpoints",
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "custom-auth-url",
|
|
||||||
Value: "",
|
|
||||||
Usage: "Use a custom Authorization URL (option for GitLab/GitHub)",
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "custom-token-url",
|
|
||||||
Value: "",
|
|
||||||
Usage: "Use a custom Token URL (option for GitLab/GitHub)",
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "custom-profile-url",
|
|
||||||
Value: "",
|
|
||||||
Usage: "Use a custom Profile URL (option for GitLab/GitHub)",
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "custom-email-url",
|
|
||||||
Value: "",
|
|
||||||
Usage: "Use a custom Email URL (option for GitHub)",
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "icon-url",
|
|
||||||
Value: "",
|
|
||||||
Usage: "Custom icon URL for OAuth2 login source",
|
|
||||||
},
|
|
||||||
&cli.BoolFlag{
|
|
||||||
Name: "skip-local-2fa",
|
|
||||||
Usage: "Set to true to skip local 2fa for users authenticated by this source",
|
|
||||||
},
|
|
||||||
&cli.StringSliceFlag{
|
|
||||||
Name: "scopes",
|
|
||||||
Value: nil,
|
|
||||||
Usage: "Scopes to request when to authenticate against this OAuth2 source",
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "required-claim-name",
|
|
||||||
Value: "",
|
|
||||||
Usage: "Claim name that has to be set to allow users to login with this source",
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "required-claim-value",
|
|
||||||
Value: "",
|
|
||||||
Usage: "Claim value that has to be set to allow users to login with this source",
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "group-claim-name",
|
|
||||||
Value: "",
|
|
||||||
Usage: "Claim name providing group names for this source",
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "admin-group",
|
|
||||||
Value: "",
|
|
||||||
Usage: "Group Claim value for administrator users",
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "restricted-group",
|
|
||||||
Value: "",
|
|
||||||
Usage: "Group Claim value for restricted users",
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "group-team-map",
|
|
||||||
Value: "",
|
|
||||||
Usage: "JSON mapping between groups and org teams",
|
|
||||||
},
|
|
||||||
&cli.BoolFlag{
|
|
||||||
Name: "group-team-map-removal",
|
|
||||||
Usage: "Activate automatic team membership removal depending on groups",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
microcmdAuthUpdateOauth = &cli.Command{
|
|
||||||
Name: "update-oauth",
|
|
||||||
Usage: "Update existing Oauth authentication source",
|
|
||||||
Action: runUpdateOauth,
|
|
||||||
Flags: append(oauthCLIFlags[:1], append([]cli.Flag{idFlag}, oauthCLIFlags[1:]...)...),
|
|
||||||
}
|
|
||||||
|
|
||||||
microcmdAuthAddOauth = &cli.Command{
|
|
||||||
Name: "add-oauth",
|
|
||||||
Usage: "Add new Oauth authentication source",
|
|
||||||
Action: runAddOauth,
|
|
||||||
Flags: oauthCLIFlags,
|
|
||||||
}
|
|
||||||
|
|
||||||
subcmdSendMail = &cli.Command{
|
subcmdSendMail = &cli.Command{
|
||||||
Name: "sendmail",
|
Name: "sendmail",
|
||||||
Usage: "Send a message to all users",
|
Usage: "Send a message to all users",
|
||||||
@ -275,75 +86,9 @@ var (
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
smtpCLIFlags = []cli.Flag{
|
idFlag = &cli.Int64Flag{
|
||||||
&cli.StringFlag{
|
Name: "id",
|
||||||
Name: "name",
|
Usage: "ID of authentication source",
|
||||||
Value: "",
|
|
||||||
Usage: "Application Name",
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "auth-type",
|
|
||||||
Value: "PLAIN",
|
|
||||||
Usage: "SMTP Authentication Type (PLAIN/LOGIN/CRAM-MD5) default PLAIN",
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "host",
|
|
||||||
Value: "",
|
|
||||||
Usage: "SMTP Host",
|
|
||||||
},
|
|
||||||
&cli.IntFlag{
|
|
||||||
Name: "port",
|
|
||||||
Usage: "SMTP Port",
|
|
||||||
},
|
|
||||||
&cli.BoolFlag{
|
|
||||||
Name: "force-smtps",
|
|
||||||
Usage: "SMTPS is always used on port 465. Set this to force SMTPS on other ports.",
|
|
||||||
Value: true,
|
|
||||||
},
|
|
||||||
&cli.BoolFlag{
|
|
||||||
Name: "skip-verify",
|
|
||||||
Usage: "Skip TLS verify.",
|
|
||||||
Value: true,
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "helo-hostname",
|
|
||||||
Value: "",
|
|
||||||
Usage: "Hostname sent with HELO. Leave blank to send current hostname",
|
|
||||||
},
|
|
||||||
&cli.BoolFlag{
|
|
||||||
Name: "disable-helo",
|
|
||||||
Usage: "Disable SMTP helo.",
|
|
||||||
Value: true,
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "allowed-domains",
|
|
||||||
Value: "",
|
|
||||||
Usage: "Leave empty to allow all domains. Separate multiple domains with a comma (',')",
|
|
||||||
},
|
|
||||||
&cli.BoolFlag{
|
|
||||||
Name: "skip-local-2fa",
|
|
||||||
Usage: "Skip 2FA to log on.",
|
|
||||||
Value: true,
|
|
||||||
},
|
|
||||||
&cli.BoolFlag{
|
|
||||||
Name: "active",
|
|
||||||
Usage: "This Authentication Source is Activated.",
|
|
||||||
Value: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
microcmdAuthAddSMTP = &cli.Command{
|
|
||||||
Name: "add-smtp",
|
|
||||||
Usage: "Add new SMTP authentication source",
|
|
||||||
Action: runAddSMTP,
|
|
||||||
Flags: smtpCLIFlags,
|
|
||||||
}
|
|
||||||
|
|
||||||
microcmdAuthUpdateSMTP = &cli.Command{
|
|
||||||
Name: "update-smtp",
|
|
||||||
Usage: "Update existing SMTP authentication source",
|
|
||||||
Action: runUpdateSMTP,
|
|
||||||
Flags: append(smtpCLIFlags[:1], append([]cli.Flag{idFlag}, smtpCLIFlags[1:]...)...),
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -420,351 +165,3 @@ func getReleaseCount(ctx context.Context, id int64) (int64, error) {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func runRegenerateHooks(_ *cli.Context) error {
|
|
||||||
ctx, cancel := installSignals()
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
if err := initDB(ctx); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return repo_service.SyncRepositoryHooks(graceful.GetManager().ShutdownContext())
|
|
||||||
}
|
|
||||||
|
|
||||||
func runRegenerateKeys(_ *cli.Context) error {
|
|
||||||
ctx, cancel := installSignals()
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
if err := initDB(ctx); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return asymkey_model.RewriteAllPublicKeys(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseOAuth2Config(c *cli.Context) *oauth2.Source {
|
|
||||||
var customURLMapping *oauth2.CustomURLMapping
|
|
||||||
if c.IsSet("use-custom-urls") {
|
|
||||||
customURLMapping = &oauth2.CustomURLMapping{
|
|
||||||
TokenURL: c.String("custom-token-url"),
|
|
||||||
AuthURL: c.String("custom-auth-url"),
|
|
||||||
ProfileURL: c.String("custom-profile-url"),
|
|
||||||
EmailURL: c.String("custom-email-url"),
|
|
||||||
Tenant: c.String("custom-tenant-id"),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
customURLMapping = nil
|
|
||||||
}
|
|
||||||
return &oauth2.Source{
|
|
||||||
Provider: c.String("provider"),
|
|
||||||
ClientID: c.String("key"),
|
|
||||||
ClientSecret: c.String("secret"),
|
|
||||||
OpenIDConnectAutoDiscoveryURL: c.String("auto-discover-url"),
|
|
||||||
CustomURLMapping: customURLMapping,
|
|
||||||
IconURL: c.String("icon-url"),
|
|
||||||
SkipLocalTwoFA: c.Bool("skip-local-2fa"),
|
|
||||||
Scopes: c.StringSlice("scopes"),
|
|
||||||
RequiredClaimName: c.String("required-claim-name"),
|
|
||||||
RequiredClaimValue: c.String("required-claim-value"),
|
|
||||||
GroupClaimName: c.String("group-claim-name"),
|
|
||||||
AdminGroup: c.String("admin-group"),
|
|
||||||
RestrictedGroup: c.String("restricted-group"),
|
|
||||||
GroupTeamMap: c.String("group-team-map"),
|
|
||||||
GroupTeamMapRemoval: c.Bool("group-team-map-removal"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func runAddOauth(c *cli.Context) error {
|
|
||||||
ctx, cancel := installSignals()
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
if err := initDB(ctx); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
config := parseOAuth2Config(c)
|
|
||||||
if config.Provider == "openidConnect" {
|
|
||||||
discoveryURL, err := url.Parse(config.OpenIDConnectAutoDiscoveryURL)
|
|
||||||
if err != nil || (discoveryURL.Scheme != "http" && discoveryURL.Scheme != "https") {
|
|
||||||
return fmt.Errorf("invalid Auto Discovery URL: %s (this must be a valid URL starting with http:// or https://)", config.OpenIDConnectAutoDiscoveryURL)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return auth_model.CreateSource(&auth_model.Source{
|
|
||||||
Type: auth_model.OAuth2,
|
|
||||||
Name: c.String("name"),
|
|
||||||
IsActive: true,
|
|
||||||
Cfg: config,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func runUpdateOauth(c *cli.Context) error {
|
|
||||||
if !c.IsSet("id") {
|
|
||||||
return fmt.Errorf("--id flag is missing")
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, cancel := installSignals()
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
if err := initDB(ctx); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
source, err := auth_model.GetSourceByID(c.Int64("id"))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
oAuth2Config := source.Cfg.(*oauth2.Source)
|
|
||||||
|
|
||||||
if c.IsSet("name") {
|
|
||||||
source.Name = c.String("name")
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.IsSet("provider") {
|
|
||||||
oAuth2Config.Provider = c.String("provider")
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.IsSet("key") {
|
|
||||||
oAuth2Config.ClientID = c.String("key")
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.IsSet("secret") {
|
|
||||||
oAuth2Config.ClientSecret = c.String("secret")
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.IsSet("auto-discover-url") {
|
|
||||||
oAuth2Config.OpenIDConnectAutoDiscoveryURL = c.String("auto-discover-url")
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.IsSet("icon-url") {
|
|
||||||
oAuth2Config.IconURL = c.String("icon-url")
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.IsSet("scopes") {
|
|
||||||
oAuth2Config.Scopes = c.StringSlice("scopes")
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.IsSet("required-claim-name") {
|
|
||||||
oAuth2Config.RequiredClaimName = c.String("required-claim-name")
|
|
||||||
}
|
|
||||||
if c.IsSet("required-claim-value") {
|
|
||||||
oAuth2Config.RequiredClaimValue = c.String("required-claim-value")
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.IsSet("group-claim-name") {
|
|
||||||
oAuth2Config.GroupClaimName = c.String("group-claim-name")
|
|
||||||
}
|
|
||||||
if c.IsSet("admin-group") {
|
|
||||||
oAuth2Config.AdminGroup = c.String("admin-group")
|
|
||||||
}
|
|
||||||
if c.IsSet("restricted-group") {
|
|
||||||
oAuth2Config.RestrictedGroup = c.String("restricted-group")
|
|
||||||
}
|
|
||||||
if c.IsSet("group-team-map") {
|
|
||||||
oAuth2Config.GroupTeamMap = c.String("group-team-map")
|
|
||||||
}
|
|
||||||
if c.IsSet("group-team-map-removal") {
|
|
||||||
oAuth2Config.GroupTeamMapRemoval = c.Bool("group-team-map-removal")
|
|
||||||
}
|
|
||||||
|
|
||||||
// update custom URL mapping
|
|
||||||
customURLMapping := &oauth2.CustomURLMapping{}
|
|
||||||
|
|
||||||
if oAuth2Config.CustomURLMapping != nil {
|
|
||||||
customURLMapping.TokenURL = oAuth2Config.CustomURLMapping.TokenURL
|
|
||||||
customURLMapping.AuthURL = oAuth2Config.CustomURLMapping.AuthURL
|
|
||||||
customURLMapping.ProfileURL = oAuth2Config.CustomURLMapping.ProfileURL
|
|
||||||
customURLMapping.EmailURL = oAuth2Config.CustomURLMapping.EmailURL
|
|
||||||
customURLMapping.Tenant = oAuth2Config.CustomURLMapping.Tenant
|
|
||||||
}
|
|
||||||
if c.IsSet("use-custom-urls") && c.IsSet("custom-token-url") {
|
|
||||||
customURLMapping.TokenURL = c.String("custom-token-url")
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.IsSet("use-custom-urls") && c.IsSet("custom-auth-url") {
|
|
||||||
customURLMapping.AuthURL = c.String("custom-auth-url")
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.IsSet("use-custom-urls") && c.IsSet("custom-profile-url") {
|
|
||||||
customURLMapping.ProfileURL = c.String("custom-profile-url")
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.IsSet("use-custom-urls") && c.IsSet("custom-email-url") {
|
|
||||||
customURLMapping.EmailURL = c.String("custom-email-url")
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.IsSet("use-custom-urls") && c.IsSet("custom-tenant-id") {
|
|
||||||
customURLMapping.Tenant = c.String("custom-tenant-id")
|
|
||||||
}
|
|
||||||
|
|
||||||
oAuth2Config.CustomURLMapping = customURLMapping
|
|
||||||
source.Cfg = oAuth2Config
|
|
||||||
|
|
||||||
return auth_model.UpdateSource(source)
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseSMTPConfig(c *cli.Context, conf *smtp.Source) error {
|
|
||||||
if c.IsSet("auth-type") {
|
|
||||||
conf.Auth = c.String("auth-type")
|
|
||||||
validAuthTypes := []string{"PLAIN", "LOGIN", "CRAM-MD5"}
|
|
||||||
if !util.SliceContainsString(validAuthTypes, strings.ToUpper(c.String("auth-type"))) {
|
|
||||||
return errors.New("Auth must be one of PLAIN/LOGIN/CRAM-MD5")
|
|
||||||
}
|
|
||||||
conf.Auth = c.String("auth-type")
|
|
||||||
}
|
|
||||||
if c.IsSet("host") {
|
|
||||||
conf.Host = c.String("host")
|
|
||||||
}
|
|
||||||
if c.IsSet("port") {
|
|
||||||
conf.Port = c.Int("port")
|
|
||||||
}
|
|
||||||
if c.IsSet("allowed-domains") {
|
|
||||||
conf.AllowedDomains = c.String("allowed-domains")
|
|
||||||
}
|
|
||||||
if c.IsSet("force-smtps") {
|
|
||||||
conf.ForceSMTPS = c.Bool("force-smtps")
|
|
||||||
}
|
|
||||||
if c.IsSet("skip-verify") {
|
|
||||||
conf.SkipVerify = c.Bool("skip-verify")
|
|
||||||
}
|
|
||||||
if c.IsSet("helo-hostname") {
|
|
||||||
conf.HeloHostname = c.String("helo-hostname")
|
|
||||||
}
|
|
||||||
if c.IsSet("disable-helo") {
|
|
||||||
conf.DisableHelo = c.Bool("disable-helo")
|
|
||||||
}
|
|
||||||
if c.IsSet("skip-local-2fa") {
|
|
||||||
conf.SkipLocalTwoFA = c.Bool("skip-local-2fa")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func runAddSMTP(c *cli.Context) error {
|
|
||||||
ctx, cancel := installSignals()
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
if err := initDB(ctx); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !c.IsSet("name") || len(c.String("name")) == 0 {
|
|
||||||
return errors.New("name must be set")
|
|
||||||
}
|
|
||||||
if !c.IsSet("host") || len(c.String("host")) == 0 {
|
|
||||||
return errors.New("host must be set")
|
|
||||||
}
|
|
||||||
if !c.IsSet("port") {
|
|
||||||
return errors.New("port must be set")
|
|
||||||
}
|
|
||||||
active := true
|
|
||||||
if c.IsSet("active") {
|
|
||||||
active = c.Bool("active")
|
|
||||||
}
|
|
||||||
|
|
||||||
var smtpConfig smtp.Source
|
|
||||||
if err := parseSMTPConfig(c, &smtpConfig); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// If not set default to PLAIN
|
|
||||||
if len(smtpConfig.Auth) == 0 {
|
|
||||||
smtpConfig.Auth = "PLAIN"
|
|
||||||
}
|
|
||||||
|
|
||||||
return auth_model.CreateSource(&auth_model.Source{
|
|
||||||
Type: auth_model.SMTP,
|
|
||||||
Name: c.String("name"),
|
|
||||||
IsActive: active,
|
|
||||||
Cfg: &smtpConfig,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func runUpdateSMTP(c *cli.Context) error {
|
|
||||||
if !c.IsSet("id") {
|
|
||||||
return fmt.Errorf("--id flag is missing")
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, cancel := installSignals()
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
if err := initDB(ctx); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
source, err := auth_model.GetSourceByID(c.Int64("id"))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
smtpConfig := source.Cfg.(*smtp.Source)
|
|
||||||
|
|
||||||
if err := parseSMTPConfig(c, smtpConfig); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.IsSet("name") {
|
|
||||||
source.Name = c.String("name")
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.IsSet("active") {
|
|
||||||
source.IsActive = c.Bool("active")
|
|
||||||
}
|
|
||||||
|
|
||||||
source.Cfg = smtpConfig
|
|
||||||
|
|
||||||
return auth_model.UpdateSource(source)
|
|
||||||
}
|
|
||||||
|
|
||||||
func runListAuth(c *cli.Context) error {
|
|
||||||
ctx, cancel := installSignals()
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
if err := initDB(ctx); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
authSources, err := auth_model.Sources()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
flags := tabwriter.AlignRight
|
|
||||||
if c.Bool("vertical-bars") {
|
|
||||||
flags |= tabwriter.Debug
|
|
||||||
}
|
|
||||||
|
|
||||||
padChar := byte('\t')
|
|
||||||
if len(c.String("pad-char")) > 0 {
|
|
||||||
padChar = c.String("pad-char")[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
// loop through each source and print
|
|
||||||
w := tabwriter.NewWriter(os.Stdout, c.Int("min-width"), c.Int("tab-width"), c.Int("padding"), padChar, flags)
|
|
||||||
fmt.Fprintf(w, "ID\tName\tType\tEnabled\n")
|
|
||||||
for _, source := range authSources {
|
|
||||||
fmt.Fprintf(w, "%d\t%s\t%s\t%t\n", source.ID, source.Name, source.Type.String(), source.IsActive)
|
|
||||||
}
|
|
||||||
w.Flush()
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func runDeleteAuth(c *cli.Context) error {
|
|
||||||
if !c.IsSet("id") {
|
|
||||||
return fmt.Errorf("--id flag is missing")
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx, cancel := installSignals()
|
|
||||||
defer cancel()
|
|
||||||
|
|
||||||
if err := initDB(ctx); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
source, err := auth_model.GetSourceByID(c.Int64("id"))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return auth_service.DeleteSource(source)
|
|
||||||
}
|
|
||||||
|
109
cmd/admin_auth.go
Normal file
109
cmd/admin_auth.go
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"text/tabwriter"
|
||||||
|
|
||||||
|
auth_model "code.gitea.io/gitea/models/auth"
|
||||||
|
auth_service "code.gitea.io/gitea/services/auth"
|
||||||
|
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
microcmdAuthDelete = &cli.Command{
|
||||||
|
Name: "delete",
|
||||||
|
Usage: "Delete specific auth source",
|
||||||
|
Flags: []cli.Flag{idFlag},
|
||||||
|
Action: runDeleteAuth,
|
||||||
|
}
|
||||||
|
microcmdAuthList = &cli.Command{
|
||||||
|
Name: "list",
|
||||||
|
Usage: "List auth sources",
|
||||||
|
Action: runListAuth,
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.IntFlag{
|
||||||
|
Name: "min-width",
|
||||||
|
Usage: "Minimal cell width including any padding for the formatted table",
|
||||||
|
Value: 0,
|
||||||
|
},
|
||||||
|
&cli.IntFlag{
|
||||||
|
Name: "tab-width",
|
||||||
|
Usage: "width of tab characters in formatted table (equivalent number of spaces)",
|
||||||
|
Value: 8,
|
||||||
|
},
|
||||||
|
&cli.IntFlag{
|
||||||
|
Name: "padding",
|
||||||
|
Usage: "padding added to a cell before computing its width",
|
||||||
|
Value: 1,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "pad-char",
|
||||||
|
Usage: `ASCII char used for padding if padchar == '\\t', the Writer will assume that the width of a '\\t' in the formatted output is tabwidth, and cells are left-aligned independent of align_left (for correct-looking results, tabwidth must correspond to the tab width in the viewer displaying the result)`,
|
||||||
|
Value: "\t",
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "vertical-bars",
|
||||||
|
Usage: "Set to true to print vertical bars between columns",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func runListAuth(c *cli.Context) error {
|
||||||
|
ctx, cancel := installSignals()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
if err := initDB(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
authSources, err := auth_model.Sources()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
flags := tabwriter.AlignRight
|
||||||
|
if c.Bool("vertical-bars") {
|
||||||
|
flags |= tabwriter.Debug
|
||||||
|
}
|
||||||
|
|
||||||
|
padChar := byte('\t')
|
||||||
|
if len(c.String("pad-char")) > 0 {
|
||||||
|
padChar = c.String("pad-char")[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// loop through each source and print
|
||||||
|
w := tabwriter.NewWriter(os.Stdout, c.Int("min-width"), c.Int("tab-width"), c.Int("padding"), padChar, flags)
|
||||||
|
fmt.Fprintf(w, "ID\tName\tType\tEnabled\n")
|
||||||
|
for _, source := range authSources {
|
||||||
|
fmt.Fprintf(w, "%d\t%s\t%s\t%t\n", source.ID, source.Name, source.Type.String(), source.IsActive)
|
||||||
|
}
|
||||||
|
w.Flush()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func runDeleteAuth(c *cli.Context) error {
|
||||||
|
if !c.IsSet("id") {
|
||||||
|
return fmt.Errorf("--id flag is missing")
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, cancel := installSignals()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
if err := initDB(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
source, err := auth_model.GetSourceByID(c.Int64("id"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return auth_service.DeleteSource(source)
|
||||||
|
}
|
@ -132,10 +132,10 @@ var (
|
|||||||
ldapSimpleAuthCLIFlags = append(commonLdapCLIFlags,
|
ldapSimpleAuthCLIFlags = append(commonLdapCLIFlags,
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "user-dn",
|
Name: "user-dn",
|
||||||
Usage: "The user’s DN.",
|
Usage: "The user's DN.",
|
||||||
})
|
})
|
||||||
|
|
||||||
cmdAuthAddLdapBindDn = &cli.Command{
|
microcmdAuthAddLdapBindDn = &cli.Command{
|
||||||
Name: "add-ldap",
|
Name: "add-ldap",
|
||||||
Usage: "Add new LDAP (via Bind DN) authentication source",
|
Usage: "Add new LDAP (via Bind DN) authentication source",
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(c *cli.Context) error {
|
||||||
@ -144,7 +144,7 @@ var (
|
|||||||
Flags: ldapBindDnCLIFlags,
|
Flags: ldapBindDnCLIFlags,
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdAuthUpdateLdapBindDn = &cli.Command{
|
microcmdAuthUpdateLdapBindDn = &cli.Command{
|
||||||
Name: "update-ldap",
|
Name: "update-ldap",
|
||||||
Usage: "Update existing LDAP (via Bind DN) authentication source",
|
Usage: "Update existing LDAP (via Bind DN) authentication source",
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(c *cli.Context) error {
|
||||||
@ -153,7 +153,7 @@ var (
|
|||||||
Flags: append([]cli.Flag{idFlag}, ldapBindDnCLIFlags...),
|
Flags: append([]cli.Flag{idFlag}, ldapBindDnCLIFlags...),
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdAuthAddLdapSimpleAuth = &cli.Command{
|
microcmdAuthAddLdapSimpleAuth = &cli.Command{
|
||||||
Name: "add-ldap-simple",
|
Name: "add-ldap-simple",
|
||||||
Usage: "Add new LDAP (simple auth) authentication source",
|
Usage: "Add new LDAP (simple auth) authentication source",
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(c *cli.Context) error {
|
||||||
@ -162,7 +162,7 @@ var (
|
|||||||
Flags: ldapSimpleAuthCLIFlags,
|
Flags: ldapSimpleAuthCLIFlags,
|
||||||
}
|
}
|
||||||
|
|
||||||
cmdAuthUpdateLdapSimpleAuth = &cli.Command{
|
microcmdAuthUpdateLdapSimpleAuth = &cli.Command{
|
||||||
Name: "update-ldap-simple",
|
Name: "update-ldap-simple",
|
||||||
Usage: "Update existing LDAP (simple auth) authentication source",
|
Usage: "Update existing LDAP (simple auth) authentication source",
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(c *cli.Context) error {
|
||||||
|
@ -226,7 +226,7 @@ func TestAddLdapBindDn(t *testing.T) {
|
|||||||
|
|
||||||
// Create a copy of command to test
|
// Create a copy of command to test
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
app.Flags = cmdAuthAddLdapBindDn.Flags
|
app.Flags = microcmdAuthAddLdapBindDn.Flags
|
||||||
app.Action = service.addLdapBindDn
|
app.Action = service.addLdapBindDn
|
||||||
|
|
||||||
// Run it
|
// Run it
|
||||||
@ -457,7 +457,7 @@ func TestAddLdapSimpleAuth(t *testing.T) {
|
|||||||
|
|
||||||
// Create a copy of command to test
|
// Create a copy of command to test
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
app.Flags = cmdAuthAddLdapSimpleAuth.Flags
|
app.Flags = microcmdAuthAddLdapSimpleAuth.Flags
|
||||||
app.Action = service.addLdapSimpleAuth
|
app.Action = service.addLdapSimpleAuth
|
||||||
|
|
||||||
// Run it
|
// Run it
|
||||||
@ -920,7 +920,7 @@ func TestUpdateLdapBindDn(t *testing.T) {
|
|||||||
|
|
||||||
// Create a copy of command to test
|
// Create a copy of command to test
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
app.Flags = cmdAuthUpdateLdapBindDn.Flags
|
app.Flags = microcmdAuthUpdateLdapBindDn.Flags
|
||||||
app.Action = service.updateLdapBindDn
|
app.Action = service.updateLdapBindDn
|
||||||
|
|
||||||
// Run it
|
// Run it
|
||||||
@ -1310,7 +1310,7 @@ func TestUpdateLdapSimpleAuth(t *testing.T) {
|
|||||||
|
|
||||||
// Create a copy of command to test
|
// Create a copy of command to test
|
||||||
app := cli.NewApp()
|
app := cli.NewApp()
|
||||||
app.Flags = cmdAuthUpdateLdapSimpleAuth.Flags
|
app.Flags = microcmdAuthUpdateLdapSimpleAuth.Flags
|
||||||
app.Action = service.updateLdapSimpleAuth
|
app.Action = service.updateLdapSimpleAuth
|
||||||
|
|
||||||
// Run it
|
// Run it
|
||||||
|
298
cmd/admin_auth_oauth.go
Normal file
298
cmd/admin_auth_oauth.go
Normal file
@ -0,0 +1,298 @@
|
|||||||
|
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
auth_model "code.gitea.io/gitea/models/auth"
|
||||||
|
"code.gitea.io/gitea/services/auth/source/oauth2"
|
||||||
|
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
oauthCLIFlags = []cli.Flag{
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "name",
|
||||||
|
Value: "",
|
||||||
|
Usage: "Application Name",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "provider",
|
||||||
|
Value: "",
|
||||||
|
Usage: "OAuth2 Provider",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "key",
|
||||||
|
Value: "",
|
||||||
|
Usage: "Client ID (Key)",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "secret",
|
||||||
|
Value: "",
|
||||||
|
Usage: "Client Secret",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "auto-discover-url",
|
||||||
|
Value: "",
|
||||||
|
Usage: "OpenID Connect Auto Discovery URL (only required when using OpenID Connect as provider)",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "use-custom-urls",
|
||||||
|
Value: "false",
|
||||||
|
Usage: "Use custom URLs for GitLab/GitHub OAuth endpoints",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "custom-tenant-id",
|
||||||
|
Value: "",
|
||||||
|
Usage: "Use custom Tenant ID for OAuth endpoints",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "custom-auth-url",
|
||||||
|
Value: "",
|
||||||
|
Usage: "Use a custom Authorization URL (option for GitLab/GitHub)",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "custom-token-url",
|
||||||
|
Value: "",
|
||||||
|
Usage: "Use a custom Token URL (option for GitLab/GitHub)",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "custom-profile-url",
|
||||||
|
Value: "",
|
||||||
|
Usage: "Use a custom Profile URL (option for GitLab/GitHub)",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "custom-email-url",
|
||||||
|
Value: "",
|
||||||
|
Usage: "Use a custom Email URL (option for GitHub)",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "icon-url",
|
||||||
|
Value: "",
|
||||||
|
Usage: "Custom icon URL for OAuth2 login source",
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "skip-local-2fa",
|
||||||
|
Usage: "Set to true to skip local 2fa for users authenticated by this source",
|
||||||
|
},
|
||||||
|
&cli.StringSliceFlag{
|
||||||
|
Name: "scopes",
|
||||||
|
Value: nil,
|
||||||
|
Usage: "Scopes to request when to authenticate against this OAuth2 source",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "required-claim-name",
|
||||||
|
Value: "",
|
||||||
|
Usage: "Claim name that has to be set to allow users to login with this source",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "required-claim-value",
|
||||||
|
Value: "",
|
||||||
|
Usage: "Claim value that has to be set to allow users to login with this source",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "group-claim-name",
|
||||||
|
Value: "",
|
||||||
|
Usage: "Claim name providing group names for this source",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "admin-group",
|
||||||
|
Value: "",
|
||||||
|
Usage: "Group Claim value for administrator users",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "restricted-group",
|
||||||
|
Value: "",
|
||||||
|
Usage: "Group Claim value for restricted users",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "group-team-map",
|
||||||
|
Value: "",
|
||||||
|
Usage: "JSON mapping between groups and org teams",
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "group-team-map-removal",
|
||||||
|
Usage: "Activate automatic team membership removal depending on groups",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
microcmdAuthAddOauth = &cli.Command{
|
||||||
|
Name: "add-oauth",
|
||||||
|
Usage: "Add new Oauth authentication source",
|
||||||
|
Action: runAddOauth,
|
||||||
|
Flags: oauthCLIFlags,
|
||||||
|
}
|
||||||
|
|
||||||
|
microcmdAuthUpdateOauth = &cli.Command{
|
||||||
|
Name: "update-oauth",
|
||||||
|
Usage: "Update existing Oauth authentication source",
|
||||||
|
Action: runUpdateOauth,
|
||||||
|
Flags: append(oauthCLIFlags[:1], append([]cli.Flag{idFlag}, oauthCLIFlags[1:]...)...),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func parseOAuth2Config(c *cli.Context) *oauth2.Source {
|
||||||
|
var customURLMapping *oauth2.CustomURLMapping
|
||||||
|
if c.IsSet("use-custom-urls") {
|
||||||
|
customURLMapping = &oauth2.CustomURLMapping{
|
||||||
|
TokenURL: c.String("custom-token-url"),
|
||||||
|
AuthURL: c.String("custom-auth-url"),
|
||||||
|
ProfileURL: c.String("custom-profile-url"),
|
||||||
|
EmailURL: c.String("custom-email-url"),
|
||||||
|
Tenant: c.String("custom-tenant-id"),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
customURLMapping = nil
|
||||||
|
}
|
||||||
|
return &oauth2.Source{
|
||||||
|
Provider: c.String("provider"),
|
||||||
|
ClientID: c.String("key"),
|
||||||
|
ClientSecret: c.String("secret"),
|
||||||
|
OpenIDConnectAutoDiscoveryURL: c.String("auto-discover-url"),
|
||||||
|
CustomURLMapping: customURLMapping,
|
||||||
|
IconURL: c.String("icon-url"),
|
||||||
|
SkipLocalTwoFA: c.Bool("skip-local-2fa"),
|
||||||
|
Scopes: c.StringSlice("scopes"),
|
||||||
|
RequiredClaimName: c.String("required-claim-name"),
|
||||||
|
RequiredClaimValue: c.String("required-claim-value"),
|
||||||
|
GroupClaimName: c.String("group-claim-name"),
|
||||||
|
AdminGroup: c.String("admin-group"),
|
||||||
|
RestrictedGroup: c.String("restricted-group"),
|
||||||
|
GroupTeamMap: c.String("group-team-map"),
|
||||||
|
GroupTeamMapRemoval: c.Bool("group-team-map-removal"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func runAddOauth(c *cli.Context) error {
|
||||||
|
ctx, cancel := installSignals()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
if err := initDB(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
config := parseOAuth2Config(c)
|
||||||
|
if config.Provider == "openidConnect" {
|
||||||
|
discoveryURL, err := url.Parse(config.OpenIDConnectAutoDiscoveryURL)
|
||||||
|
if err != nil || (discoveryURL.Scheme != "http" && discoveryURL.Scheme != "https") {
|
||||||
|
return fmt.Errorf("invalid Auto Discovery URL: %s (this must be a valid URL starting with http:// or https://)", config.OpenIDConnectAutoDiscoveryURL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return auth_model.CreateSource(&auth_model.Source{
|
||||||
|
Type: auth_model.OAuth2,
|
||||||
|
Name: c.String("name"),
|
||||||
|
IsActive: true,
|
||||||
|
Cfg: config,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func runUpdateOauth(c *cli.Context) error {
|
||||||
|
if !c.IsSet("id") {
|
||||||
|
return fmt.Errorf("--id flag is missing")
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, cancel := installSignals()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
if err := initDB(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
source, err := auth_model.GetSourceByID(c.Int64("id"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
oAuth2Config := source.Cfg.(*oauth2.Source)
|
||||||
|
|
||||||
|
if c.IsSet("name") {
|
||||||
|
source.Name = c.String("name")
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.IsSet("provider") {
|
||||||
|
oAuth2Config.Provider = c.String("provider")
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.IsSet("key") {
|
||||||
|
oAuth2Config.ClientID = c.String("key")
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.IsSet("secret") {
|
||||||
|
oAuth2Config.ClientSecret = c.String("secret")
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.IsSet("auto-discover-url") {
|
||||||
|
oAuth2Config.OpenIDConnectAutoDiscoveryURL = c.String("auto-discover-url")
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.IsSet("icon-url") {
|
||||||
|
oAuth2Config.IconURL = c.String("icon-url")
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.IsSet("scopes") {
|
||||||
|
oAuth2Config.Scopes = c.StringSlice("scopes")
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.IsSet("required-claim-name") {
|
||||||
|
oAuth2Config.RequiredClaimName = c.String("required-claim-name")
|
||||||
|
}
|
||||||
|
if c.IsSet("required-claim-value") {
|
||||||
|
oAuth2Config.RequiredClaimValue = c.String("required-claim-value")
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.IsSet("group-claim-name") {
|
||||||
|
oAuth2Config.GroupClaimName = c.String("group-claim-name")
|
||||||
|
}
|
||||||
|
if c.IsSet("admin-group") {
|
||||||
|
oAuth2Config.AdminGroup = c.String("admin-group")
|
||||||
|
}
|
||||||
|
if c.IsSet("restricted-group") {
|
||||||
|
oAuth2Config.RestrictedGroup = c.String("restricted-group")
|
||||||
|
}
|
||||||
|
if c.IsSet("group-team-map") {
|
||||||
|
oAuth2Config.GroupTeamMap = c.String("group-team-map")
|
||||||
|
}
|
||||||
|
if c.IsSet("group-team-map-removal") {
|
||||||
|
oAuth2Config.GroupTeamMapRemoval = c.Bool("group-team-map-removal")
|
||||||
|
}
|
||||||
|
|
||||||
|
// update custom URL mapping
|
||||||
|
customURLMapping := &oauth2.CustomURLMapping{}
|
||||||
|
|
||||||
|
if oAuth2Config.CustomURLMapping != nil {
|
||||||
|
customURLMapping.TokenURL = oAuth2Config.CustomURLMapping.TokenURL
|
||||||
|
customURLMapping.AuthURL = oAuth2Config.CustomURLMapping.AuthURL
|
||||||
|
customURLMapping.ProfileURL = oAuth2Config.CustomURLMapping.ProfileURL
|
||||||
|
customURLMapping.EmailURL = oAuth2Config.CustomURLMapping.EmailURL
|
||||||
|
customURLMapping.Tenant = oAuth2Config.CustomURLMapping.Tenant
|
||||||
|
}
|
||||||
|
if c.IsSet("use-custom-urls") && c.IsSet("custom-token-url") {
|
||||||
|
customURLMapping.TokenURL = c.String("custom-token-url")
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.IsSet("use-custom-urls") && c.IsSet("custom-auth-url") {
|
||||||
|
customURLMapping.AuthURL = c.String("custom-auth-url")
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.IsSet("use-custom-urls") && c.IsSet("custom-profile-url") {
|
||||||
|
customURLMapping.ProfileURL = c.String("custom-profile-url")
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.IsSet("use-custom-urls") && c.IsSet("custom-email-url") {
|
||||||
|
customURLMapping.EmailURL = c.String("custom-email-url")
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.IsSet("use-custom-urls") && c.IsSet("custom-tenant-id") {
|
||||||
|
customURLMapping.Tenant = c.String("custom-tenant-id")
|
||||||
|
}
|
||||||
|
|
||||||
|
oAuth2Config.CustomURLMapping = customURLMapping
|
||||||
|
source.Cfg = oAuth2Config
|
||||||
|
|
||||||
|
return auth_model.UpdateSource(source)
|
||||||
|
}
|
201
cmd/admin_auth_stmp.go
Normal file
201
cmd/admin_auth_stmp.go
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
auth_model "code.gitea.io/gitea/models/auth"
|
||||||
|
"code.gitea.io/gitea/modules/util"
|
||||||
|
"code.gitea.io/gitea/services/auth/source/smtp"
|
||||||
|
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
smtpCLIFlags = []cli.Flag{
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "name",
|
||||||
|
Value: "",
|
||||||
|
Usage: "Application Name",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "auth-type",
|
||||||
|
Value: "PLAIN",
|
||||||
|
Usage: "SMTP Authentication Type (PLAIN/LOGIN/CRAM-MD5) default PLAIN",
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "host",
|
||||||
|
Value: "",
|
||||||
|
Usage: "SMTP Host",
|
||||||
|
},
|
||||||
|
&cli.IntFlag{
|
||||||
|
Name: "port",
|
||||||
|
Usage: "SMTP Port",
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "force-smtps",
|
||||||
|
Usage: "SMTPS is always used on port 465. Set this to force SMTPS on other ports.",
|
||||||
|
Value: true,
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "skip-verify",
|
||||||
|
Usage: "Skip TLS verify.",
|
||||||
|
Value: true,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "helo-hostname",
|
||||||
|
Value: "",
|
||||||
|
Usage: "Hostname sent with HELO. Leave blank to send current hostname",
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "disable-helo",
|
||||||
|
Usage: "Disable SMTP helo.",
|
||||||
|
Value: true,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "allowed-domains",
|
||||||
|
Value: "",
|
||||||
|
Usage: "Leave empty to allow all domains. Separate multiple domains with a comma (',')",
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "skip-local-2fa",
|
||||||
|
Usage: "Skip 2FA to log on.",
|
||||||
|
Value: true,
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "active",
|
||||||
|
Usage: "This Authentication Source is Activated.",
|
||||||
|
Value: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
microcmdAuthAddSMTP = &cli.Command{
|
||||||
|
Name: "add-smtp",
|
||||||
|
Usage: "Add new SMTP authentication source",
|
||||||
|
Action: runAddSMTP,
|
||||||
|
Flags: smtpCLIFlags,
|
||||||
|
}
|
||||||
|
|
||||||
|
microcmdAuthUpdateSMTP = &cli.Command{
|
||||||
|
Name: "update-smtp",
|
||||||
|
Usage: "Update existing SMTP authentication source",
|
||||||
|
Action: runUpdateSMTP,
|
||||||
|
Flags: append(smtpCLIFlags[:1], append([]cli.Flag{idFlag}, smtpCLIFlags[1:]...)...),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func parseSMTPConfig(c *cli.Context, conf *smtp.Source) error {
|
||||||
|
if c.IsSet("auth-type") {
|
||||||
|
conf.Auth = c.String("auth-type")
|
||||||
|
validAuthTypes := []string{"PLAIN", "LOGIN", "CRAM-MD5"}
|
||||||
|
if !util.SliceContainsString(validAuthTypes, strings.ToUpper(c.String("auth-type"))) {
|
||||||
|
return errors.New("Auth must be one of PLAIN/LOGIN/CRAM-MD5")
|
||||||
|
}
|
||||||
|
conf.Auth = c.String("auth-type")
|
||||||
|
}
|
||||||
|
if c.IsSet("host") {
|
||||||
|
conf.Host = c.String("host")
|
||||||
|
}
|
||||||
|
if c.IsSet("port") {
|
||||||
|
conf.Port = c.Int("port")
|
||||||
|
}
|
||||||
|
if c.IsSet("allowed-domains") {
|
||||||
|
conf.AllowedDomains = c.String("allowed-domains")
|
||||||
|
}
|
||||||
|
if c.IsSet("force-smtps") {
|
||||||
|
conf.ForceSMTPS = c.Bool("force-smtps")
|
||||||
|
}
|
||||||
|
if c.IsSet("skip-verify") {
|
||||||
|
conf.SkipVerify = c.Bool("skip-verify")
|
||||||
|
}
|
||||||
|
if c.IsSet("helo-hostname") {
|
||||||
|
conf.HeloHostname = c.String("helo-hostname")
|
||||||
|
}
|
||||||
|
if c.IsSet("disable-helo") {
|
||||||
|
conf.DisableHelo = c.Bool("disable-helo")
|
||||||
|
}
|
||||||
|
if c.IsSet("skip-local-2fa") {
|
||||||
|
conf.SkipLocalTwoFA = c.Bool("skip-local-2fa")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func runAddSMTP(c *cli.Context) error {
|
||||||
|
ctx, cancel := installSignals()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
if err := initDB(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !c.IsSet("name") || len(c.String("name")) == 0 {
|
||||||
|
return errors.New("name must be set")
|
||||||
|
}
|
||||||
|
if !c.IsSet("host") || len(c.String("host")) == 0 {
|
||||||
|
return errors.New("host must be set")
|
||||||
|
}
|
||||||
|
if !c.IsSet("port") {
|
||||||
|
return errors.New("port must be set")
|
||||||
|
}
|
||||||
|
active := true
|
||||||
|
if c.IsSet("active") {
|
||||||
|
active = c.Bool("active")
|
||||||
|
}
|
||||||
|
|
||||||
|
var smtpConfig smtp.Source
|
||||||
|
if err := parseSMTPConfig(c, &smtpConfig); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If not set default to PLAIN
|
||||||
|
if len(smtpConfig.Auth) == 0 {
|
||||||
|
smtpConfig.Auth = "PLAIN"
|
||||||
|
}
|
||||||
|
|
||||||
|
return auth_model.CreateSource(&auth_model.Source{
|
||||||
|
Type: auth_model.SMTP,
|
||||||
|
Name: c.String("name"),
|
||||||
|
IsActive: active,
|
||||||
|
Cfg: &smtpConfig,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func runUpdateSMTP(c *cli.Context) error {
|
||||||
|
if !c.IsSet("id") {
|
||||||
|
return fmt.Errorf("--id flag is missing")
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, cancel := installSignals()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
if err := initDB(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
source, err := auth_model.GetSourceByID(c.Int64("id"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
smtpConfig := source.Cfg.(*smtp.Source)
|
||||||
|
|
||||||
|
if err := parseSMTPConfig(c, smtpConfig); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.IsSet("name") {
|
||||||
|
source.Name = c.String("name")
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.IsSet("active") {
|
||||||
|
source.IsActive = c.Bool("active")
|
||||||
|
}
|
||||||
|
|
||||||
|
source.Cfg = smtpConfig
|
||||||
|
|
||||||
|
return auth_model.UpdateSource(source)
|
||||||
|
}
|
46
cmd/admin_regenerate.go
Normal file
46
cmd/admin_regenerate.go
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||||
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
asymkey_model "code.gitea.io/gitea/models/asymkey"
|
||||||
|
"code.gitea.io/gitea/modules/graceful"
|
||||||
|
repo_service "code.gitea.io/gitea/services/repository"
|
||||||
|
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
microcmdRegenHooks = &cli.Command{
|
||||||
|
Name: "hooks",
|
||||||
|
Usage: "Regenerate git-hooks",
|
||||||
|
Action: runRegenerateHooks,
|
||||||
|
}
|
||||||
|
|
||||||
|
microcmdRegenKeys = &cli.Command{
|
||||||
|
Name: "keys",
|
||||||
|
Usage: "Regenerate authorized_keys file",
|
||||||
|
Action: runRegenerateKeys,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func runRegenerateHooks(_ *cli.Context) error {
|
||||||
|
ctx, cancel := installSignals()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
if err := initDB(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return repo_service.SyncRepositoryHooks(graceful.GetManager().ShutdownContext())
|
||||||
|
}
|
||||||
|
|
||||||
|
func runRegenerateKeys(_ *cli.Context) error {
|
||||||
|
ctx, cancel := installSignals()
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
if err := initDB(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return asymkey_model.RewriteAllPublicKeys(ctx)
|
||||||
|
}
|
@ -20,9 +20,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: "..",
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func makePathOutput(workPath, customPath, customConf string) string {
|
func makePathOutput(workPath, customPath, customConf string) string {
|
||||||
|
@ -220,10 +220,10 @@ TAGS="bindata sqlite sqlite_unlock_notify" \
|
|||||||
make build
|
make build
|
||||||
```
|
```
|
||||||
|
|
||||||
## 源映射
|
## Source Map
|
||||||
|
|
||||||
默认情况下,gitea 会为前端文件生成精简的源映射以节省空间。 这可以通过“ENABLE_SOURCEMAP”环境变量进行控制:
|
默认情况下,gitea 会为前端文件生成精简的 Source Map 以节省空间。 这可以通过“ENABLE_SOURCEMAP”环境变量进行控制:
|
||||||
|
|
||||||
- `ENABLE_SOURCEMAP=true` 生成所有源映射,这是开发版本的默认设置
|
- `ENABLE_SOURCEMAP=true` 生成所有Source Map,这是开发版本的默认设置
|
||||||
- `ENABLE_SOURCEMAP=reduced` 生成有限的源映射,这是生产版本的默认设置
|
- `ENABLE_SOURCEMAP=reduced` 生成有限的Source Map,这是生产版本的默认设置
|
||||||
- `ENABLE_SOURCEMAP=false` 不生成源映射
|
- `ENABLE_SOURCEMAP=false` 不生成Source Map
|
||||||
|
20
go.mod
20
go.mod
@ -19,7 +19,7 @@ require (
|
|||||||
github.com/PuerkitoBio/goquery v1.8.1
|
github.com/PuerkitoBio/goquery v1.8.1
|
||||||
github.com/alecthomas/chroma/v2 v2.9.1
|
github.com/alecthomas/chroma/v2 v2.9.1
|
||||||
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb
|
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb
|
||||||
github.com/blevesearch/bleve/v2 v2.3.9
|
github.com/blevesearch/bleve/v2 v2.3.10
|
||||||
github.com/bufbuild/connect-go v1.10.0
|
github.com/bufbuild/connect-go v1.10.0
|
||||||
github.com/buildkite/terminal-to-html/v3 v3.9.1
|
github.com/buildkite/terminal-to-html/v3 v3.9.1
|
||||||
github.com/caddyserver/certmagic v0.19.2
|
github.com/caddyserver/certmagic v0.19.2
|
||||||
@ -145,22 +145,22 @@ require (
|
|||||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
||||||
github.com/aymerick/douceur v0.2.0 // indirect
|
github.com/aymerick/douceur v0.2.0 // indirect
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/bits-and-blooms/bitset v1.8.0 // indirect
|
github.com/bits-and-blooms/bitset v1.9.0 // indirect
|
||||||
github.com/blevesearch/bleve_index_api v1.0.5 // indirect
|
github.com/blevesearch/bleve_index_api v1.0.6 // indirect
|
||||||
github.com/blevesearch/geo v0.1.17 // indirect
|
github.com/blevesearch/geo v0.1.18 // indirect
|
||||||
github.com/blevesearch/go-porterstemmer v1.0.3 // indirect
|
github.com/blevesearch/go-porterstemmer v1.0.3 // indirect
|
||||||
github.com/blevesearch/gtreap v0.1.1 // indirect
|
github.com/blevesearch/gtreap v0.1.1 // indirect
|
||||||
github.com/blevesearch/mmap-go v1.0.4 // indirect
|
github.com/blevesearch/mmap-go v1.0.4 // indirect
|
||||||
github.com/blevesearch/scorch_segment_api/v2 v2.1.5 // indirect
|
github.com/blevesearch/scorch_segment_api/v2 v2.1.6 // indirect
|
||||||
github.com/blevesearch/segment v0.9.1 // indirect
|
github.com/blevesearch/segment v0.9.1 // indirect
|
||||||
github.com/blevesearch/snowballstem v0.9.0 // indirect
|
github.com/blevesearch/snowballstem v0.9.0 // indirect
|
||||||
github.com/blevesearch/upsidedown_store_api v1.0.2 // indirect
|
github.com/blevesearch/upsidedown_store_api v1.0.2 // indirect
|
||||||
github.com/blevesearch/vellum v1.0.10 // indirect
|
github.com/blevesearch/vellum v1.0.10 // indirect
|
||||||
github.com/blevesearch/zapx/v11 v11.3.9 // indirect
|
github.com/blevesearch/zapx/v11 v11.3.10 // indirect
|
||||||
github.com/blevesearch/zapx/v12 v12.3.9 // indirect
|
github.com/blevesearch/zapx/v12 v12.3.10 // indirect
|
||||||
github.com/blevesearch/zapx/v13 v13.3.9 // indirect
|
github.com/blevesearch/zapx/v13 v13.3.10 // indirect
|
||||||
github.com/blevesearch/zapx/v14 v14.3.9 // indirect
|
github.com/blevesearch/zapx/v14 v14.3.10 // indirect
|
||||||
github.com/blevesearch/zapx/v15 v15.3.12 // indirect
|
github.com/blevesearch/zapx/v15 v15.3.13 // indirect
|
||||||
github.com/boombuler/barcode v1.0.1 // indirect
|
github.com/boombuler/barcode v1.0.1 // indirect
|
||||||
github.com/bradfitz/gomemcache v0.0.0-20230611145640-acc696258285 // indirect
|
github.com/bradfitz/gomemcache v0.0.0-20230611145640-acc696258285 // indirect
|
||||||
github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a // indirect
|
github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a // indirect
|
||||||
|
40
go.sum
40
go.sum
@ -149,18 +149,18 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
|||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
github.com/bits-and-blooms/bitset v1.1.10/go.mod h1:w0XsmFg8qg6cmpTtJ0z3pKgjTDBMMnI/+I2syrE6XBE=
|
github.com/bits-and-blooms/bitset v1.1.10/go.mod h1:w0XsmFg8qg6cmpTtJ0z3pKgjTDBMMnI/+I2syrE6XBE=
|
||||||
github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
|
github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
|
||||||
github.com/bits-and-blooms/bitset v1.8.0 h1:FD+XqgOZDUxxZ8hzoBFuV9+cGWY9CslN6d5MS5JVb4c=
|
github.com/bits-and-blooms/bitset v1.9.0 h1:g1YivPG8jOtrN013Fe8OBXubkiTwvm7/vG2vXz03ANU=
|
||||||
github.com/bits-and-blooms/bitset v1.8.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
|
github.com/bits-and-blooms/bitset v1.9.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
|
||||||
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb h1:m935MPodAbYS46DG4pJSv7WO+VECIWUQ7OJYSoTrMh4=
|
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb h1:m935MPodAbYS46DG4pJSv7WO+VECIWUQ7OJYSoTrMh4=
|
||||||
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
|
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
|
||||||
github.com/blevesearch/bleve/v2 v2.0.5/go.mod h1:ZjWibgnbRX33c+vBRgla9QhPb4QOjD6fdVJ+R1Bk8LM=
|
github.com/blevesearch/bleve/v2 v2.0.5/go.mod h1:ZjWibgnbRX33c+vBRgla9QhPb4QOjD6fdVJ+R1Bk8LM=
|
||||||
github.com/blevesearch/bleve/v2 v2.3.9 h1:pUMvK0mxAexqasZcVj8lazmWnEW5XiV0tASIqANiNTQ=
|
github.com/blevesearch/bleve/v2 v2.3.10 h1:z8V0wwGoL4rp7nG/O3qVVLYxUqCbEwskMt4iRJsPLgg=
|
||||||
github.com/blevesearch/bleve/v2 v2.3.9/go.mod h1:1PibElcjlQMQHF9uS9mRv58ODQgj4pCWHA1Wfd+qagU=
|
github.com/blevesearch/bleve/v2 v2.3.10/go.mod h1:RJzeoeHC+vNHsoLR54+crS1HmOWpnH87fL70HAUCzIA=
|
||||||
github.com/blevesearch/bleve_index_api v1.0.0/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4=
|
github.com/blevesearch/bleve_index_api v1.0.0/go.mod h1:fiwKS0xLEm+gBRgv5mumf0dhgFr2mDgZah1pqv1c1M4=
|
||||||
github.com/blevesearch/bleve_index_api v1.0.5 h1:Lc986kpC4Z0/n1g3gg8ul7H+lxgOQPcXb9SxvQGu+tw=
|
github.com/blevesearch/bleve_index_api v1.0.6 h1:gyUUxdsrvmW3jVhhYdCVL6h9dCjNT/geNU7PxGn37p8=
|
||||||
github.com/blevesearch/bleve_index_api v1.0.5/go.mod h1:YXMDwaXFFXwncRS8UobWs7nvo0DmusriM1nztTlj1ms=
|
github.com/blevesearch/bleve_index_api v1.0.6/go.mod h1:YXMDwaXFFXwncRS8UobWs7nvo0DmusriM1nztTlj1ms=
|
||||||
github.com/blevesearch/geo v0.1.17 h1:AguzI6/5mHXapzB0gE9IKWo+wWPHZmXZoscHcjFgAFA=
|
github.com/blevesearch/geo v0.1.18 h1:Np8jycHTZ5scFe7VEPLrDoHnnb9C4j636ue/CGrhtDw=
|
||||||
github.com/blevesearch/geo v0.1.17/go.mod h1:uRMGWG0HJYfWfFJpK3zTdnnr1K+ksZTuWKhXeSokfnM=
|
github.com/blevesearch/geo v0.1.18/go.mod h1:uRMGWG0HJYfWfFJpK3zTdnnr1K+ksZTuWKhXeSokfnM=
|
||||||
github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo=
|
github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo=
|
||||||
github.com/blevesearch/go-porterstemmer v1.0.3/go.mod h1:angGc5Ht+k2xhJdZi511LtmxuEf0OVpvUUNrwmM1P7M=
|
github.com/blevesearch/go-porterstemmer v1.0.3/go.mod h1:angGc5Ht+k2xhJdZi511LtmxuEf0OVpvUUNrwmM1P7M=
|
||||||
github.com/blevesearch/gtreap v0.1.1 h1:2JWigFrzDMR+42WGIN/V2p0cUvn4UP3C4Q5nmaZGW8Y=
|
github.com/blevesearch/gtreap v0.1.1 h1:2JWigFrzDMR+42WGIN/V2p0cUvn4UP3C4Q5nmaZGW8Y=
|
||||||
@ -169,8 +169,8 @@ github.com/blevesearch/mmap-go v1.0.2/go.mod h1:ol2qBqYaOUsGdm7aRMRrYGgPvnwLe6Y+
|
|||||||
github.com/blevesearch/mmap-go v1.0.4 h1:OVhDhT5B/M1HNPpYPBKIEJaD0F3Si+CrEKULGCDPWmc=
|
github.com/blevesearch/mmap-go v1.0.4 h1:OVhDhT5B/M1HNPpYPBKIEJaD0F3Si+CrEKULGCDPWmc=
|
||||||
github.com/blevesearch/mmap-go v1.0.4/go.mod h1:EWmEAOmdAS9z/pi/+Toxu99DnsbhG1TIxUoRmJw/pSs=
|
github.com/blevesearch/mmap-go v1.0.4/go.mod h1:EWmEAOmdAS9z/pi/+Toxu99DnsbhG1TIxUoRmJw/pSs=
|
||||||
github.com/blevesearch/scorch_segment_api/v2 v2.0.1/go.mod h1:lq7yK2jQy1yQjtjTfU931aVqz7pYxEudHaDwOt1tXfU=
|
github.com/blevesearch/scorch_segment_api/v2 v2.0.1/go.mod h1:lq7yK2jQy1yQjtjTfU931aVqz7pYxEudHaDwOt1tXfU=
|
||||||
github.com/blevesearch/scorch_segment_api/v2 v2.1.5 h1:1g713kpCQZ8u4a3stRGBfrwVOuGRnmxOVU5MQkUPrHU=
|
github.com/blevesearch/scorch_segment_api/v2 v2.1.6 h1:CdekX/Ob6YCYmeHzD72cKpwzBjvkOGegHOqhAkXp6yA=
|
||||||
github.com/blevesearch/scorch_segment_api/v2 v2.1.5/go.mod h1:f2nOkKS1HcjgIWZgDAErgBdxmr2eyt0Kn7IY+FU1Xe4=
|
github.com/blevesearch/scorch_segment_api/v2 v2.1.6/go.mod h1:nQQYlp51XvoSVxcciBjtvuHPIVjlWrN1hX4qwK2cqdc=
|
||||||
github.com/blevesearch/segment v0.9.0/go.mod h1:9PfHYUdQCgHktBgvtUOF4x+pc4/l8rdH0u5spnW85UQ=
|
github.com/blevesearch/segment v0.9.0/go.mod h1:9PfHYUdQCgHktBgvtUOF4x+pc4/l8rdH0u5spnW85UQ=
|
||||||
github.com/blevesearch/segment v0.9.1 h1:+dThDy+Lvgj5JMxhmOVlgFfkUtZV2kw49xax4+jTfSU=
|
github.com/blevesearch/segment v0.9.1 h1:+dThDy+Lvgj5JMxhmOVlgFfkUtZV2kw49xax4+jTfSU=
|
||||||
github.com/blevesearch/segment v0.9.1/go.mod h1:zN21iLm7+GnBHWTao9I+Au/7MBiL8pPFtJBJTsk6kQw=
|
github.com/blevesearch/segment v0.9.1/go.mod h1:zN21iLm7+GnBHWTao9I+Au/7MBiL8pPFtJBJTsk6kQw=
|
||||||
@ -184,20 +184,20 @@ github.com/blevesearch/vellum v1.0.4/go.mod h1:cMhywHI0de50f7Nj42YgvyD6bFJ2WkNRv
|
|||||||
github.com/blevesearch/vellum v1.0.10 h1:HGPJDT2bTva12hrHepVT3rOyIKFFF4t7Gf6yMxyMIPI=
|
github.com/blevesearch/vellum v1.0.10 h1:HGPJDT2bTva12hrHepVT3rOyIKFFF4t7Gf6yMxyMIPI=
|
||||||
github.com/blevesearch/vellum v1.0.10/go.mod h1:ul1oT0FhSMDIExNjIxHqJoGpVrBpKCdgDQNxfqgJt7k=
|
github.com/blevesearch/vellum v1.0.10/go.mod h1:ul1oT0FhSMDIExNjIxHqJoGpVrBpKCdgDQNxfqgJt7k=
|
||||||
github.com/blevesearch/zapx/v11 v11.2.0/go.mod h1:gN/a0alGw1FZt/YGTo1G6Z6XpDkeOfujX5exY9sCQQM=
|
github.com/blevesearch/zapx/v11 v11.2.0/go.mod h1:gN/a0alGw1FZt/YGTo1G6Z6XpDkeOfujX5exY9sCQQM=
|
||||||
github.com/blevesearch/zapx/v11 v11.3.9 h1:y3ijS4h4MJdmQ07MHASxat4owAixreK2xdo76w9ncrw=
|
github.com/blevesearch/zapx/v11 v11.3.10 h1:hvjgj9tZ9DeIqBCxKhi70TtSZYMdcFn7gDb71Xo/fvk=
|
||||||
github.com/blevesearch/zapx/v11 v11.3.9/go.mod h1:jcAYnQwlr+LqD2vLjDWjWiZDXDXGFqPbpPDRTd3XmS4=
|
github.com/blevesearch/zapx/v11 v11.3.10/go.mod h1:0+gW+FaE48fNxoVtMY5ugtNHHof/PxCqh7CnhYdnMzQ=
|
||||||
github.com/blevesearch/zapx/v12 v12.2.0/go.mod h1:fdjwvCwWWwJW/EYTYGtAp3gBA0geCYGLcVTtJEZnY6A=
|
github.com/blevesearch/zapx/v12 v12.2.0/go.mod h1:fdjwvCwWWwJW/EYTYGtAp3gBA0geCYGLcVTtJEZnY6A=
|
||||||
github.com/blevesearch/zapx/v12 v12.3.9 h1:MXGLlZ03oxXH3DMJTZaBaRj2xb6t4wQVZeZK/wu1M6w=
|
github.com/blevesearch/zapx/v12 v12.3.10 h1:yHfj3vXLSYmmsBleJFROXuO08mS3L1qDCdDK81jDl8s=
|
||||||
github.com/blevesearch/zapx/v12 v12.3.9/go.mod h1:QXCMwmOkdLnMDgTN1P4CcuX5F851iUOtOwXbw0HMBYs=
|
github.com/blevesearch/zapx/v12 v12.3.10/go.mod h1:0yeZg6JhaGxITlsS5co73aqPtM04+ycnI6D1v0mhbCs=
|
||||||
github.com/blevesearch/zapx/v13 v13.2.0/go.mod h1:o5rAy/lRS5JpAbITdrOHBS/TugWYbkcYZTz6VfEinAQ=
|
github.com/blevesearch/zapx/v13 v13.2.0/go.mod h1:o5rAy/lRS5JpAbITdrOHBS/TugWYbkcYZTz6VfEinAQ=
|
||||||
github.com/blevesearch/zapx/v13 v13.3.9 h1:+VAz9V0VmllHXlZV4DCvfYj0nqaZHgF3MeEHwOyRBwQ=
|
github.com/blevesearch/zapx/v13 v13.3.10 h1:0KY9tuxg06rXxOZHg3DwPJBjniSlqEgVpxIqMGahDE8=
|
||||||
github.com/blevesearch/zapx/v13 v13.3.9/go.mod h1:s+WjNp4WSDtrBVBpa37DUOd7S/Gr/jTZ7ST/MbCVj/0=
|
github.com/blevesearch/zapx/v13 v13.3.10/go.mod h1:w2wjSDQ/WBVeEIvP0fvMJZAzDwqwIEzVPnCPrz93yAk=
|
||||||
github.com/blevesearch/zapx/v14 v14.2.0/go.mod h1:GNgZusc1p4ot040cBQMRGEZobvwjCquiEKYh1xLFK9g=
|
github.com/blevesearch/zapx/v14 v14.2.0/go.mod h1:GNgZusc1p4ot040cBQMRGEZobvwjCquiEKYh1xLFK9g=
|
||||||
github.com/blevesearch/zapx/v14 v14.3.9 h1:wuqxATgsTCNHM9xsOFOeFp8H2heZ/gMX/tsl9lRK8U4=
|
github.com/blevesearch/zapx/v14 v14.3.10 h1:SG6xlsL+W6YjhX5N3aEiL/2tcWh3DO75Bnz77pSwwKU=
|
||||||
github.com/blevesearch/zapx/v14 v14.3.9/go.mod h1:MWZ4v8AzFBRurhDzkLvokFW8ljcq9Evm27mkWe8OGbM=
|
github.com/blevesearch/zapx/v14 v14.3.10/go.mod h1:qqyuR0u230jN1yMmE4FIAuCxmahRQEOehF78m6oTgns=
|
||||||
github.com/blevesearch/zapx/v15 v15.2.0/go.mod h1:MmQceLpWfME4n1WrBFIwplhWmaQbQqLQARpaKUEOs/A=
|
github.com/blevesearch/zapx/v15 v15.2.0/go.mod h1:MmQceLpWfME4n1WrBFIwplhWmaQbQqLQARpaKUEOs/A=
|
||||||
github.com/blevesearch/zapx/v15 v15.3.12 h1:w/kU9aHyfMDEdwHGZzCiakC3HZ9z5gYlXaALDC4Dct8=
|
github.com/blevesearch/zapx/v15 v15.3.13 h1:6EkfaZiPlAxqXz0neniq35my6S48QI94W/wyhnpDHHQ=
|
||||||
github.com/blevesearch/zapx/v15 v15.3.12/go.mod h1:tx53gDJS/7Oa3Je820cmVurqCuJ4dqdAy1kiDMV/IUo=
|
github.com/blevesearch/zapx/v15 v15.3.13/go.mod h1:Turk/TNRKj9es7ZpKK95PS7f6D44Y7fAFy8F4LXQtGg=
|
||||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||||
github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs=
|
github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs=
|
||||||
github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
|
||||||
|
@ -22,7 +22,7 @@ type ActionRunnerToken struct {
|
|||||||
Owner *user_model.User `xorm:"-"`
|
Owner *user_model.User `xorm:"-"`
|
||||||
RepoID int64 `xorm:"index"` // repo level runner, if orgid also is zero, then it's a global
|
RepoID int64 `xorm:"index"` // repo level runner, if orgid also is zero, then it's a global
|
||||||
Repo *repo_model.Repository `xorm:"-"`
|
Repo *repo_model.Repository `xorm:"-"`
|
||||||
IsActive bool
|
IsActive bool // true means it can be used
|
||||||
|
|
||||||
Created timeutil.TimeStamp `xorm:"created"`
|
Created timeutil.TimeStamp `xorm:"created"`
|
||||||
Updated timeutil.TimeStamp `xorm:"updated"`
|
Updated timeutil.TimeStamp `xorm:"updated"`
|
||||||
@ -57,7 +57,7 @@ func UpdateRunnerToken(ctx context.Context, r *ActionRunnerToken, cols ...string
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRunnerToken creates a new runner token
|
// NewRunnerToken creates a new active runner token and invalidate all old tokens
|
||||||
func NewRunnerToken(ctx context.Context, ownerID, repoID int64) (*ActionRunnerToken, error) {
|
func NewRunnerToken(ctx context.Context, ownerID, repoID int64) (*ActionRunnerToken, error) {
|
||||||
token, err := util.CryptoRandomString(40)
|
token, err := util.CryptoRandomString(40)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -66,17 +66,27 @@ func NewRunnerToken(ctx context.Context, ownerID, repoID int64) (*ActionRunnerTo
|
|||||||
runnerToken := &ActionRunnerToken{
|
runnerToken := &ActionRunnerToken{
|
||||||
OwnerID: ownerID,
|
OwnerID: ownerID,
|
||||||
RepoID: repoID,
|
RepoID: repoID,
|
||||||
IsActive: false,
|
IsActive: true,
|
||||||
Token: token,
|
Token: token,
|
||||||
}
|
}
|
||||||
_, err = db.GetEngine(ctx).Insert(runnerToken)
|
|
||||||
return runnerToken, err
|
return runnerToken, db.WithTx(ctx, func(ctx context.Context) error {
|
||||||
|
if _, err := db.GetEngine(ctx).Where("owner_id =? AND repo_id = ?", ownerID, repoID).Cols("is_active").Update(&ActionRunnerToken{
|
||||||
|
IsActive: false,
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = db.GetEngine(ctx).Insert(runnerToken)
|
||||||
|
return err
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUnactivatedRunnerToken returns a unactivated runner token
|
// GetLastestRunnerToken returns the latest runner token
|
||||||
func GetUnactivatedRunnerToken(ctx context.Context, ownerID, repoID int64) (*ActionRunnerToken, error) {
|
func GetLastestRunnerToken(ctx context.Context, ownerID, repoID int64) (*ActionRunnerToken, error) {
|
||||||
var runnerToken ActionRunnerToken
|
var runnerToken ActionRunnerToken
|
||||||
has, err := db.GetEngine(ctx).Where("owner_id=? AND repo_id=? AND is_active=?", ownerID, repoID, false).OrderBy("id DESC").Get(&runnerToken)
|
has, err := db.GetEngine(ctx).Where("owner_id=? AND repo_id=?", ownerID, repoID).
|
||||||
|
OrderBy("id DESC").Get(&runnerToken)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
} else if !has {
|
} else if !has {
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package activities_test
|
package activities_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
@ -14,7 +13,5 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package asymkey
|
package asymkey
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
@ -12,7 +11,6 @@ import (
|
|||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m, &unittest.TestOptions{
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
FixtureFiles: []string{
|
FixtureFiles: []string{
|
||||||
"gpg_key.yml",
|
"gpg_key.yml",
|
||||||
"public_key.yml",
|
"public_key.yml",
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package auth_test
|
package auth_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
@ -17,7 +16,5 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package avatars_test
|
package avatars_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
@ -15,7 +14,5 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package db_test
|
package db_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
@ -14,7 +13,5 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -4,14 +4,11 @@
|
|||||||
package paginator
|
package paginator
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", "..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -4,14 +4,11 @@
|
|||||||
package dbfs
|
package dbfs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package git_test
|
package git_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
@ -15,7 +14,5 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package issues_test
|
package issues_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
issues_model "code.gitea.io/gitea/models/issues"
|
issues_model "code.gitea.io/gitea/models/issues"
|
||||||
@ -30,7 +29,5 @@ func TestFixturesAreConsistent(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,5 @@ func TestFixturesAreConsistent(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: "..",
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package organization_test
|
package organization_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
@ -18,7 +17,5 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package packages_test
|
package packages_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
@ -20,9 +19,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHasOwnerPackages(t *testing.T) {
|
func TestHasOwnerPackages(t *testing.T) {
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package access_test
|
package access_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
@ -17,7 +16,5 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", "..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package project
|
package project
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
@ -14,7 +13,6 @@ import (
|
|||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m, &unittest.TestOptions{
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
FixtureFiles: []string{
|
FixtureFiles: []string{
|
||||||
"project.yml",
|
"project.yml",
|
||||||
"project_board.yml",
|
"project_board.yml",
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package repo_test
|
package repo_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
@ -18,7 +17,5 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package system_test
|
package system_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
@ -16,7 +15,5 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -62,35 +62,46 @@ func InitSettings(extraConfigs ...string) {
|
|||||||
|
|
||||||
// TestOptions represents test options
|
// TestOptions represents test options
|
||||||
type TestOptions struct {
|
type TestOptions struct {
|
||||||
GiteaRootPath string
|
FixtureFiles []string
|
||||||
FixtureFiles []string
|
SetUp func() error // SetUp will be executed before all tests in this package
|
||||||
SetUp func() error // SetUp will be executed before all tests in this package
|
TearDown func() error // TearDown will be executed after all tests in this package
|
||||||
TearDown func() error // TearDown will be executed after all tests in this package
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MainTest a reusable TestMain(..) function for unit tests that need to use a
|
// MainTest a reusable TestMain(..) function for unit tests that need to use a
|
||||||
// test database. Creates the test database, and sets necessary settings.
|
// test database. Creates the test database, and sets necessary settings.
|
||||||
func MainTest(m *testing.M, testOpts *TestOptions) {
|
func MainTest(m *testing.M, testOpts ...*TestOptions) {
|
||||||
setting.CustomPath = filepath.Join(testOpts.GiteaRootPath, "custom")
|
searchDir, _ := os.Getwd()
|
||||||
|
for searchDir != "" {
|
||||||
|
if _, err := os.Stat(filepath.Join(searchDir, "go.mod")); err == nil {
|
||||||
|
break // The "go.mod" should be the one for Gitea repository
|
||||||
|
}
|
||||||
|
if dir := filepath.Dir(searchDir); dir == searchDir {
|
||||||
|
searchDir = "" // reaches the root of filesystem
|
||||||
|
} else {
|
||||||
|
searchDir = dir
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if searchDir == "" {
|
||||||
|
panic("The tests should run in a Gitea repository, there should be a 'go.mod' in the root")
|
||||||
|
}
|
||||||
|
|
||||||
|
giteaRoot = searchDir
|
||||||
|
setting.CustomPath = filepath.Join(giteaRoot, "custom")
|
||||||
InitSettings()
|
InitSettings()
|
||||||
|
|
||||||
var err error
|
fixturesDir = filepath.Join(giteaRoot, "models", "fixtures")
|
||||||
|
|
||||||
giteaRoot = testOpts.GiteaRootPath
|
|
||||||
fixturesDir = filepath.Join(testOpts.GiteaRootPath, "models", "fixtures")
|
|
||||||
|
|
||||||
var opts FixturesOptions
|
var opts FixturesOptions
|
||||||
if len(testOpts.FixtureFiles) == 0 {
|
if len(testOpts) == 0 || len(testOpts[0].FixtureFiles) == 0 {
|
||||||
opts.Dir = fixturesDir
|
opts.Dir = fixturesDir
|
||||||
} else {
|
} else {
|
||||||
for _, f := range testOpts.FixtureFiles {
|
for _, f := range testOpts[0].FixtureFiles {
|
||||||
if len(f) != 0 {
|
if len(f) != 0 {
|
||||||
opts.Files = append(opts.Files, filepath.Join(fixturesDir, f))
|
opts.Files = append(opts.Files, filepath.Join(fixturesDir, f))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = CreateTestEngine(opts); err != nil {
|
if err := CreateTestEngine(opts); err != nil {
|
||||||
fatalTestError("Error creating test engine: %v\n", err)
|
fatalTestError("Error creating test engine: %v\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,8 +123,8 @@ func MainTest(m *testing.M, testOpts *TestOptions) {
|
|||||||
fatalTestError("TempDir: %v\n", err)
|
fatalTestError("TempDir: %v\n", err)
|
||||||
}
|
}
|
||||||
setting.AppDataPath = appDataPath
|
setting.AppDataPath = appDataPath
|
||||||
setting.AppWorkPath = testOpts.GiteaRootPath
|
setting.AppWorkPath = giteaRoot
|
||||||
setting.StaticRootPath = testOpts.GiteaRootPath
|
setting.StaticRootPath = giteaRoot
|
||||||
setting.GravatarSource = "https://secure.gravatar.com/avatar/"
|
setting.GravatarSource = "https://secure.gravatar.com/avatar/"
|
||||||
|
|
||||||
setting.Attachment.Storage.Path = filepath.Join(setting.AppDataPath, "attachments")
|
setting.Attachment.Storage.Path = filepath.Join(setting.AppDataPath, "attachments")
|
||||||
@ -144,7 +155,7 @@ func MainTest(m *testing.M, testOpts *TestOptions) {
|
|||||||
if err = util.RemoveAll(repoRootPath); err != nil {
|
if err = util.RemoveAll(repoRootPath); err != nil {
|
||||||
fatalTestError("util.RemoveAll: %v\n", err)
|
fatalTestError("util.RemoveAll: %v\n", err)
|
||||||
}
|
}
|
||||||
if err = CopyDir(filepath.Join(testOpts.GiteaRootPath, "tests", "gitea-repositories-meta"), setting.RepoRootPath); err != nil {
|
if err = CopyDir(filepath.Join(giteaRoot, "tests", "gitea-repositories-meta"), setting.RepoRootPath); err != nil {
|
||||||
fatalTestError("util.CopyDir: %v\n", err)
|
fatalTestError("util.CopyDir: %v\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -171,16 +182,16 @@ func MainTest(m *testing.M, testOpts *TestOptions) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if testOpts.SetUp != nil {
|
if len(testOpts) > 0 && testOpts[0].SetUp != nil {
|
||||||
if err := testOpts.SetUp(); err != nil {
|
if err := testOpts[0].SetUp(); err != nil {
|
||||||
fatalTestError("set up failed: %v\n", err)
|
fatalTestError("set up failed: %v\n", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exitStatus := m.Run()
|
exitStatus := m.Run()
|
||||||
|
|
||||||
if testOpts.TearDown != nil {
|
if len(testOpts) > 0 && testOpts[0].TearDown != nil {
|
||||||
if err := testOpts.TearDown(); err != nil {
|
if err := testOpts[0].TearDown(); err != nil {
|
||||||
fatalTestError("tear down failed: %v\n", err)
|
fatalTestError("tear down failed: %v\n", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package user_test
|
package user_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
@ -16,7 +15,5 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package webhook
|
package webhook
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
@ -12,7 +11,6 @@ import (
|
|||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m, &unittest.TestOptions{
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
FixtureFiles: []string{
|
FixtureFiles: []string{
|
||||||
"webhook.yml",
|
"webhook.yml",
|
||||||
"hook_task.yml",
|
"hook_task.yml",
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package activitypub
|
package activitypub
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
@ -15,7 +14,5 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -168,9 +168,9 @@ func checkDBConsistency(ctx context.Context, logger log.Logger, autofix bool) er
|
|||||||
// find protected branches without existing repository
|
// find protected branches without existing repository
|
||||||
genericOrphanCheck("Protected Branches without existing repository",
|
genericOrphanCheck("Protected Branches without existing repository",
|
||||||
"protected_branch", "repository", "protected_branch.repo_id=repository.id"),
|
"protected_branch", "repository", "protected_branch.repo_id=repository.id"),
|
||||||
// find deleted branches without existing repository
|
// find branches without existing repository
|
||||||
genericOrphanCheck("Deleted Branches without existing repository",
|
genericOrphanCheck("Branches without existing repository",
|
||||||
"deleted_branch", "repository", "deleted_branch.repo_id=repository.id"),
|
"branch", "repository", "branch.repo_id=repository.id"),
|
||||||
// find LFS locks without existing repository
|
// find LFS locks without existing repository
|
||||||
genericOrphanCheck("LFS locks without existing repository",
|
genericOrphanCheck("LFS locks without existing repository",
|
||||||
"lfs_lock", "repository", "lfs_lock.repo_id=repository.id"),
|
"lfs_lock", "repository", "lfs_lock.repo_id=repository.id"),
|
||||||
@ -189,6 +189,9 @@ func checkDBConsistency(ctx context.Context, logger log.Logger, autofix bool) er
|
|||||||
// find action without repository
|
// find action without repository
|
||||||
genericOrphanCheck("Action entries without existing repository",
|
genericOrphanCheck("Action entries without existing repository",
|
||||||
"action", "repository", "action.repo_id=repository.id"),
|
"action", "repository", "action.repo_id=repository.id"),
|
||||||
|
// find action without user
|
||||||
|
genericOrphanCheck("Action entries without existing user",
|
||||||
|
"action", "user", "action.act_user_id=`user`.id"),
|
||||||
// find OAuth2Grant without existing user
|
// find OAuth2Grant without existing user
|
||||||
genericOrphanCheck("Orphaned OAuth2Grant without existing User",
|
genericOrphanCheck("Orphaned OAuth2Grant without existing User",
|
||||||
"oauth2_grant", "user", "oauth2_grant.user_id=`user`.id"),
|
"oauth2_grant", "user", "oauth2_grant.user_id=`user`.id"),
|
||||||
|
@ -6,7 +6,6 @@ package code
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
@ -23,9 +22,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", "..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testIndexer(name string, t *testing.T, indexer internal.Indexer) {
|
func testIndexer(name string, t *testing.T, indexer internal.Indexer) {
|
||||||
|
@ -5,7 +5,6 @@ package issues
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/db"
|
"code.gitea.io/gitea/models/db"
|
||||||
@ -22,9 +21,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", "..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDBSearchIssues(t *testing.T) {
|
func TestDBSearchIssues(t *testing.T) {
|
||||||
|
@ -5,7 +5,6 @@ package stats
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -23,9 +22,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", "..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRepoStatsIndex(t *testing.T) {
|
func TestRepoStatsIndex(t *testing.T) {
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package repository
|
package repository
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
@ -13,7 +12,5 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package system
|
package system
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
@ -14,8 +13,7 @@ import (
|
|||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m, &unittest.TestOptions{
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
FixtureFiles: []string{""}, // load nothing
|
||||||
FixtureFiles: []string{""}, // load nothing
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +80,7 @@ milestones=マイルストーン
|
|||||||
|
|
||||||
ok=OK
|
ok=OK
|
||||||
cancel=キャンセル
|
cancel=キャンセル
|
||||||
|
retry=再試行
|
||||||
rerun=再実行
|
rerun=再実行
|
||||||
rerun_all=すべてのジョブを再実行
|
rerun_all=すべてのジョブを再実行
|
||||||
save=保存
|
save=保存
|
||||||
|
7
package-lock.json
generated
7
package-lock.json
generated
@ -67,6 +67,7 @@
|
|||||||
"eslint-plugin-regexp": "1.15.0",
|
"eslint-plugin-regexp": "1.15.0",
|
||||||
"eslint-plugin-sonarjs": "0.21.0",
|
"eslint-plugin-sonarjs": "0.21.0",
|
||||||
"eslint-plugin-unicorn": "48.0.1",
|
"eslint-plugin-unicorn": "48.0.1",
|
||||||
|
"eslint-plugin-vitest-globals": "1.4.0",
|
||||||
"eslint-plugin-vue": "9.17.0",
|
"eslint-plugin-vue": "9.17.0",
|
||||||
"eslint-plugin-vue-scoped-css": "2.5.0",
|
"eslint-plugin-vue-scoped-css": "2.5.0",
|
||||||
"eslint-plugin-wc": "2.0.3",
|
"eslint-plugin-wc": "2.0.3",
|
||||||
@ -4963,6 +4964,12 @@
|
|||||||
"eslint": ">=8.44.0"
|
"eslint": ">=8.44.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/eslint-plugin-vitest-globals": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-plugin-vitest-globals/-/eslint-plugin-vitest-globals-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-WE+YlK9X9s4vf5EaYRU0Scw7WItDZStm+PapFSYlg2ABNtaQ4zIG7wEqpoUB3SlfM+SgkhgmzR0TeJOO5k3/Nw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/eslint-plugin-vue": {
|
"node_modules/eslint-plugin-vue": {
|
||||||
"version": "9.17.0",
|
"version": "9.17.0",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.17.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.17.0.tgz",
|
||||||
|
@ -66,6 +66,7 @@
|
|||||||
"eslint-plugin-regexp": "1.15.0",
|
"eslint-plugin-regexp": "1.15.0",
|
||||||
"eslint-plugin-sonarjs": "0.21.0",
|
"eslint-plugin-sonarjs": "0.21.0",
|
||||||
"eslint-plugin-unicorn": "48.0.1",
|
"eslint-plugin-unicorn": "48.0.1",
|
||||||
|
"eslint-plugin-vitest-globals": "1.4.0",
|
||||||
"eslint-plugin-vue": "9.17.0",
|
"eslint-plugin-vue": "9.17.0",
|
||||||
"eslint-plugin-vue-scoped-css": "2.5.0",
|
"eslint-plugin-vue-scoped-css": "2.5.0",
|
||||||
"eslint-plugin-wc": "2.0.3",
|
"eslint-plugin-wc": "2.0.3",
|
||||||
|
@ -47,11 +47,11 @@ func (s *Service) Register(
|
|||||||
|
|
||||||
runnerToken, err := actions_model.GetRunnerToken(ctx, req.Msg.Token)
|
runnerToken, err := actions_model.GetRunnerToken(ctx, req.Msg.Token)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.New("runner token not found")
|
return nil, errors.New("runner registration token not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
if runnerToken.IsActive {
|
if !runnerToken.IsActive {
|
||||||
return nil, errors.New("runner token has already been activated")
|
return nil, errors.New("runner registration token has been invalidated, please use the latest one")
|
||||||
}
|
}
|
||||||
|
|
||||||
labels := req.Msg.Labels
|
labels := req.Msg.Labels
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package repo
|
package repo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
@ -14,7 +13,6 @@ import (
|
|||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m, &unittest.TestOptions{
|
||||||
GiteaRootPath: filepath.Join("..", "..", "..", ".."),
|
|
||||||
SetUp: func() error {
|
SetUp: func() error {
|
||||||
setting.LoadQueueSettings()
|
setting.LoadQueueSettings()
|
||||||
return webhook_service.Init()
|
return webhook_service.Init()
|
||||||
|
@ -9,7 +9,6 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"net/url"
|
"net/url"
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
@ -35,7 +34,5 @@ func TestRenderPanicErrorPage(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ package install
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
@ -35,7 +34,5 @@ func TestRoutes(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -41,8 +41,8 @@ func GenerateActionsRunnerToken(ctx *context.PrivateContext) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
token, err := actions_model.GetUnactivatedRunnerToken(ctx, owner, repo)
|
token, err := actions_model.GetLastestRunnerToken(ctx, owner, repo)
|
||||||
if errors.Is(err, util.ErrNotExist) {
|
if errors.Is(err, util.ErrNotExist) || (token != nil && !token.IsActive) {
|
||||||
token, err = actions_model.NewRunnerToken(ctx, owner, repo)
|
token, err = actions_model.NewRunnerToken(ctx, owner, repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err := fmt.Sprintf("error while creating runner token: %v", err)
|
err := fmt.Sprintf("error while creating runner token: %v", err)
|
||||||
|
@ -4,14 +4,11 @@
|
|||||||
package private
|
package private
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -4,14 +4,11 @@
|
|||||||
package admin
|
package admin
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", "..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -4,14 +4,11 @@
|
|||||||
package auth
|
package auth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", "..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -4,14 +4,11 @@
|
|||||||
package org_test
|
package org_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", "..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -4,14 +4,11 @@
|
|||||||
package repo
|
package repo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", "..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -4,14 +4,11 @@
|
|||||||
package setting
|
package setting
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", "..", "..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -35,15 +35,15 @@ func RunnersList(ctx *context.Context, opts actions_model.FindRunnerOptions) {
|
|||||||
|
|
||||||
// ownid=0,repo_id=0,means this token is used for global
|
// ownid=0,repo_id=0,means this token is used for global
|
||||||
var token *actions_model.ActionRunnerToken
|
var token *actions_model.ActionRunnerToken
|
||||||
token, err = actions_model.GetUnactivatedRunnerToken(ctx, opts.OwnerID, opts.RepoID)
|
token, err = actions_model.GetLastestRunnerToken(ctx, opts.OwnerID, opts.RepoID)
|
||||||
if errors.Is(err, util.ErrNotExist) {
|
if errors.Is(err, util.ErrNotExist) || (token != nil && !token.IsActive) {
|
||||||
token, err = actions_model.NewRunnerToken(ctx, opts.OwnerID, opts.RepoID)
|
token, err = actions_model.NewRunnerToken(ctx, opts.OwnerID, opts.RepoID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.ServerError("CreateRunnerToken", err)
|
ctx.ServerError("CreateRunnerToken", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
ctx.ServerError("GetUnactivatedRunnerToken", err)
|
ctx.ServerError("GetLastestRunnerToken", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,14 +4,11 @@
|
|||||||
package user
|
package user
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", "..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -4,14 +4,11 @@
|
|||||||
package setting
|
package setting
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", "..", "..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package asymkey
|
package asymkey
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
@ -14,7 +13,5 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUploadAttachment(t *testing.T) {
|
func TestUploadAttachment(t *testing.T) {
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package convert
|
package convert
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
@ -13,7 +12,5 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package feed
|
package feed
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -20,9 +19,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRenameRepoAction(t *testing.T) {
|
func TestRenameRepoAction(t *testing.T) {
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package gitdiff
|
package gitdiff
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
@ -15,7 +14,5 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package issue
|
package issue
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
@ -13,7 +12,5 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package mailer
|
package mailer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
@ -13,7 +12,5 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package markup
|
package markup
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
@ -12,7 +11,6 @@ import (
|
|||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m, &unittest.TestOptions{
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
FixtureFiles: []string{"user.yml"},
|
||||||
FixtureFiles: []string{"user.yml"},
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
package migrations
|
package migrations
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -16,9 +15,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func timePtr(t time.Time) *time.Time {
|
func timePtr(t time.Time) *time.Time {
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package org
|
package org
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models"
|
"code.gitea.io/gitea/models"
|
||||||
@ -16,9 +15,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeleteOrganization(t *testing.T) {
|
func TestDeleteOrganization(t *testing.T) {
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
package pull
|
package pull
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
@ -14,7 +13,5 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package release
|
package release
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
@ -22,9 +21,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRelease_Create(t *testing.T) {
|
func TestRelease_Create(t *testing.T) {
|
||||||
|
@ -5,7 +5,6 @@ package archiver
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -18,9 +17,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", "..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestArchive_Basic(t *testing.T) {
|
func TestArchive_Basic(t *testing.T) {
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package files
|
package files
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
repo_model "code.gitea.io/gitea/models/repo"
|
repo_model "code.gitea.io/gitea/models/repo"
|
||||||
@ -19,9 +18,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", "..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func getExpectedReadmeContentsResponse() *api.ContentsResponse {
|
func getExpectedReadmeContentsResponse() *api.ContentsResponse {
|
||||||
|
@ -4,14 +4,11 @@
|
|||||||
package repository
|
package repository
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ package user
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -22,9 +21,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDeleteUser(t *testing.T) {
|
func TestDeleteUser(t *testing.T) {
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
package webhook
|
package webhook
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"code.gitea.io/gitea/models/unittest"
|
"code.gitea.io/gitea/models/unittest"
|
||||||
@ -19,7 +18,6 @@ func TestMain(m *testing.M) {
|
|||||||
// for tests, allow only loopback IPs
|
// for tests, allow only loopback IPs
|
||||||
setting.Webhook.AllowedHostList = hostmatcher.MatchBuiltinLoopback
|
setting.Webhook.AllowedHostList = hostmatcher.MatchBuiltinLoopback
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m, &unittest.TestOptions{
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
SetUp: func() error {
|
SetUp: func() error {
|
||||||
setting.LoadQueueSettings()
|
setting.LoadQueueSettings()
|
||||||
return Init()
|
return Init()
|
||||||
|
@ -5,7 +5,6 @@ package wiki
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -20,9 +19,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
unittest.MainTest(m, &unittest.TestOptions{
|
unittest.MainTest(m)
|
||||||
GiteaRootPath: filepath.Join("..", ".."),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestWebPathSegments(t *testing.T) {
|
func TestWebPathSegments(t *testing.T) {
|
||||||
|
@ -19,12 +19,12 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
{{if .DefaultBranchBranch.IsProtected}}
|
|
||||||
{{svg "octicon-shield-lock"}}
|
|
||||||
{{end}}
|
|
||||||
<div class="gt-df gt-ac">
|
<div class="gt-df gt-ac">
|
||||||
|
{{if .DefaultBranchBranch.IsProtected}}
|
||||||
|
<span class="gt-df gt-pr-2">{{svg "octicon-shield-lock"}}</span>
|
||||||
|
{{end}}
|
||||||
<a class="gt-ellipsis" href="{{.RepoLink}}/src/branch/{{PathEscapeSegments .DefaultBranchBranch.DBBranch.Name}}">{{.DefaultBranchBranch.DBBranch.Name}}</a>
|
<a class="gt-ellipsis" href="{{.RepoLink}}/src/branch/{{PathEscapeSegments .DefaultBranchBranch.DBBranch.Name}}">{{.DefaultBranchBranch.DBBranch.Name}}</a>
|
||||||
<button class="btn interact-fg gt-p-3" data-clipboard-text="{{.DefaultBranchBranch.DBBranch.Name}}">{{svg "octicon-copy" 14}}</button>
|
<button class="btn interact-fg gt-df gt-p-3" data-clipboard-text="{{.DefaultBranchBranch.DBBranch.Name}}">{{svg "octicon-copy" 14}}</button>
|
||||||
{{template "repo/commit_statuses" dict "Status" (index $.CommitStatus .DefaultBranchBranch.DBBranch.CommitID) "Statuses" (index $.CommitStatuses .DefaultBranchBranch.DBBranch.CommitID)}}
|
{{template "repo/commit_statuses" dict "Status" (index $.CommitStatus .DefaultBranchBranch.DBBranch.CommitID) "Statuses" (index $.CommitStatuses .DefaultBranchBranch.DBBranch.CommitID)}}
|
||||||
</div>
|
</div>
|
||||||
<p class="info gt-df gt-ac gt-my-2">{{svg "octicon-git-commit" 16 "gt-mr-2"}}<a href="{{.RepoLink}}/commit/{{PathEscape .DefaultBranchBranch.DBBranch.CommitID}}">{{ShortSha .DefaultBranchBranch.DBBranch.CommitID}}</a> · <span class="commit-message">{{RenderCommitMessage $.Context .DefaultBranchBranch.DBBranch.CommitMessage .RepoLink .Repository.ComposeMetas}}</span> · {{ctx.Locale.Tr "org.repo_updated"}} {{TimeSince .DefaultBranchBranch.DBBranch.CommitTime.AsTime ctx.Locale}}{{if .DefaultBranchBranch.DBBranch.Pusher}} {{template "shared/user/avatarlink" dict "user" .DefaultBranchBranch.DBBranch.Pusher}}{{template "shared/user/namelink" .DefaultBranchBranch.DBBranch.Pusher}}{{end}}</p>
|
<p class="info gt-df gt-ac gt-my-2">{{svg "octicon-git-commit" 16 "gt-mr-2"}}<a href="{{.RepoLink}}/commit/{{PathEscape .DefaultBranchBranch.DBBranch.CommitID}}">{{ShortSha .DefaultBranchBranch.DBBranch.CommitID}}</a> · <span class="commit-message">{{RenderCommitMessage $.Context .DefaultBranchBranch.DBBranch.CommitMessage .RepoLink .Repository.ComposeMetas}}</span> · {{ctx.Locale.Tr "org.repo_updated"}} {{TimeSince .DefaultBranchBranch.DBBranch.CommitTime.AsTime ctx.Locale}}{{if .DefaultBranchBranch.DBBranch.Pusher}} {{template "shared/user/avatarlink" dict "user" .DefaultBranchBranch.DBBranch.Pusher}}{{template "shared/user/namelink" .DefaultBranchBranch.DBBranch.Pusher}}{{end}}</p>
|
||||||
@ -97,12 +97,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<p class="info">{{ctx.Locale.Tr "repo.branch.deleted_by" .DBBranch.DeletedBy.Name}} {{TimeSinceUnix .DBBranch.DeletedUnix ctx.Locale}}</p>
|
<p class="info">{{ctx.Locale.Tr "repo.branch.deleted_by" .DBBranch.DeletedBy.Name}} {{TimeSinceUnix .DBBranch.DeletedUnix ctx.Locale}}</p>
|
||||||
{{else}}
|
{{else}}
|
||||||
{{if .IsProtected}}
|
|
||||||
{{svg "octicon-shield-lock"}}
|
|
||||||
{{end}}
|
|
||||||
<div class="gt-df gt-ac">
|
<div class="gt-df gt-ac">
|
||||||
|
{{if .IsProtected}}
|
||||||
|
<span class="gt-df gt-pr-2">{{svg "octicon-shield-lock"}}</span>
|
||||||
|
{{end}}
|
||||||
<a class="gt-ellipsis" href="{{$.RepoLink}}/src/branch/{{PathEscapeSegments .DBBranch.Name}}">{{.DBBranch.Name}}</a>
|
<a class="gt-ellipsis" href="{{$.RepoLink}}/src/branch/{{PathEscapeSegments .DBBranch.Name}}">{{.DBBranch.Name}}</a>
|
||||||
<button class="btn interact-fg gt-p-3" data-clipboard-text="{{.DBBranch.Name}}">{{svg "octicon-copy" 14}}</button>
|
<button class="btn interact-fg gt-df gt-p-3" data-clipboard-text="{{.DBBranch.Name}}">{{svg "octicon-copy" 14}}</button>
|
||||||
{{template "repo/commit_statuses" dict "Status" (index $.CommitStatus .DBBranch.CommitID) "Statuses" (index $.CommitStatuses .DBBranch.CommitID)}}
|
{{template "repo/commit_statuses" dict "Status" (index $.CommitStatus .DBBranch.CommitID) "Statuses" (index $.CommitStatuses .DBBranch.CommitID)}}
|
||||||
</div>
|
</div>
|
||||||
<p class="info gt-df gt-ac gt-my-2">{{svg "octicon-git-commit" 16 "gt-mr-2"}}<a href="{{$.RepoLink}}/commit/{{PathEscape .DBBranch.CommitID}}">{{ShortSha .DBBranch.CommitID}}</a> · <span class="commit-message">{{RenderCommitMessage $.Context .DBBranch.CommitMessage $.RepoLink $.Repository.ComposeMetas}}</span> · {{ctx.Locale.Tr "org.repo_updated"}} {{TimeSince .DBBranch.CommitTime.AsTime ctx.Locale}}{{if .DBBranch.Pusher}} {{template "shared/user/avatarlink" dict "user" .DBBranch.Pusher}} {{template "shared/user/namelink" .DBBranch.Pusher}}{{end}}</p>
|
<p class="info gt-df gt-ac gt-my-2">{{svg "octicon-git-commit" 16 "gt-mr-2"}}<a href="{{$.RepoLink}}/commit/{{PathEscape .DBBranch.CommitID}}">{{ShortSha .DBBranch.CommitID}}</a> · <span class="commit-message">{{RenderCommitMessage $.Context .DBBranch.CommitMessage $.RepoLink $.Repository.ComposeMetas}}</span> · {{ctx.Locale.Tr "org.repo_updated"}} {{TimeSince .DBBranch.CommitTime.AsTime ctx.Locale}}{{if .DBBranch.Pusher}} {{template "shared/user/avatarlink" dict "user" .DBBranch.Pusher}} {{template "shared/user/namelink" .DBBranch.Pusher}}{{end}}</p>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<!-- make sure this matches the color logic in web_src/js/components/DashboardRepoList.vue -->
|
<!-- make sure this matches the color logic in web_src/js/components/DashboardRepoList.vue -->
|
||||||
|
<span class="gt-df">
|
||||||
{{if eq .State "pending"}}
|
{{if eq .State "pending"}}
|
||||||
{{svg "octicon-dot-fill" 18 "commit-status icon text yellow"}}
|
{{svg "octicon-dot-fill" 18 "commit-status icon text yellow"}}
|
||||||
{{end}}
|
{{end}}
|
||||||
@ -11,3 +12,4 @@
|
|||||||
{{if eq .State "failure"}}
|
{{if eq .State "failure"}}
|
||||||
{{svg "octicon-x" 18 "commit-status icon text red"}}
|
{{svg "octicon-x" 18 "commit-status icon text red"}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
</span>
|
||||||
|
@ -11,6 +11,7 @@ export default defineConfig({
|
|||||||
open: false,
|
open: false,
|
||||||
allowOnly: true,
|
allowOnly: true,
|
||||||
passWithNoTests: true,
|
passWithNoTests: true,
|
||||||
|
globals: true,
|
||||||
watch: false,
|
watch: false,
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import {test, expect} from 'vitest';
|
|
||||||
import {parseIssueListQuickGotoLink} from './common-issue-list.js';
|
import {parseIssueListQuickGotoLink} from './common-issue-list.js';
|
||||||
|
|
||||||
test('parseIssueListQuickGotoLink', () => {
|
test('parseIssueListQuickGotoLink', () => {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import {test, expect} from 'vitest';
|
|
||||||
import {singleAnchorRegex, rangeAnchorRegex} from './repo-code.js';
|
import {singleAnchorRegex, rangeAnchorRegex} from './repo-code.js';
|
||||||
|
|
||||||
test('singleAnchorRegex', () => {
|
test('singleAnchorRegex', () => {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import {describe, expect, test} from 'vitest';
|
|
||||||
import {strSubMatch, calcMatchedWeight, filterRepoFilesWeighted} from './repo-findfile.js';
|
import {strSubMatch, calcMatchedWeight, filterRepoFilesWeighted} from './repo-findfile.js';
|
||||||
|
|
||||||
describe('Repo Find Files', () => {
|
describe('Repo Find Files', () => {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import {test, expect} from 'vitest';
|
|
||||||
import {GET, POST, PATCH, PUT, DELETE} from './fetch.js';
|
import {GET, POST, PATCH, PUT, DELETE} from './fetch.js';
|
||||||
|
|
||||||
// tests here are only to satisfy the linter for unused functions
|
// tests here are only to satisfy the linter for unused functions
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import {test, expect} from 'vitest';
|
|
||||||
import {showInfoToast, showErrorToast, showWarningToast} from './toast.js';
|
import {showInfoToast, showErrorToast, showWarningToast} from './toast.js';
|
||||||
|
|
||||||
test('showInfoToast', async () => {
|
test('showInfoToast', async () => {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import {expect, test} from 'vitest';
|
|
||||||
import {renderAnsi} from './ansi.js';
|
import {renderAnsi} from './ansi.js';
|
||||||
|
|
||||||
test('renderAnsi', () => {
|
test('renderAnsi', () => {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import {expect, test} from 'vitest';
|
|
||||||
import {svg, SvgIcon, svgParseOuterInner} from './svg.js';
|
import {svg, SvgIcon, svgParseOuterInner} from './svg.js';
|
||||||
import {createApp, h} from 'vue';
|
import {createApp, h} from 'vue';
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import {expect, test} from 'vitest';
|
|
||||||
import {
|
import {
|
||||||
basename, extname, isObject, stripTags, parseIssueHref,
|
basename, extname, isObject, stripTags, parseIssueHref,
|
||||||
parseUrl, translateMonth, translateDay, blobToDataURI,
|
parseUrl, translateMonth, translateDay, blobToDataURI,
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import {test, expect} from 'vitest';
|
|
||||||
import {useLightTextOnBackground} from './color.js';
|
import {useLightTextOnBackground} from './color.js';
|
||||||
|
|
||||||
test('useLightTextOnBackground', () => {
|
test('useLightTextOnBackground', () => {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import {test, expect} from 'vitest';
|
|
||||||
import {matchEmoji, matchMention} from './match.js';
|
import {matchEmoji, matchMention} from './match.js';
|
||||||
|
|
||||||
test('matchEmoji', () => {
|
test('matchEmoji', () => {
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import {expect, test} from 'vitest';
|
|
||||||
import {pathEscapeSegments} from './url.js';
|
import {pathEscapeSegments} from './url.js';
|
||||||
|
|
||||||
test('pathEscapeSegments', () => {
|
test('pathEscapeSegments', () => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user