初始提交: Gitea 项目代码
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package forms
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"gitea.dev/modules/structs"
|
||||
"gitea.dev/modules/web/middleware"
|
||||
"gitea.dev/services/context"
|
||||
|
||||
"gitea.com/go-chi/binding"
|
||||
)
|
||||
|
||||
// AdminCreateUserForm form for admin to create user
|
||||
type AdminCreateUserForm struct {
|
||||
LoginType string `binding:"Required"`
|
||||
LoginName string
|
||||
UserName string `binding:"Required;Username;MaxSize(40)"`
|
||||
Email string `binding:"Required;Email;MaxSize(254)"`
|
||||
Password string `binding:"MaxSize(255)"`
|
||||
SendNotify bool
|
||||
MustChangePassword bool
|
||||
Visibility structs.VisibleType
|
||||
}
|
||||
|
||||
// AdminCreateBadgeForm form for admin to create badge
|
||||
type AdminCreateBadgeForm struct {
|
||||
Slug string `binding:"Required;BadgeSlug" locale:"admin.badges.slug"`
|
||||
Description string `binding:"Required" locale:"admin.badges.description"`
|
||||
ImageURL string `binding:"ValidUrl" locale:"admin.badges.image_url"`
|
||||
}
|
||||
|
||||
// AdminEditBadgeForm form for admin to edit badge
|
||||
type AdminEditBadgeForm struct {
|
||||
Description string `binding:"Required" locale:"admin.badges.description"`
|
||||
ImageURL string `binding:"ValidUrl" locale:"admin.badges.image_url"`
|
||||
}
|
||||
|
||||
// Validate validates form fields
|
||||
func (f *AdminCreateBadgeForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// Validate validates form fields
|
||||
func (f *AdminEditBadgeForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// Validate validates form fields
|
||||
func (f *AdminCreateUserForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// AdminEditUserForm form for admin to create user
|
||||
type AdminEditUserForm struct {
|
||||
LoginType string `binding:"Required"`
|
||||
UserName string `binding:"Username;MaxSize(40)"`
|
||||
LoginName string
|
||||
FullName string `binding:"MaxSize(100)"`
|
||||
Email string `binding:"Required;Email;MaxSize(254)"`
|
||||
Password string `binding:"MaxSize(255)"`
|
||||
Website string `binding:"ValidUrl;MaxSize(255)"`
|
||||
Location string `binding:"MaxSize(50)"`
|
||||
Language string `binding:"MaxSize(5)"`
|
||||
MaxRepoCreation int
|
||||
Active bool
|
||||
Admin bool
|
||||
Restricted bool
|
||||
AllowGitHook bool
|
||||
AllowImportLocal bool
|
||||
AllowCreateOrganization bool
|
||||
ProhibitLogin bool
|
||||
Reset2FA bool `form:"reset_2fa"`
|
||||
Visibility structs.VisibleType
|
||||
}
|
||||
|
||||
// Validate validates form fields
|
||||
func (f *AdminEditUserForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// AdminDashboardForm form for admin dashboard operations
|
||||
type AdminDashboardForm struct {
|
||||
Op string `binding:"required"`
|
||||
From string
|
||||
}
|
||||
|
||||
// Validate validates form fields
|
||||
func (f *AdminDashboardForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package forms
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"gitea.dev/modules/web/middleware"
|
||||
"gitea.dev/services/context"
|
||||
|
||||
"gitea.com/go-chi/binding"
|
||||
)
|
||||
|
||||
// AuthenticationForm form for authentication
|
||||
type AuthenticationForm struct {
|
||||
Type int `binding:"Range(2,7)"`
|
||||
Name string `binding:"Required;MaxSize(30)"`
|
||||
TwoFactorPolicy string
|
||||
IsActive bool
|
||||
IsSyncEnabled bool
|
||||
|
||||
// LDAP
|
||||
Host string
|
||||
Port int
|
||||
BindDN string
|
||||
BindPassword string
|
||||
UserBase string
|
||||
UserDN string
|
||||
AttributeUsername string
|
||||
AttributeName string
|
||||
AttributeSurname string
|
||||
AttributeMail string
|
||||
AttributeSSHPublicKey string
|
||||
AttributeAvatar string
|
||||
SSHKeysAreVerified bool
|
||||
AttributesInBind bool
|
||||
UsePagedSearch bool
|
||||
SearchPageSize int
|
||||
Filter string
|
||||
AdminFilter string
|
||||
GroupsEnabled bool
|
||||
GroupDN string
|
||||
GroupFilter string
|
||||
GroupMemberUID string
|
||||
UserUID string
|
||||
RestrictedFilter string
|
||||
AllowDeactivateAll bool
|
||||
GroupTeamMap string `binding:"ValidGroupTeamMap"`
|
||||
GroupTeamMapRemoval bool
|
||||
|
||||
// SMTP
|
||||
SMTPAuth string
|
||||
SMTPHost string
|
||||
SMTPPort int
|
||||
AllowedDomains string
|
||||
SecurityProtocol int `binding:"Range(0,2)"`
|
||||
TLS bool
|
||||
SkipVerify bool
|
||||
HeloHostname string
|
||||
DisableHelo bool
|
||||
ForceSMTPS bool
|
||||
|
||||
// PAM
|
||||
PAMServiceName string
|
||||
PAMEmailDomain string
|
||||
|
||||
// Oauth2 & OIDC
|
||||
Oauth2Provider string
|
||||
Oauth2Key string
|
||||
Oauth2Secret string
|
||||
OpenIDConnectAutoDiscoveryURL string
|
||||
Oauth2UseCustomURL bool
|
||||
Oauth2TokenURL string
|
||||
Oauth2AuthURL string
|
||||
Oauth2ProfileURL string
|
||||
Oauth2EmailURL string
|
||||
Oauth2IconURL string
|
||||
Oauth2Tenant string
|
||||
Oauth2Scopes string
|
||||
Oauth2RequiredClaimName string
|
||||
Oauth2RequiredClaimValue string
|
||||
Oauth2GroupClaimName string
|
||||
Oauth2AdminGroup string
|
||||
Oauth2RestrictedGroup string
|
||||
Oauth2GroupTeamMap string `binding:"ValidGroupTeamMap"`
|
||||
Oauth2GroupTeamMapRemoval bool
|
||||
Oauth2SSHPublicKeyClaimName string
|
||||
Oauth2FullNameClaimName string
|
||||
OpenIDConnectExternalIDClaim string
|
||||
|
||||
// SSPI
|
||||
SSPIAutoCreateUsers bool
|
||||
SSPIAutoActivateUsers bool
|
||||
SSPIStripDomainNames bool
|
||||
SSPISeparatorReplacement string `binding:"AlphaDashDot;MaxSize(5)"`
|
||||
SSPIDefaultLanguage string
|
||||
}
|
||||
|
||||
// Validate validates fields
|
||||
func (f *AuthenticationForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package forms
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"gitea.dev/modules/structs"
|
||||
"gitea.dev/modules/web/middleware"
|
||||
"gitea.dev/services/context"
|
||||
|
||||
"gitea.com/go-chi/binding"
|
||||
)
|
||||
|
||||
// ________ .__ __ .__
|
||||
// \_____ \_______ _________ ____ |__|____________ _/ |_|__| ____ ____
|
||||
// / | \_ __ \/ ___\__ \ / \| \___ /\__ \\ __\ |/ _ \ / \
|
||||
// / | \ | \/ /_/ > __ \| | \ |/ / / __ \| | | ( <_> ) | \
|
||||
// \_______ /__| \___ (____ /___| /__/_____ \(____ /__| |__|\____/|___| /
|
||||
// \/ /_____/ \/ \/ \/ \/ \/
|
||||
|
||||
// CreateOrgForm form for creating organization
|
||||
type CreateOrgForm struct {
|
||||
OrgName string `binding:"Required;Username;MaxSize(40)" locale:"org.org_name_holder"`
|
||||
Visibility structs.VisibleType
|
||||
RepoAdminChangeTeamAccess bool
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *CreateOrgForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// UpdateOrgSettingForm form for updating organization settings
|
||||
type UpdateOrgSettingForm struct {
|
||||
FullName *string `binding:"MaxSize(100)"`
|
||||
Email *string `binding:"MaxSize(255)"`
|
||||
Description *string `binding:"MaxSize(255)"`
|
||||
Website *string `binding:"ValidUrl;MaxSize(255)"`
|
||||
Location *string `binding:"MaxSize(50)"`
|
||||
MaxRepoCreation *int
|
||||
RepoAdminChangeTeamAccess *bool
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *UpdateOrgSettingForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
type RenameOrgForm struct {
|
||||
OrgName string `binding:"Required"`
|
||||
NewOrgName string `binding:"Required;Username;MaxSize(40)" locale:"org.org_name_holder"`
|
||||
}
|
||||
|
||||
// ___________
|
||||
// \__ ___/___ _____ _____
|
||||
// | |_/ __ \\__ \ / \
|
||||
// | |\ ___/ / __ \| Y Y \
|
||||
// |____| \___ >____ /__|_| /
|
||||
// \/ \/ \/
|
||||
|
||||
// CreateTeamForm form for creating team
|
||||
type CreateTeamForm struct {
|
||||
TeamName string `binding:"Required;AlphaDashDot;MaxSize(255)"`
|
||||
Description string `binding:"MaxSize(255)"`
|
||||
Permission string
|
||||
RepoAccess string
|
||||
CanCreateOrgRepo bool
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *CreateTeamForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package forms
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"gitea.dev/modules/web/middleware"
|
||||
"gitea.dev/services/context"
|
||||
|
||||
"gitea.com/go-chi/binding"
|
||||
)
|
||||
|
||||
type PackageCleanupRuleForm struct {
|
||||
ID int64
|
||||
Enabled bool
|
||||
Type string `binding:"Required;In(alpine,arch,cargo,chef,composer,conan,conda,container,cran,debian,generic,go,helm,maven,npm,nuget,pub,pypi,rpm,rubygems,swift,terraform,vagrant)"`
|
||||
KeepCount int `binding:"In(0,1,5,10,25,50,100)"`
|
||||
KeepPattern string `binding:"RegexPattern"`
|
||||
RemoveDays int `binding:"In(0,7,14,30,60,90,180)"`
|
||||
RemovePattern string `binding:"RegexPattern"`
|
||||
MatchFullName bool
|
||||
Action string `binding:"Required;In(save,remove)"`
|
||||
}
|
||||
|
||||
func (f *PackageCleanupRuleForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
// Copyright 2017 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package forms
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"gitea.dev/modules/web/middleware"
|
||||
"gitea.dev/services/context"
|
||||
|
||||
"gitea.com/go-chi/binding"
|
||||
)
|
||||
|
||||
// NewBranchForm form for creating a new branch
|
||||
type NewBranchForm struct {
|
||||
NewBranchName string `binding:"Required;MaxSize(100);GitRefName"`
|
||||
CurrentPath string
|
||||
CreateTag bool
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *NewBranchForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// RenameBranchForm form for rename a branch
|
||||
type RenameBranchForm struct {
|
||||
From string `binding:"Required;MaxSize(100);GitRefName"`
|
||||
To string `binding:"Required;MaxSize(100);GitRefName"`
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *RenameBranchForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
@@ -0,0 +1,741 @@
|
||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||
// Copyright 2017 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package forms
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
issues_model "gitea.dev/models/issues"
|
||||
project_model "gitea.dev/models/project"
|
||||
"gitea.dev/modules/json"
|
||||
"gitea.dev/modules/structs"
|
||||
"gitea.dev/modules/util"
|
||||
"gitea.dev/modules/web/middleware"
|
||||
"gitea.dev/services/context"
|
||||
"gitea.dev/services/webhook"
|
||||
|
||||
"gitea.com/go-chi/binding"
|
||||
)
|
||||
|
||||
// CreateRepoForm form for creating repository
|
||||
type CreateRepoForm struct {
|
||||
UID int64 `binding:"Required"`
|
||||
RepoName string `binding:"Required;AlphaDashDot;MaxSize(100)"`
|
||||
Private bool
|
||||
Description string `binding:"MaxSize(2048)"`
|
||||
DefaultBranch string `binding:"GitRefName;MaxSize(100)"`
|
||||
AutoInit bool
|
||||
Gitignores string
|
||||
IssueLabels string `binding:"MaxSize(255)"`
|
||||
License string `binding:"MaxSize(100)"`
|
||||
Readme string `binding:"MaxSize(255)"`
|
||||
Template bool
|
||||
|
||||
RepoTemplate int64
|
||||
GitContent bool
|
||||
Topics bool
|
||||
GitHooks bool
|
||||
Webhooks bool
|
||||
Avatar bool
|
||||
Labels bool
|
||||
ProtectedBranch bool
|
||||
|
||||
ForkSingleBranch string `binding:"MaxSize(255)"`
|
||||
ObjectFormatName string
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *CreateRepoForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// MigrateRepoForm form for migrating repository
|
||||
// this is used to interact with web ui
|
||||
type MigrateRepoForm struct {
|
||||
// required: true
|
||||
CloneAddr string `json:"clone_addr" binding:"Required"`
|
||||
Service structs.GitServiceType `json:"service"`
|
||||
AuthUsername string `json:"auth_username"`
|
||||
AuthPassword string `json:"auth_password"`
|
||||
AuthToken string `json:"auth_token"`
|
||||
// required: true
|
||||
UID int64 `json:"uid" binding:"Required"`
|
||||
// required: true
|
||||
RepoName string `json:"repo_name" binding:"Required;AlphaDashDot;MaxSize(100)"`
|
||||
Mirror bool `json:"mirror"`
|
||||
LFS bool `json:"lfs"`
|
||||
LFSEndpoint string `json:"lfs_endpoint"`
|
||||
Private bool `json:"private"`
|
||||
Description string `json:"description" binding:"MaxSize(2048)"`
|
||||
Wiki bool `json:"wiki"`
|
||||
Milestones bool `json:"milestones"`
|
||||
Labels bool `json:"labels"`
|
||||
Issues bool `json:"issues"`
|
||||
PullRequests bool `json:"pull_requests"`
|
||||
Releases bool `json:"releases"`
|
||||
MirrorInterval string `json:"mirror_interval"`
|
||||
|
||||
AWSAccessKeyID string `json:"aws_access_key_id"`
|
||||
AWSSecretAccessKey string `json:"aws_secret_access_key"`
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *MigrateRepoForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// RepoSettingForm form for changing repository settings
|
||||
type RepoSettingForm struct {
|
||||
RepoName string `binding:"Required;AlphaDashDot;MaxSize(100)"`
|
||||
Description string `binding:"MaxSize(2048)"`
|
||||
Website string `binding:"ValidUrl;MaxSize(1024)"`
|
||||
Interval string
|
||||
MirrorAddress string
|
||||
MirrorUsername string
|
||||
MirrorPassword string
|
||||
LFS bool `form:"mirror_lfs"`
|
||||
LFSEndpoint string `form:"mirror_lfs_endpoint"`
|
||||
PushMirrorID int64
|
||||
PushMirrorAddress string
|
||||
PushMirrorUsername string
|
||||
PushMirrorPassword string
|
||||
PushMirrorSyncOnCommit bool
|
||||
PushMirrorInterval string
|
||||
Template bool
|
||||
EnablePrune bool
|
||||
|
||||
// Advanced settings
|
||||
EnableCode bool
|
||||
|
||||
EnableWiki bool
|
||||
EnableExternalWiki bool
|
||||
DefaultWikiBranch string
|
||||
ExternalWikiURL string
|
||||
|
||||
EnableIssues bool
|
||||
EnableExternalTracker bool
|
||||
ExternalTrackerURL string
|
||||
TrackerURLFormat string
|
||||
TrackerIssueStyle string
|
||||
ExternalTrackerRegexpPattern string
|
||||
EnableCloseIssuesViaCommitInAnyBranch bool
|
||||
|
||||
EnableProjects bool
|
||||
ProjectsMode string
|
||||
|
||||
EnableReleases bool
|
||||
|
||||
EnablePackages bool
|
||||
|
||||
EnablePulls bool
|
||||
PullsIgnoreWhitespace bool
|
||||
PullsAllowMerge bool
|
||||
PullsAllowRebase bool
|
||||
PullsAllowRebaseMerge bool
|
||||
PullsAllowSquash bool
|
||||
PullsAllowFastForwardOnly bool
|
||||
PullsAllowManualMerge bool
|
||||
PullsDefaultMergeStyle string
|
||||
EnableAutodetectManualMerge bool
|
||||
PullsAllowMergeUpdate bool
|
||||
PullsAllowRebaseUpdate bool
|
||||
PullsDefaultUpdateStyle string
|
||||
DefaultDeleteBranchAfterMerge bool
|
||||
DefaultAllowMaintainerEdit bool
|
||||
DefaultTargetBranch string
|
||||
EnableTimetracker bool
|
||||
AllowOnlyContributorsToTrackTime bool
|
||||
EnableIssueDependencies bool
|
||||
|
||||
// Signing Settings
|
||||
TrustModel string
|
||||
|
||||
// Admin settings
|
||||
EnableHealthCheck bool
|
||||
RequestReindexType string
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *RepoSettingForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// ProtectBranchForm form for changing protected branch settings
|
||||
type ProtectBranchForm struct {
|
||||
RuleName string `binding:"Required"`
|
||||
RuleID int64
|
||||
EnablePush string
|
||||
WhitelistUsers string
|
||||
WhitelistTeams string
|
||||
WhitelistDeployKeys bool
|
||||
EnableForcePush string
|
||||
ForcePushAllowlistUsers string
|
||||
ForcePushAllowlistTeams string
|
||||
ForcePushAllowlistDeployKeys bool
|
||||
EnableMergeWhitelist bool
|
||||
MergeWhitelistUsers string
|
||||
MergeWhitelistTeams string
|
||||
EnableBypassAllowlist bool
|
||||
BypassAllowlistUsers string
|
||||
BypassAllowlistTeams string
|
||||
EnableStatusCheck bool
|
||||
StatusCheckContexts string
|
||||
RequiredApprovals int64
|
||||
EnableApprovalsWhitelist bool
|
||||
ApprovalsWhitelistUsers string
|
||||
ApprovalsWhitelistTeams string
|
||||
BlockOnRejectedReviews bool
|
||||
BlockOnOfficialReviewRequests bool
|
||||
BlockOnOutdatedBranch bool
|
||||
DismissStaleApprovals bool
|
||||
IgnoreStaleApprovals bool
|
||||
RequireSignedCommits bool
|
||||
ProtectedFilePatterns string
|
||||
UnprotectedFilePatterns string
|
||||
BlockAdminMergeOverride bool
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *ProtectBranchForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// WebhookForm form for changing web hook
|
||||
type WebhookForm struct {
|
||||
Name string `binding:"MaxSize(255)"`
|
||||
Events string
|
||||
Create bool
|
||||
Delete bool
|
||||
Fork bool
|
||||
Push bool
|
||||
Issues bool
|
||||
IssueAssign bool
|
||||
IssueLabel bool
|
||||
IssueMilestone bool
|
||||
IssueComment bool
|
||||
PullRequest bool
|
||||
PullRequestAssign bool
|
||||
PullRequestLabel bool
|
||||
PullRequestMilestone bool
|
||||
PullRequestComment bool
|
||||
PullRequestReview bool
|
||||
PullRequestSync bool
|
||||
PullRequestReviewRequest bool
|
||||
Wiki bool
|
||||
Repository bool
|
||||
Release bool
|
||||
Package bool
|
||||
Status bool
|
||||
WorkflowRun bool
|
||||
WorkflowJob bool
|
||||
Active bool
|
||||
BranchFilter string `binding:"GlobPattern"`
|
||||
AuthorizationHeader string
|
||||
Secret string
|
||||
}
|
||||
|
||||
// PushOnly if the hook will be triggered when push
|
||||
func (f WebhookForm) PushOnly() bool {
|
||||
return f.Events == "push_only"
|
||||
}
|
||||
|
||||
// SendEverything if the hook will be triggered any event
|
||||
func (f WebhookForm) SendEverything() bool {
|
||||
return f.Events == "send_everything"
|
||||
}
|
||||
|
||||
// ChooseEvents if the hook will be triggered choose events
|
||||
func (f WebhookForm) ChooseEvents() bool {
|
||||
return f.Events == "choose_events"
|
||||
}
|
||||
|
||||
// NewWebhookForm form for creating web hook
|
||||
type NewWebhookForm struct {
|
||||
PayloadURL string `binding:"Required;ValidUrl"`
|
||||
HTTPMethod string `binding:"Required;In(POST,GET)"`
|
||||
ContentType int `binding:"Required"`
|
||||
WebhookForm
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *NewWebhookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// NewGogshookForm form for creating gogs hook
|
||||
type NewGogshookForm struct {
|
||||
PayloadURL string `binding:"Required;ValidUrl"`
|
||||
ContentType int `binding:"Required"`
|
||||
WebhookForm
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *NewGogshookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// NewSlackHookForm form for creating slack hook
|
||||
type NewSlackHookForm struct {
|
||||
PayloadURL string `binding:"Required;ValidUrl"`
|
||||
Channel string `binding:"Required"`
|
||||
Username string
|
||||
IconURL string
|
||||
Color string
|
||||
WebhookForm
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *NewSlackHookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
if !webhook.IsValidSlackChannel(strings.TrimSpace(f.Channel)) {
|
||||
errs = append(errs, binding.Error{
|
||||
FieldNames: []string{"Channel"},
|
||||
Classification: "",
|
||||
Message: ctx.Locale.TrString("repo.settings.add_webhook.invalid_channel_name"),
|
||||
})
|
||||
}
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// NewDiscordHookForm form for creating discord hook
|
||||
type NewDiscordHookForm struct {
|
||||
PayloadURL string `binding:"Required;ValidUrl"`
|
||||
Username string
|
||||
IconURL string
|
||||
WebhookForm
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *NewDiscordHookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// NewDingtalkHookForm form for creating dingtalk hook
|
||||
type NewDingtalkHookForm struct {
|
||||
PayloadURL string `binding:"Required;ValidUrl"`
|
||||
WebhookForm
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *NewDingtalkHookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// NewTelegramHookForm form for creating telegram hook
|
||||
type NewTelegramHookForm struct {
|
||||
BotToken string `binding:"Required"`
|
||||
ChatID string `binding:"Required"`
|
||||
ThreadID string
|
||||
WebhookForm
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *NewTelegramHookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// NewMatrixHookForm form for creating Matrix hook
|
||||
type NewMatrixHookForm struct {
|
||||
HomeserverURL string `binding:"Required;ValidUrl"`
|
||||
RoomID string `binding:"Required"`
|
||||
MessageType int
|
||||
WebhookForm
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *NewMatrixHookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// NewMSTeamsHookForm form for creating MS Teams hook
|
||||
type NewMSTeamsHookForm struct {
|
||||
PayloadURL string `binding:"Required;ValidUrl"`
|
||||
WebhookForm
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *NewMSTeamsHookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// NewFeishuHookForm form for creating feishu hook
|
||||
type NewFeishuHookForm struct {
|
||||
PayloadURL string `binding:"Required;ValidUrl"`
|
||||
WebhookForm
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *NewFeishuHookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// NewWechatWorkHookForm form for creating wechatwork hook
|
||||
type NewWechatWorkHookForm struct {
|
||||
PayloadURL string `binding:"Required;ValidUrl"`
|
||||
WebhookForm
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *NewWechatWorkHookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// NewPackagistHookForm form for creating packagist hook
|
||||
type NewPackagistHookForm struct {
|
||||
Username string `binding:"Required"`
|
||||
APIToken string `binding:"Required"`
|
||||
PackageURL string `binding:"Required;ValidUrl"`
|
||||
WebhookForm
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *NewPackagistHookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// CreateIssueForm form for creating issue
|
||||
type CreateIssueForm struct {
|
||||
Title string `binding:"Required;MaxSize(255)"`
|
||||
AssigneeIDs string `form:"assignee_ids"`
|
||||
ReviewerIDs string `form:"reviewer_ids"`
|
||||
Ref string `form:"ref"`
|
||||
MilestoneID int64
|
||||
Content string
|
||||
Files []string
|
||||
AllowMaintainerEdit bool
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *CreateIssueForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// CreateCommentForm form for creating comment
|
||||
type CreateCommentForm struct {
|
||||
Content string
|
||||
Status string `binding:"OmitEmpty;In(reopen,close)"`
|
||||
Files []string
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *CreateCommentForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// ReactionForm form for adding and removing reaction
|
||||
type ReactionForm struct {
|
||||
Content string `binding:"Required"`
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *ReactionForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// IssueLockForm form for locking an issue
|
||||
type IssueLockForm struct {
|
||||
Reason string `binding:"Required"`
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (i *IssueLockForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, i, ctx.Locale)
|
||||
}
|
||||
|
||||
// CreateProjectForm form for creating a project
|
||||
type CreateProjectForm struct {
|
||||
Title string `binding:"Required;MaxSize(100)"`
|
||||
Content string
|
||||
TemplateType project_model.TemplateType
|
||||
CardType project_model.CardType
|
||||
}
|
||||
|
||||
// EditProjectColumnForm is a form for editing a project column
|
||||
type EditProjectColumnForm struct {
|
||||
Title string `binding:"Required;MaxSize(100)"`
|
||||
Sorting int8
|
||||
Color string `binding:"MaxSize(7)"`
|
||||
}
|
||||
|
||||
// CreateMilestoneForm form for creating milestone
|
||||
type CreateMilestoneForm struct {
|
||||
Title string `binding:"Required;MaxSize(50)"`
|
||||
Content string
|
||||
Deadline string
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *CreateMilestoneForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// CreateLabelForm form for creating label
|
||||
type CreateLabelForm struct {
|
||||
ID int64
|
||||
Title string `binding:"Required;MaxSize(50)" locale:"repo.issues.label_title"`
|
||||
Exclusive bool `form:"exclusive"`
|
||||
ExclusiveOrder int `form:"exclusive_order"`
|
||||
IsArchived bool `form:"is_archived"`
|
||||
Description string `binding:"MaxSize(200)" locale:"repo.issues.label_description"`
|
||||
Color string `binding:"Required;MaxSize(7)" locale:"repo.issues.label_color"`
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *CreateLabelForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// InitializeLabelsForm form for initializing labels
|
||||
type InitializeLabelsForm struct {
|
||||
TemplateName string `binding:"Required"`
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *InitializeLabelsForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// MergePullRequestForm form for merging Pull Request
|
||||
// swagger:model MergePullRequestOption
|
||||
type MergePullRequestForm struct {
|
||||
// required: true
|
||||
// enum: ["merge","rebase","rebase-merge","squash","fast-forward-only","manually-merged"]
|
||||
Do string `json:"do" binding:"Required;In(merge,rebase,rebase-merge,squash,fast-forward-only,manually-merged)"`
|
||||
MergeTitleField string `json:"merge_title_field,omitempty"`
|
||||
MergeMessageField string `json:"merge_message_field,omitempty"`
|
||||
MergeCommitID string `json:"merge_commit_id,omitempty"` // only used for manually-merged
|
||||
HeadCommitID string `json:"head_commit_id,omitempty"`
|
||||
ForceMerge bool `json:"force_merge,omitempty"`
|
||||
MergeWhenChecksSucceed bool `json:"merge_when_checks_succeed,omitempty"`
|
||||
DeleteBranchAfterMerge *bool `json:"delete_branch_after_merge,omitempty"`
|
||||
}
|
||||
|
||||
func (f *MergePullRequestForm) UnmarshalJSON(b []byte) error {
|
||||
// This is for backward compatibility, to support both field names like "do" and "Do",
|
||||
// because old code doesn't have "json" tag for these fields
|
||||
type aux struct {
|
||||
Do1 string `json:"do"`
|
||||
Do2 string `json:"Do"`
|
||||
MergeTitleField1 string `json:"merge_title_field"`
|
||||
MergeTitleField2 string `json:"MergeTitleField"`
|
||||
MergeMessageField1 string `json:"merge_message_field"`
|
||||
MergeMessageField2 string `json:"MergeMessageField"`
|
||||
MergeCommitID1 string `json:"merge_commit_id"`
|
||||
MergeCommitID2 string `json:"MergeCommitID"`
|
||||
|
||||
HeadCommitID string `json:"head_commit_id"`
|
||||
ForceMerge bool `json:"force_merge"`
|
||||
MergeWhenChecksSucceed bool `json:"merge_when_checks_succeed"`
|
||||
DeleteBranchAfterMerge *bool `json:"delete_branch_after_merge"`
|
||||
}
|
||||
var a aux
|
||||
if err := json.Unmarshal(b, &a); err != nil {
|
||||
return err
|
||||
}
|
||||
f.Do = util.IfZero(a.Do1, a.Do2)
|
||||
f.MergeTitleField = util.IfZero(a.MergeTitleField1, a.MergeTitleField2)
|
||||
f.MergeMessageField = util.IfZero(a.MergeMessageField1, a.MergeMessageField2)
|
||||
f.MergeCommitID = util.IfZero(a.MergeCommitID1, a.MergeCommitID2)
|
||||
f.HeadCommitID = a.HeadCommitID
|
||||
f.ForceMerge = a.ForceMerge
|
||||
f.MergeWhenChecksSucceed = a.MergeWhenChecksSucceed
|
||||
f.DeleteBranchAfterMerge = a.DeleteBranchAfterMerge
|
||||
return nil
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *MergePullRequestForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// CodeCommentForm form for adding code comments for PRs
|
||||
type CodeCommentForm struct {
|
||||
Origin string `binding:"Required;In(timeline,diff)"`
|
||||
Content string `binding:"Required"`
|
||||
Side string `binding:"Required;In(previous,proposed)"`
|
||||
Line int64
|
||||
TreePath string `form:"path" binding:"Required"`
|
||||
SingleReview bool `form:"single_review"`
|
||||
Reply int64 `form:"reply"`
|
||||
LatestCommitID string
|
||||
Files []string
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *CodeCommentForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// SubmitReviewForm for submitting a finished code review
|
||||
type SubmitReviewForm struct {
|
||||
Content string
|
||||
Type string
|
||||
CommitID string
|
||||
Files []string
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *SubmitReviewForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// ReviewType will return the corresponding ReviewType for type
|
||||
func (f SubmitReviewForm) ReviewType() issues_model.ReviewType {
|
||||
switch f.Type {
|
||||
case "approve":
|
||||
return issues_model.ReviewTypeApprove
|
||||
case "comment":
|
||||
return issues_model.ReviewTypeComment
|
||||
case "reject":
|
||||
return issues_model.ReviewTypeReject
|
||||
case "":
|
||||
return issues_model.ReviewTypeComment // default to comment when doing quick-submit (Ctrl+Enter) on the review form
|
||||
default:
|
||||
return issues_model.ReviewTypeUnknown
|
||||
}
|
||||
}
|
||||
|
||||
// HasEmptyContent checks if the content of the review form is empty.
|
||||
func (f SubmitReviewForm) HasEmptyContent() bool {
|
||||
reviewType := f.ReviewType()
|
||||
|
||||
return (reviewType == issues_model.ReviewTypeComment || reviewType == issues_model.ReviewTypeReject) &&
|
||||
len(strings.TrimSpace(f.Content)) == 0
|
||||
}
|
||||
|
||||
// DismissReviewForm for dismissing stale review by repo admin
|
||||
type DismissReviewForm struct {
|
||||
ReviewID int64 `binding:"Required"`
|
||||
Message string
|
||||
}
|
||||
|
||||
// UpdateAllowEditsForm form for changing if PR allows edits from maintainers
|
||||
type UpdateAllowEditsForm struct {
|
||||
AllowMaintainerEdit bool
|
||||
}
|
||||
|
||||
// __________ .__
|
||||
// \______ \ ____ | | ____ _____ ______ ____
|
||||
// | _// __ \| | _/ __ \\__ \ / ___// __ \
|
||||
// | | \ ___/| |_\ ___/ / __ \_\___ \\ ___/
|
||||
// |____|_ /\___ >____/\___ >____ /____ >\___ >
|
||||
// \/ \/ \/ \/ \/ \/
|
||||
|
||||
// NewReleaseForm form for creating release
|
||||
type NewReleaseForm struct {
|
||||
TagName string `binding:"Required;GitRefName;MaxSize(255)"`
|
||||
Target string `form:"tag_target" binding:"Required;MaxSize(255)"`
|
||||
Title string `binding:"MaxSize(255)"`
|
||||
Content string
|
||||
Draft bool
|
||||
TagOnly bool
|
||||
Prerelease bool
|
||||
AddTagMsg bool
|
||||
Files []string
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *NewReleaseForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// GenerateReleaseNotesForm retrieves release notes recommendations.
|
||||
type GenerateReleaseNotesForm struct {
|
||||
TagName string `form:"tag_name" binding:"Required;GitRefName;MaxSize(255)"`
|
||||
TagTarget string `form:"tag_target" binding:"MaxSize(255)"`
|
||||
PreviousTag string `form:"previous_tag" binding:"MaxSize(255)"`
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *GenerateReleaseNotesForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// EditReleaseForm form for changing release
|
||||
type EditReleaseForm struct {
|
||||
Title string `form:"title" binding:"Required;MaxSize(255)"`
|
||||
Content string `form:"content"`
|
||||
Draft string `form:"draft"`
|
||||
Prerelease bool `form:"prerelease"`
|
||||
Files []string
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *EditReleaseForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// __ __.__ __ .__
|
||||
// / \ / \__| | _|__|
|
||||
// \ \/\/ / | |/ / |
|
||||
// \ /| | <| |
|
||||
// \__/\ / |__|__|_ \__|
|
||||
// \/ \/
|
||||
|
||||
// NewWikiForm form for creating wiki
|
||||
type NewWikiForm struct {
|
||||
Title string `binding:"Required"`
|
||||
Content string `binding:"Required"`
|
||||
Message string
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
// FIXME: use code generation to generate this method.
|
||||
func (f *NewWikiForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// ___________.__ ___________ __
|
||||
// \__ ___/|__| _____ ____ \__ ___/___________ ____ | | __ ___________
|
||||
// | | | |/ \_/ __ \ | | \_ __ \__ \ _/ ___\| |/ // __ \_ __ \
|
||||
// | | | | Y Y \ ___/ | | | | \// __ \\ \___| <\ ___/| | \/
|
||||
// |____| |__|__|_| /\___ > |____| |__| (____ /\___ >__|_ \\___ >__|
|
||||
// \/ \/ \/ \/ \/ \/
|
||||
|
||||
// AddTimeManuallyForm form that adds spent time manually.
|
||||
type AddTimeManuallyForm struct {
|
||||
Hours int `binding:"Range(0,1000)"`
|
||||
Minutes int `binding:"Range(0,1000)"`
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *AddTimeManuallyForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// SaveTopicForm form for save topics for repository
|
||||
type SaveTopicForm struct {
|
||||
Topics []string `binding:"topics;Required;"`
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
// Copyright 2025 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package forms
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"gitea.dev/modules/optional"
|
||||
"gitea.dev/modules/web/middleware"
|
||||
"gitea.dev/services/context"
|
||||
|
||||
"gitea.com/go-chi/binding"
|
||||
)
|
||||
|
||||
type CommitCommonForm struct {
|
||||
TreePath string `binding:"MaxSize(500)"`
|
||||
CommitSummary string `binding:"MaxSize(100)"`
|
||||
CommitMessage string
|
||||
CommitChoice string `binding:"Required;MaxSize(50)"`
|
||||
NewBranchName string `binding:"GitRefName;MaxSize(100)"`
|
||||
LastCommit string
|
||||
Signoff bool
|
||||
CommitEmail string
|
||||
}
|
||||
|
||||
func (f *CommitCommonForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
type CommitCommonFormInterface interface {
|
||||
GetCommitCommonForm() *CommitCommonForm
|
||||
}
|
||||
|
||||
func (f *CommitCommonForm) GetCommitCommonForm() *CommitCommonForm {
|
||||
return f
|
||||
}
|
||||
|
||||
type EditRepoFileForm struct {
|
||||
CommitCommonForm
|
||||
Content optional.Option[string]
|
||||
}
|
||||
|
||||
type DeleteRepoFileForm struct {
|
||||
CommitCommonForm
|
||||
}
|
||||
|
||||
type UploadRepoFileForm struct {
|
||||
CommitCommonForm
|
||||
Files []string
|
||||
}
|
||||
|
||||
type CherryPickForm struct {
|
||||
CommitCommonForm
|
||||
Revert bool
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
// Copyright 2018 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package forms
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"gitea.dev/modules/json"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestSubmitReviewForm_IsEmpty(t *testing.T) {
|
||||
cases := []struct {
|
||||
form SubmitReviewForm
|
||||
expected bool
|
||||
}{
|
||||
// Approved PR with a comment shouldn't count as empty
|
||||
{SubmitReviewForm{Type: "approve", Content: "Awesome"}, false},
|
||||
|
||||
// Approved PR without a comment shouldn't count as empty
|
||||
{SubmitReviewForm{Type: "approve", Content: ""}, false},
|
||||
|
||||
// Rejected PR without a comment should count as empty
|
||||
{SubmitReviewForm{Type: "reject", Content: ""}, true},
|
||||
|
||||
// Rejected PR with a comment shouldn't count as empty
|
||||
{SubmitReviewForm{Type: "reject", Content: "Awesome"}, false},
|
||||
|
||||
// Comment review on a PR with a comment shouldn't count as empty
|
||||
{SubmitReviewForm{Type: "comment", Content: "Awesome"}, false},
|
||||
|
||||
// Comment review on a PR without a comment should count as empty
|
||||
{SubmitReviewForm{Type: "comment", Content: ""}, true},
|
||||
}
|
||||
|
||||
for _, v := range cases {
|
||||
assert.Equal(t, v.expected, v.form.HasEmptyContent())
|
||||
}
|
||||
}
|
||||
|
||||
func TestMergePullRequestForm(t *testing.T) {
|
||||
expected := &MergePullRequestForm{
|
||||
Do: "merge",
|
||||
MergeTitleField: "title",
|
||||
MergeMessageField: "message",
|
||||
MergeCommitID: "merge-id",
|
||||
HeadCommitID: "head-id",
|
||||
ForceMerge: true,
|
||||
MergeWhenChecksSucceed: true,
|
||||
DeleteBranchAfterMerge: new(true),
|
||||
}
|
||||
|
||||
t.Run("NewFields", func(t *testing.T) {
|
||||
input := `{
|
||||
"do": "merge",
|
||||
"merge_title_field": "title",
|
||||
"merge_message_field": "message",
|
||||
"merge_commit_id": "merge-id",
|
||||
"head_commit_id": "head-id",
|
||||
"force_merge": true,
|
||||
"merge_when_checks_succeed": true,
|
||||
"delete_branch_after_merge": true
|
||||
}`
|
||||
var m *MergePullRequestForm
|
||||
require.NoError(t, json.Unmarshal([]byte(input), &m))
|
||||
assert.Equal(t, expected, m)
|
||||
})
|
||||
|
||||
t.Run("OldFields", func(t *testing.T) {
|
||||
input := `{
|
||||
"Do": "merge",
|
||||
"MergeTitleField": "title",
|
||||
"MergeMessageField": "message",
|
||||
"MergeCommitID": "merge-id",
|
||||
"head_commit_id": "head-id",
|
||||
"force_merge": true,
|
||||
"merge_when_checks_succeed": true,
|
||||
"delete_branch_after_merge": true
|
||||
}`
|
||||
var m *MergePullRequestForm
|
||||
require.NoError(t, json.Unmarshal([]byte(input), &m))
|
||||
assert.Equal(t, expected, m)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package forms
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"gitea.dev/modules/web/middleware"
|
||||
"gitea.dev/services/context"
|
||||
|
||||
"gitea.com/go-chi/binding"
|
||||
)
|
||||
|
||||
// ProtectTagForm form for changing protected tag settings
|
||||
type ProtectTagForm struct {
|
||||
NamePattern string `binding:"Required;GlobOrRegexPattern"`
|
||||
AllowlistUsers string
|
||||
AllowlistTeams string
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *ProtectTagForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package forms
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"gitea.dev/modules/web/middleware"
|
||||
"gitea.dev/services/context"
|
||||
|
||||
"gitea.com/go-chi/binding"
|
||||
)
|
||||
|
||||
// EditRunnerForm form for admin to create runner
|
||||
type EditRunnerForm struct {
|
||||
Description string
|
||||
}
|
||||
|
||||
// Validate validates form fields
|
||||
func (f *EditRunnerForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
@@ -0,0 +1,454 @@
|
||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
||||
// Copyright 2018 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package forms
|
||||
|
||||
import (
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
user_model "gitea.dev/models/user"
|
||||
"gitea.dev/modules/setting"
|
||||
"gitea.dev/modules/structs"
|
||||
"gitea.dev/modules/util"
|
||||
"gitea.dev/modules/validation"
|
||||
"gitea.dev/modules/web/middleware"
|
||||
"gitea.dev/services/context"
|
||||
|
||||
"gitea.com/go-chi/binding"
|
||||
)
|
||||
|
||||
// InstallForm form for installation page
|
||||
type InstallForm struct {
|
||||
DbType string `binding:"Required"`
|
||||
DbHost string
|
||||
DbUser string
|
||||
DbPasswd string
|
||||
DbName string
|
||||
SSLMode string
|
||||
DbPath string
|
||||
DbSchema string
|
||||
|
||||
AppName string `binding:"Required" locale:"install.app_name"`
|
||||
RepoRootPath string `binding:"Required"`
|
||||
LFSRootPath string
|
||||
RunUser string `binding:"Required"`
|
||||
Domain string `binding:"Required"`
|
||||
SSHPort int
|
||||
HTTPPort string `binding:"Required"`
|
||||
AppURL string `binding:"Required"`
|
||||
LogRootPath string `binding:"Required"`
|
||||
|
||||
SMTPAddr string
|
||||
SMTPPort string
|
||||
SMTPFrom string
|
||||
SMTPUser string `binding:"OmitEmpty;MaxSize(254)" locale:"install.mailer_user"`
|
||||
SMTPPasswd string
|
||||
RegisterConfirm bool
|
||||
MailNotify bool
|
||||
|
||||
EnableOpenIDSignIn bool
|
||||
EnableOpenIDSignUp bool
|
||||
DisableRegistration bool
|
||||
AllowOnlyExternalRegistration bool
|
||||
EnableCaptcha bool
|
||||
RequireSignInView bool
|
||||
DefaultKeepEmailPrivate bool
|
||||
DefaultAllowCreateOrganization bool
|
||||
DefaultEnableTimetracking bool
|
||||
EnableUpdateChecker bool
|
||||
NoReplyAddress string
|
||||
|
||||
PasswordAlgorithm string
|
||||
|
||||
AdminName string `binding:"OmitEmpty;Username;MaxSize(30)" locale:"install.admin_name"`
|
||||
AdminPasswd string `binding:"OmitEmpty;MaxSize(255)" locale:"install.admin_password"`
|
||||
AdminConfirmPasswd string
|
||||
AdminEmail string `binding:"OmitEmpty;MinSize(3);MaxSize(254);Include(@)" locale:"install.admin_email"`
|
||||
|
||||
// ReinstallConfirmFirst we can not use 1/2/3 or A/B/C here, there is a framework bug, can not parse "reinstall_confirm_1" or "reinstall_confirm_a"
|
||||
ReinstallConfirmFirst bool
|
||||
ReinstallConfirmSecond bool
|
||||
ReinstallConfirmThird bool
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *InstallForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// _____ ____ _________________ ___
|
||||
// / _ \ | | \__ ___/ | \
|
||||
// / /_\ \| | / | | / ~ \
|
||||
// / | \ | / | | \ Y /
|
||||
// \____|__ /______/ |____| \___|_ /
|
||||
// \/ \/
|
||||
|
||||
// RegisterForm form for registering
|
||||
type RegisterForm struct {
|
||||
UserName string `binding:"Required;Username;MaxSize(40)"`
|
||||
Email string `binding:"Required;MaxSize(254)"`
|
||||
Password string `binding:"MaxSize(255)"`
|
||||
Retype string
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *RegisterForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// IsEmailDomainAllowed validates that the email address
|
||||
// provided by the user matches what has been configured .
|
||||
// The email is marked as allowed if it matches any of the
|
||||
// domains in the whitelist or if it doesn't match any of
|
||||
// domains in the blocklist, if any such list is not empty.
|
||||
func (f *RegisterForm) IsEmailDomainAllowed() bool {
|
||||
return user_model.IsEmailDomainAllowed(f.Email)
|
||||
}
|
||||
|
||||
// MustChangePasswordForm form for updating your password after account creation
|
||||
// by an admin
|
||||
type MustChangePasswordForm struct {
|
||||
Password string `binding:"Required;MaxSize(255)"`
|
||||
Retype string
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *MustChangePasswordForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// SignInForm form for signing in with user/password
|
||||
type SignInForm struct {
|
||||
UserName string `binding:"Required;MaxSize(254)"`
|
||||
// TODO remove required from password for SecondFactorAuthentication
|
||||
Password string `binding:"Required;MaxSize(255)"`
|
||||
Remember bool
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *SignInForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// AuthorizationForm form for authorizing oauth2 clients
|
||||
type AuthorizationForm struct {
|
||||
ResponseType string `binding:"Required;In(code)"`
|
||||
ClientID string `binding:"Required"`
|
||||
RedirectURI string
|
||||
State string
|
||||
Scope string
|
||||
Nonce string
|
||||
|
||||
// PKCE support
|
||||
CodeChallengeMethod string // S256, plain
|
||||
CodeChallenge string
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *AuthorizationForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// GrantApplicationForm form for authorizing oauth2 clients
|
||||
type GrantApplicationForm struct {
|
||||
ClientID string `binding:"Required"`
|
||||
Granted bool
|
||||
RedirectURI string
|
||||
State string
|
||||
Scope string
|
||||
Nonce string
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *GrantApplicationForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// AccessTokenForm for issuing access tokens from authorization codes or refresh tokens
|
||||
type AccessTokenForm struct {
|
||||
GrantType string `json:"grant_type"`
|
||||
ClientID string `json:"client_id"`
|
||||
ClientSecret string `json:"client_secret"`
|
||||
RedirectURI string `json:"redirect_uri"`
|
||||
Code string `json:"code"`
|
||||
RefreshToken string `json:"refresh_token"`
|
||||
|
||||
// PKCE support
|
||||
CodeVerifier string `json:"code_verifier"`
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *AccessTokenForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// IntrospectTokenForm for introspecting tokens
|
||||
type IntrospectTokenForm struct {
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *IntrospectTokenForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// __________________________________________.___ _______ ________ _________
|
||||
// / _____/\_ _____/\__ ___/\__ ___/| |\ \ / _____/ / _____/
|
||||
// \_____ \ | __)_ | | | | | |/ | \/ \ ___ \_____ \
|
||||
// / \ | \ | | | | | / | \ \_\ \/ \
|
||||
// /_______ //_______ / |____| |____| |___\____|__ /\______ /_______ /
|
||||
// \/ \/ \/ \/ \/
|
||||
|
||||
// UpdateProfileForm form for updating profile
|
||||
type UpdateProfileForm struct {
|
||||
Name string `binding:"Username;MaxSize(40)"`
|
||||
FullName string `binding:"MaxSize(100)"`
|
||||
KeepEmailPrivate bool
|
||||
Website string `binding:"ValidSiteUrl;MaxSize(255)"`
|
||||
Location string `binding:"MaxSize(50)"`
|
||||
Description string `binding:"MaxSize(255)"`
|
||||
Visibility structs.VisibleType
|
||||
KeepActivityPrivate bool
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *UpdateProfileForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// UpdateLanguageForm form for updating profile
|
||||
type UpdateLanguageForm struct {
|
||||
Language string
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *UpdateLanguageForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// Avatar types
|
||||
const (
|
||||
AvatarLocal string = "local"
|
||||
AvatarByMail string = "bymail"
|
||||
)
|
||||
|
||||
// AvatarForm form for changing avatar
|
||||
type AvatarForm struct {
|
||||
Source string
|
||||
Avatar *multipart.FileHeader
|
||||
Gravatar string `binding:"OmitEmpty;Email;MaxSize(254)"`
|
||||
Federavatar bool
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *AvatarForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// AddEmailForm form for adding new email
|
||||
type AddEmailForm struct {
|
||||
Email string `binding:"Required;Email;MaxSize(254)"`
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *AddEmailForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// UpdateThemeForm form for updating a users' theme
|
||||
type UpdateThemeForm struct {
|
||||
Theme string `binding:"Required;MaxSize(255)"`
|
||||
}
|
||||
|
||||
// Validate validates the field
|
||||
func (f *UpdateThemeForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// ChangePasswordForm form for changing password
|
||||
type ChangePasswordForm struct {
|
||||
OldPassword string `form:"old_password" binding:"MaxSize(255)"`
|
||||
Password string `form:"password" binding:"Required;MaxSize(255)"`
|
||||
Retype string `form:"retype"`
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *ChangePasswordForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// AddOpenIDForm is for changing openid uri
|
||||
type AddOpenIDForm struct {
|
||||
Openid string `binding:"Required;MaxSize(256)"`
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *AddOpenIDForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// AddKeyForm form for adding SSH/GPG key
|
||||
type AddKeyForm struct {
|
||||
Type string `binding:"OmitEmpty"`
|
||||
Title string `binding:"Required;MaxSize(50)"`
|
||||
Content string `binding:"Required"`
|
||||
Signature string `binding:"OmitEmpty"`
|
||||
KeyID string `binding:"OmitEmpty"`
|
||||
Fingerprint string `binding:"OmitEmpty"`
|
||||
IsWritable bool
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *AddKeyForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// AddSecretForm for adding secrets
|
||||
type AddSecretForm struct {
|
||||
Name string `binding:"Required;MaxSize(255)"`
|
||||
Data string `binding:"Required;MaxSize(65535)"`
|
||||
Description string `binding:"MaxSize(65535)"`
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *AddSecretForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
type EditVariableForm struct {
|
||||
Name string `binding:"Required;MaxSize(255)"`
|
||||
Data string `binding:"Required;MaxSize(65535)"`
|
||||
Description string `binding:"MaxSize(65535)"`
|
||||
}
|
||||
|
||||
func (f *EditVariableForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// NewAccessTokenForm form for creating access token
|
||||
type NewAccessTokenForm struct {
|
||||
Name string `binding:"Required;MaxSize(255)" locale:"settings.token_name"`
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *NewAccessTokenForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// EditOAuth2ApplicationForm form for editing oauth2 applications
|
||||
type EditOAuth2ApplicationForm struct {
|
||||
Name string `binding:"Required;MaxSize(255)" form:"application_name"`
|
||||
RedirectURIs string `binding:"Required" form:"redirect_uris"`
|
||||
ConfidentialClient bool `form:"confidential_client"`
|
||||
SkipSecondaryAuthorization bool `form:"skip_secondary_authorization"`
|
||||
}
|
||||
|
||||
func DetectInvalidOAuth2ApplicationRedirectURI(uris []string) (invalidURL string) {
|
||||
for _, u := range uris {
|
||||
scheme, _, ok := strings.Cut(u, ":")
|
||||
valid := ok && (validation.IsValidURL(u) || util.SliceContainsString(setting.OAuth2.CustomSchemes, scheme))
|
||||
if !valid {
|
||||
return u
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *EditOAuth2ApplicationForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
invalidURI := DetectInvalidOAuth2ApplicationRedirectURI(util.SplitTrimSpace(f.RedirectURIs, "\n"))
|
||||
if invalidURI != "" {
|
||||
errs = middleware.ReportValidationError(errs, ctx.Data, "RedirectURIs", binding.ERR_URL, ctx.Locale.TrString("form.url_error", invalidURI))
|
||||
}
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// TwoFactorAuthForm for logging in with 2FA token.
|
||||
type TwoFactorAuthForm struct {
|
||||
Passcode string `binding:"Required"`
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *TwoFactorAuthForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// TwoFactorScratchAuthForm for logging in with 2FA scratch token.
|
||||
type TwoFactorScratchAuthForm struct {
|
||||
Token string `binding:"Required"`
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *TwoFactorScratchAuthForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// WebauthnRegistrationForm for reserving an WebAuthn name
|
||||
type WebauthnRegistrationForm struct {
|
||||
Name string `binding:"Required"`
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *WebauthnRegistrationForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// WebauthnDeleteForm for deleting WebAuthn keys
|
||||
type WebauthnDeleteForm struct {
|
||||
ID int64 `binding:"Required"`
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *WebauthnDeleteForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// PackageSettingForm form for package settings
|
||||
type PackageSettingForm struct {
|
||||
Action string
|
||||
RepoName string `form:"repo_name"`
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *PackageSettingForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
type BlockUserForm struct {
|
||||
Action string `binding:"Required;In(block,unblock,note)"`
|
||||
Blockee string `binding:"Required"`
|
||||
Note string
|
||||
}
|
||||
|
||||
func (f *BlockUserForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// Copyright 2017 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package forms
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"gitea.dev/modules/web/middleware"
|
||||
"gitea.dev/services/context"
|
||||
|
||||
"gitea.com/go-chi/binding"
|
||||
)
|
||||
|
||||
// SignInOpenIDForm form for signing in with OpenID
|
||||
type SignInOpenIDForm struct {
|
||||
Openid string `binding:"Required;MaxSize(256)"`
|
||||
Remember bool
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *SignInOpenIDForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// SignUpOpenIDForm form for signin up with OpenID
|
||||
type SignUpOpenIDForm struct {
|
||||
UserName string `binding:"Required;Username;MaxSize(40)"`
|
||||
Email string `binding:"Required;Email;MaxSize(254)"`
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *SignUpOpenIDForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
|
||||
// ConnectOpenIDForm form for connecting an existing account to an OpenID URI
|
||||
type ConnectOpenIDForm struct {
|
||||
UserName string `binding:"Required;MaxSize(254)"`
|
||||
Password string `binding:"Required;MaxSize(255)"`
|
||||
}
|
||||
|
||||
// Validate validates the fields
|
||||
func (f *ConnectOpenIDForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
|
||||
ctx := context.GetValidateContext(req)
|
||||
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
// Copyright 2021 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package forms
|
||||
|
||||
import (
|
||||
"math/big"
|
||||
|
||||
issues_model "gitea.dev/models/issues"
|
||||
"gitea.dev/modules/log"
|
||||
"gitea.dev/services/context"
|
||||
)
|
||||
|
||||
type hiddenCommentTypeGroupsType map[string][]issues_model.CommentType
|
||||
|
||||
// hiddenCommentTypeGroups maps the group names to comment types, these group names comes from the Web UI (appearance.tmpl)
|
||||
var hiddenCommentTypeGroups = hiddenCommentTypeGroupsType{
|
||||
"reference": {
|
||||
/*3*/ issues_model.CommentTypeIssueRef,
|
||||
/*4*/ issues_model.CommentTypeCommitRef,
|
||||
/*5*/ issues_model.CommentTypeCommentRef,
|
||||
/*6*/ issues_model.CommentTypePullRef,
|
||||
},
|
||||
"label": {
|
||||
/*7*/ issues_model.CommentTypeLabel,
|
||||
},
|
||||
"milestone": {
|
||||
/*8*/ issues_model.CommentTypeMilestone,
|
||||
},
|
||||
"assignee": {
|
||||
/*9*/ issues_model.CommentTypeAssignees,
|
||||
},
|
||||
"title": {
|
||||
/*10*/ issues_model.CommentTypeChangeTitle,
|
||||
},
|
||||
"branch": {
|
||||
/*11*/ issues_model.CommentTypeDeleteBranch,
|
||||
/*25*/ issues_model.CommentTypeChangeTargetBranch,
|
||||
},
|
||||
"time_tracking": {
|
||||
/*12*/ issues_model.CommentTypeStartTracking,
|
||||
/*13*/ issues_model.CommentTypeStopTracking,
|
||||
/*14*/ issues_model.CommentTypeAddTimeManual,
|
||||
/*15*/ issues_model.CommentTypeCancelTracking,
|
||||
/*26*/ issues_model.CommentTypeDeleteTimeManual,
|
||||
/*38*/ issues_model.CommentTypeChangeTimeEstimate,
|
||||
},
|
||||
"deadline": {
|
||||
/*16*/ issues_model.CommentTypeAddedDeadline,
|
||||
/*17*/ issues_model.CommentTypeModifiedDeadline,
|
||||
/*18*/ issues_model.CommentTypeRemovedDeadline,
|
||||
},
|
||||
"dependency": {
|
||||
/*19*/ issues_model.CommentTypeAddDependency,
|
||||
/*20*/ issues_model.CommentTypeRemoveDependency,
|
||||
},
|
||||
"lock": {
|
||||
/*23*/ issues_model.CommentTypeLock,
|
||||
/*24*/ issues_model.CommentTypeUnlock,
|
||||
},
|
||||
"review_request": {
|
||||
/*27*/ issues_model.CommentTypeReviewRequest,
|
||||
},
|
||||
"pull_request_push": {
|
||||
/*29*/ issues_model.CommentTypePullRequestPush,
|
||||
},
|
||||
"project": {
|
||||
/*30*/ issues_model.CommentTypeProject,
|
||||
/*31*/ issues_model.CommentTypeProjectColumn,
|
||||
},
|
||||
"issue_ref": {
|
||||
/*33*/ issues_model.CommentTypeChangeIssueRef,
|
||||
},
|
||||
}
|
||||
|
||||
// UserHiddenCommentTypesFromRequest parse the form to hidden comment types bitset
|
||||
func UserHiddenCommentTypesFromRequest(ctx *context.Context) *big.Int {
|
||||
bitset := new(big.Int)
|
||||
for group, commentTypes := range hiddenCommentTypeGroups {
|
||||
if ctx.FormBool(group) {
|
||||
for _, commentType := range commentTypes {
|
||||
bitset = bitset.SetBit(bitset, int(commentType), 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
return bitset
|
||||
}
|
||||
|
||||
// IsUserHiddenCommentTypeGroupChecked check whether a hidden comment type group is "enabled" (checked on UI)
|
||||
func IsUserHiddenCommentTypeGroupChecked(group string, hiddenCommentTypes *big.Int) (ret bool) {
|
||||
commentTypes, ok := hiddenCommentTypeGroups[group]
|
||||
if !ok {
|
||||
log.Error("the group map for hidden comment types is out of sync, unknown group: %v", group)
|
||||
return false
|
||||
}
|
||||
if hiddenCommentTypes == nil {
|
||||
return false
|
||||
}
|
||||
for _, commentType := range commentTypes {
|
||||
if hiddenCommentTypes.Bit(int(commentType)) == 1 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
// Copyright 2018 The Gogs Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package forms
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"gitea.dev/modules/glob"
|
||||
"gitea.dev/modules/setting"
|
||||
"gitea.dev/modules/test"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestRegisterForm_IsDomainAllowed_Empty(t *testing.T) {
|
||||
defer test.MockVariableValue(&setting.Service)()
|
||||
setting.Service.EmailDomainAllowList = nil
|
||||
form := RegisterForm{}
|
||||
assert.True(t, form.IsEmailDomainAllowed())
|
||||
}
|
||||
|
||||
func TestRegisterForm_IsDomainAllowed_InvalidEmail(t *testing.T) {
|
||||
defer test.MockVariableValue(&setting.Service.EmailDomainAllowList, []glob.Glob{glob.MustCompile("gitea.io")})()
|
||||
|
||||
tt := []struct {
|
||||
email string
|
||||
}{
|
||||
{"invalid-email"},
|
||||
{"gitea.io"},
|
||||
}
|
||||
|
||||
for _, v := range tt {
|
||||
form := RegisterForm{Email: v.email}
|
||||
|
||||
assert.False(t, form.IsEmailDomainAllowed())
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegisterForm_IsDomainAllowed_AllowedEmail(t *testing.T) {
|
||||
defer test.MockVariableValue(&setting.Service.EmailDomainAllowList, []glob.Glob{glob.MustCompile("gitea.io"), glob.MustCompile("*.allow")})()
|
||||
|
||||
tt := []struct {
|
||||
email string
|
||||
valid bool
|
||||
}{
|
||||
{"security@gitea.io", true},
|
||||
{"security@gITea.io", true},
|
||||
{"invalid", false},
|
||||
{"seee@example.com", false},
|
||||
|
||||
{"user@my.allow", true},
|
||||
{"user@my.allow1", false},
|
||||
}
|
||||
|
||||
for _, v := range tt {
|
||||
form := RegisterForm{Email: v.email}
|
||||
|
||||
assert.Equal(t, v.valid, form.IsEmailDomainAllowed())
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegisterForm_IsDomainAllowed_BlockedEmail(t *testing.T) {
|
||||
defer test.MockVariableValue(&setting.Service.EmailDomainBlockList, []glob.Glob{glob.MustCompile("gitea.io"), glob.MustCompile("*.block")})()
|
||||
|
||||
tt := []struct {
|
||||
email string
|
||||
valid bool
|
||||
}{
|
||||
{"security@gitea.io", false},
|
||||
{"security@gitea.example", true},
|
||||
{"invalid", true},
|
||||
|
||||
{"user@my.block", false},
|
||||
{"user@my.block1", true},
|
||||
}
|
||||
|
||||
for _, v := range tt {
|
||||
form := RegisterForm{Email: v.email}
|
||||
|
||||
assert.Equal(t, v.valid, form.IsEmailDomainAllowed())
|
||||
}
|
||||
}
|
||||
|
||||
func TestDetectInvalidOAuth2ApplicationRedirectURI(t *testing.T) {
|
||||
defer test.MockVariableValue(&setting.OAuth2.CustomSchemes)()
|
||||
setting.OAuth2.CustomSchemes = []string{"my-app"}
|
||||
assertValid := func(t *testing.T, s string, valid bool) {
|
||||
ret := DetectInvalidOAuth2ApplicationRedirectURI([]string{s})
|
||||
if valid {
|
||||
assert.Empty(t, ret)
|
||||
} else {
|
||||
assert.Equal(t, s, ret)
|
||||
}
|
||||
}
|
||||
assertValid(t, "my-app:", true)
|
||||
assertValid(t, "my-app:/foo", true)
|
||||
assertValid(t, "http://foo", true)
|
||||
assertValid(t, "https://foo", true)
|
||||
|
||||
assertValid(t, "my-app", false)
|
||||
assertValid(t, "ftp:", false)
|
||||
assertValid(t, "ftp://foo", false)
|
||||
assertValid(t, "https://[invalid", false)
|
||||
|
||||
ret := DetectInvalidOAuth2ApplicationRedirectURI([]string{"my-app:", "http://foo", "https://foo"})
|
||||
assert.Empty(t, ret)
|
||||
ret = DetectInvalidOAuth2ApplicationRedirectURI([]string{"my-app:", "http://foo", "invalid", "https://foo"})
|
||||
assert.Equal(t, "invalid", ret)
|
||||
}
|
||||
Reference in New Issue
Block a user