snapshot of https://github.com/go-gitea/gitea.git (main, 2026-09-15; blobs > 131072B omitted)
Some checks failed
cache-seeder / prune (push) Has been skipped
cache-seeder / frontend (push) Failing after 3s
cache-seeder / python (push) Failing after 3s
cache-seeder / gobuild (push) Failing after 4s
cache-seeder / lint (bindata, lint-backend) (push) Failing after 3s
giteabot backport / giteabot (push) Has been skipped
giteabot / giteabot (push) Has been skipped
cache-prune / prune (push) Has been skipped
release-nightly-snapcraft / build-and-publish (ubuntu-24.04) (push) Has been cancelled
release-nightly-snapcraft / build-and-publish (ubuntu-24.04-arm) (push) Has been cancelled
release-nightly / nightly-binary (push) Has been cancelled
release-nightly / nightly-container (push) Has been cancelled
cron-renovate / cron-renovate (push) Has been skipped

This commit is contained in:
upstream-mirror
2026-09-15 21:41:59 +05:00
commit 52ae0c5802
6280 changed files with 624193 additions and 0 deletions

68
services/forms/admin.go Normal file
View File

@@ -0,0 +1,68 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package forms
import (
"gitea.dev/modules/structs"
"gitea.dev/modules/web/middleware"
)
// AdminCreateUserForm form for admin to create user
type AdminCreateUserForm struct {
middleware.FormDefaultValidator
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 {
middleware.FormDefaultValidator
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 {
middleware.FormDefaultValidator
Description string `binding:"Required" locale:"admin.badges.description"`
ImageURL string `binding:"ValidUrl" locale:"admin.badges.image_url"`
}
// AdminEditUserForm form for admin to create user
type AdminEditUserForm struct {
middleware.FormDefaultValidator
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
}
// AdminDashboardForm form for admin dashboard operations
type AdminDashboardForm struct {
middleware.FormDefaultValidator
Op string `binding:"required"`
From string
}

View File

@@ -0,0 +1,92 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package forms
import "gitea.dev/modules/web/middleware"
// AuthenticationForm form for authentication
type AuthenticationForm struct {
middleware.FormDefaultValidator
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:"TrimSpace;AlphaDashDot;MaxSize(5)"`
SSPIDefaultLanguage string
}

61
services/forms/org.go Normal file
View File

@@ -0,0 +1,61 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package forms
import (
"gitea.dev/modules/structs"
"gitea.dev/modules/web/middleware"
)
// ________ .__ __ .__
// \_____ \_______ _________ ____ |__|____________ _/ |_|__| ____ ____
// / | \_ __ \/ ___\__ \ / \| \___ /\__ \\ __\ |/ _ \ / \
// / | \ | \/ /_/ > __ \| | \ |/ / / __ \| | | ( <_> ) | \
// \_______ /__| \___ (____ /___| /__/_____ \(____ /__| |__|\____/|___| /
// \/ /_____/ \/ \/ \/ \/ \/
// CreateOrgForm form for creating organization
type CreateOrgForm struct {
middleware.FormDefaultValidator
OrgName string `binding:"Required;Username;MaxSize(40)" locale:"org.org_name_holder"`
Visibility structs.VisibleType
RepoAdminChangeTeamAccess bool
}
// UpdateOrgSettingForm form for updating organization settings
type UpdateOrgSettingForm struct {
middleware.FormDefaultValidator
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
}
type RenameOrgForm struct {
middleware.FormDefaultValidator
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 {
middleware.FormDefaultValidator
TeamName string `binding:"Required;AlphaDashDot;MaxSize(255)"`
Description string `binding:"MaxSize(255)"`
Permission string
RepoAccess string
CanCreateOrgRepo bool
Visibility string `binding:"OmitEmpty;In(public,limited,private)"`
}

View File

@@ -0,0 +1,19 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package forms
import "gitea.dev/modules/web/middleware"
type PackageCleanupRuleForm struct {
middleware.FormDefaultValidator
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)"`
}

View File

@@ -0,0 +1,21 @@
// Copyright 2017 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package forms
import "gitea.dev/modules/web/middleware"
// NewBranchForm form for creating a new branch
type NewBranchForm struct {
middleware.FormDefaultValidator
NewBranchName string `binding:"Required;MaxSize(100);GitRefName"`
CurrentPath string
CreateTag bool
}
// RenameBranchForm form for rename a branch
type RenameBranchForm struct {
middleware.FormDefaultValidator
From string `binding:"Required;MaxSize(100);GitRefName"`
To string `binding:"Required;MaxSize(100);GitRefName"`
}

585
services/forms/repo_form.go Normal file
View File

@@ -0,0 +1,585 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Copyright 2017 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package forms
import (
"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/validation"
"gitea.dev/modules/web/middleware"
"gitea.dev/services/webhook"
)
// CreateRepoForm form for creating repository
type CreateRepoForm struct {
middleware.FormDefaultValidator
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 `binding:"MaxSize(1024)"`
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
}
// MigrateRepoForm form for migrating repository
// this is used to interact with web ui
type MigrateRepoForm struct {
middleware.FormDefaultValidator
// 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"`
}
// RepoSettingForm form for changing repository settings
type RepoSettingForm struct {
middleware.FormDefaultValidator
RepoName string `binding:"TrimSpace;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
}
// ProtectBranchForm form for changing protected branch settings
type ProtectBranchForm struct {
middleware.FormDefaultValidator
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
BlockOnCodeownerReviews bool
BlockOnOutdatedBranch bool
DismissStaleApprovals bool
IgnoreStaleApprovals bool
RequireSignedCommits bool
ProtectedFilePatterns string
UnprotectedFilePatterns string
BlockAdminMergeOverride bool
}
// WebhookForm form for changing web hook
type WebhookForm struct {
middleware.FormDefaultValidator
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 {
middleware.FormDefaultValidator
PayloadURL string `binding:"Required;ValidUrl"`
HTTPMethod string `binding:"Required;In(POST,GET)"`
ContentType int `binding:"Required"`
WebhookForm
}
// NewGogshookForm form for creating gogs hook
type NewGogshookForm struct {
middleware.FormDefaultValidator
PayloadURL string `binding:"Required;ValidUrl"`
ContentType int `binding:"Required"`
WebhookForm
}
// 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
}
func (f *NewSlackHookForm) Validate(ctx *middleware.ValidateContext, errs validation.BindingErrors) validation.BindingErrors {
if !webhook.IsValidSlackChannel(strings.TrimSpace(f.Channel)) {
errs = middleware.AddValidationError(errs, "Channel", ctx.Locale.TrString("repo.settings.add_webhook.invalid_channel_name"))
}
return errs
}
// NewDiscordHookForm form for creating discord hook
type NewDiscordHookForm struct {
middleware.FormDefaultValidator
PayloadURL string `binding:"Required;ValidUrl"`
Username string
IconURL string
WebhookForm
}
// NewDingtalkHookForm form for creating dingtalk hook
type NewDingtalkHookForm struct {
middleware.FormDefaultValidator
PayloadURL string `binding:"Required;ValidUrl"`
WebhookForm
}
// NewTelegramHookForm form for creating telegram hook
type NewTelegramHookForm struct {
middleware.FormDefaultValidator
BotToken string `binding:"Required"`
ChatID string `binding:"Required"`
ThreadID string
WebhookForm
}
// NewMatrixHookForm form for creating Matrix hook
type NewMatrixHookForm struct {
middleware.FormDefaultValidator
HomeserverURL string `binding:"Required;ValidUrl"`
RoomID string `binding:"Required"`
MessageType int
WebhookForm
}
// NewMSTeamsHookForm form for creating MS Teams hook
type NewMSTeamsHookForm struct {
middleware.FormDefaultValidator
PayloadURL string `binding:"Required;ValidUrl"`
WebhookForm
}
// NewFeishuHookForm form for creating feishu hook
type NewFeishuHookForm struct {
middleware.FormDefaultValidator
PayloadURL string `binding:"Required;ValidUrl"`
WebhookForm
}
// NewWechatWorkHookForm form for creating wechatwork hook
type NewWechatWorkHookForm struct {
middleware.FormDefaultValidator
PayloadURL string `binding:"Required;ValidUrl"`
WebhookForm
}
// NewPackagistHookForm form for creating packagist hook
type NewPackagistHookForm struct {
middleware.FormDefaultValidator
Username string `binding:"Required"`
APIToken string `binding:"Required"`
PackageURL string `binding:"Required;ValidUrl"`
WebhookForm
}
// CreateIssueForm form for creating issue
type CreateIssueForm struct {
middleware.FormDefaultValidator
Title string `binding:"TrimSpace;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
}
// CreateCommentForm form for creating comment
type CreateCommentForm struct {
middleware.FormDefaultValidator
Content string
Status string `binding:"OmitEmpty;In(reopen,close)"`
Files []string
}
// ReactionForm form for adding and removing reaction
type ReactionForm struct {
middleware.FormDefaultValidator
Content string `binding:"Required"`
}
// IssueLockForm form for locking an issue
type IssueLockForm struct {
middleware.FormDefaultValidator
Reason string `binding:"Required"`
}
// CreateProjectForm form for creating a project
type CreateProjectForm struct {
middleware.FormDefaultValidator
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 {
middleware.FormDefaultValidator
Title string `binding:"Required;MaxSize(100)"`
Sorting int8
Color string `binding:"MaxSize(7)"`
}
// CreateMilestoneForm form for creating milestone
type CreateMilestoneForm struct {
middleware.FormDefaultValidator
Title string `binding:"Required;MaxSize(50)"`
Content string
Deadline string
}
// CreateLabelForm form for creating label
type CreateLabelForm struct {
middleware.FormDefaultValidator
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"`
}
// InitializeLabelsForm form for initializing labels
type InitializeLabelsForm struct {
middleware.FormDefaultValidator
TemplateName string `binding:"Required"`
}
// MergePullRequestForm form for merging Pull Request
// swagger:model MergePullRequestOption
type MergePullRequestForm struct {
middleware.FormDefaultValidator
// 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
}
// CodeCommentForm form for adding code comments for PRs
type CodeCommentForm struct {
middleware.FormDefaultValidator
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
}
// SubmitReviewForm for submitting a finished code review
type SubmitReviewForm struct {
middleware.FormDefaultValidator
Content string
Type string
CommitID string
Files []string
}
// 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 {
middleware.FormDefaultValidator
ReviewID int64 `binding:"Required"`
Message string
}
// UpdateAllowEditsForm form for changing if PR allows edits from maintainers
type UpdateAllowEditsForm struct {
middleware.FormDefaultValidator
AllowMaintainerEdit bool
}
// __________ .__
// \______ \ ____ | | ____ _____ ______ ____
// | _// __ \| | _/ __ \\__ \ / ___// __ \
// | | \ ___/| |_\ ___/ / __ \_\___ \\ ___/
// |____|_ /\___ >____/\___ >____ /____ >\___ >
// \/ \/ \/ \/ \/ \/
// NewReleaseForm form for creating release
type NewReleaseForm struct {
middleware.FormDefaultValidator
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
}
// GenerateReleaseNotesForm retrieves release notes recommendations.
type GenerateReleaseNotesForm struct {
middleware.FormDefaultValidator
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)"`
}
// EditReleaseForm form for changing release
type EditReleaseForm struct {
middleware.FormDefaultValidator
Title string `form:"title" binding:"TrimSpace;Required;MaxSize(255)"`
Content string `form:"content"`
Draft string `form:"draft"`
Prerelease bool `form:"prerelease"`
Files []string
}
type WikiEditForm struct {
middleware.FormDefaultValidator
Title string `binding:"TrimSpace;Required"`
Content string
Message string
}
// AddTimeManuallyForm form that adds spent time manually.
type AddTimeManuallyForm struct {
middleware.FormDefaultValidator
Hours int `binding:"Range(0,1000)"`
Minutes int `binding:"Range(0,1000)"`
}
// SaveTopicForm form for save topics for repository
type SaveTopicForm struct {
middleware.FormDefaultValidator
Topics []string `binding:"topics;Required;"`
}
// AddDeployTokenForm form for adding a deploy token to a repository
type AddDeployTokenForm struct {
middleware.FormDefaultValidator
Title string `binding:"Required;MaxSize(50)"`
IsWritable bool
}

View File

@@ -0,0 +1,52 @@
// Copyright 2025 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package forms
import (
"gitea.dev/modules/optional"
"gitea.dev/modules/web/middleware"
)
type CommitCommonForm struct {
middleware.FormDefaultValidator
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
}
type CommitCommonFormInterface interface {
GetCommitCommonForm() *CommitCommonForm
}
func (f *CommitCommonForm) GetCommitCommonForm() *CommitCommonForm {
return f
}
type EditRepoFileForm struct {
middleware.FormDefaultValidator
CommitCommonForm
Content optional.Option[string]
}
type DeleteRepoFileForm struct {
middleware.FormDefaultValidator
CommitCommonForm
}
type UploadRepoFileForm struct {
middleware.FormDefaultValidator
CommitCommonForm
Files []string
}
type CherryPickForm struct {
middleware.FormDefaultValidator
CommitCommonForm
Revert bool
}

View File

@@ -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)
})
}

View File

@@ -0,0 +1,14 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package forms
import "gitea.dev/modules/web/middleware"
// ProtectTagForm form for changing protected tag settings
type ProtectTagForm struct {
middleware.FormDefaultValidator
NamePattern string `binding:"Required;GlobOrRegexPattern"`
AllowlistUsers string
AllowlistTeams string
}

12
services/forms/runner.go Normal file
View File

@@ -0,0 +1,12 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package forms
import "gitea.dev/modules/web/middleware"
// EditRunnerForm form for admin to create runner
type EditRunnerForm struct {
middleware.FormDefaultValidator
Description string
}

314
services/forms/user_form.go Normal file
View File

@@ -0,0 +1,314 @@
// 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"
"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"
)
// InstallForm form for installation page
type InstallForm struct {
middleware.FormDefaultValidator
DbType string `binding:"TrimSpace;Required"`
DbHost string `binding:"TrimSpace"`
DbUser string `binding:"TrimSpace"`
DbPasswd string
DbName string `binding:"TrimSpace"`
SSLMode string `binding:"TrimSpace"`
DbPath string `binding:"TrimSpace"`
DbSchema string `binding:"TrimSpace"`
AppName string `binding:"TrimSpace;Required" locale:"install.app_name"`
RepoRootPath string `binding:"TrimSpace;Required"`
LFSRootPath string `binding:"TrimSpace"`
RunUser string `binding:"TrimSpace;Required"`
Domain string `binding:"TrimSpace;Required"`
SSHPort int
HTTPPort string `binding:"TrimSpace;Required"`
AppURL string `binding:"TrimSpace;Required"`
LogRootPath string `binding:"TrimSpace;Required"`
SMTPAddr string `binding:"TrimSpace"`
SMTPPort string `binding:"TrimSpace"`
SMTPFrom string `binding:"TrimSpace"`
SMTPUser string `binding:"TrimSpace;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 `binding:"TrimSpace"`
PasswordAlgorithm string `binding:"TrimSpace"`
AdminName string `binding:"TrimSpace;OmitEmpty;Username;MaxSize(30)" locale:"install.admin_name"`
AdminPasswd string `binding:"OmitEmpty;MaxSize(255)" locale:"install.admin_password"`
AdminConfirmPasswd string
AdminEmail string `binding:"TrimSpace;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
}
// _____ ____ _________________ ___
// / _ \ | | \__ ___/ | \
// / /_\ \| | / | | / ~ \
// / | \ | / | | \ Y /
// \____|__ /______/ |____| \___|_ /
// \/ \/
// RegisterForm form for registering
type RegisterForm struct {
middleware.FormDefaultValidator
UserName string `binding:"Required;Username;MaxSize(40)"`
Email string `binding:"Required;MaxSize(254)"`
Password string `binding:"MaxSize(255)"`
Retype string
}
// 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 {
middleware.FormDefaultValidator
Password string `binding:"Required;MaxSize(255)"`
Retype string
}
// SignInForm form for signing in with user/password
type SignInForm struct {
middleware.FormDefaultValidator
UserName string `binding:"Required;MaxSize(254)"`
// TODO remove required from password for SecondFactorAuthentication
Password string `binding:"Required;MaxSize(255)"`
Remember bool
}
// AuthorizationForm form for authorizing oauth2 clients
type AuthorizationForm struct {
middleware.FormDefaultValidator
ResponseType string
ClientID string
RedirectURI string
State string
Scope string
Nonce string
// PKCE support
CodeChallengeMethod string // S256, plain
CodeChallenge string
}
// GrantApplicationForm form for authorizing oauth2 clients
type GrantApplicationForm struct {
middleware.FormDefaultValidator
ClientID string `binding:"Required"`
Granted bool
RedirectURI string
State string
Scope string
Nonce string
}
// AccessTokenForm for issuing access tokens from authorization codes or refresh tokens
type AccessTokenForm struct {
middleware.FormDefaultValidator
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"`
}
// IntrospectTokenForm for introspecting tokens
type IntrospectTokenForm struct {
middleware.FormDefaultValidator
Token string `json:"token"`
}
// __________________________________________.___ _______ ________ _________
// / _____/\_ _____/\__ ___/\__ ___/| |\ \ / _____/ / _____/
// \_____ \ | __)_ | | | | | |/ | \/ \ ___ \_____ \
// / \ | \ | | | | | / | \ \_\ \/ \
// /_______ //_______ / |____| |____| |___\____|__ /\______ /_______ /
// \/ \/ \/ \/ \/
// UpdateProfileForm form for updating profile
type UpdateProfileForm struct {
middleware.FormDefaultValidator
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
}
// UpdateLanguageForm form for updating profile
type UpdateLanguageForm struct {
middleware.FormDefaultValidator
Language string
}
const AvatarLocal = "local" // the AvatarForm.Source value that selects an uploaded avatar
// AvatarForm form for changing avatar
type AvatarForm struct {
middleware.FormDefaultValidator
Source string
Avatar *multipart.FileHeader
Gravatar string `binding:"OmitEmpty;Email;MaxSize(254)"`
}
// AddEmailForm form for adding new email
type AddEmailForm struct {
middleware.FormDefaultValidator
Email string `binding:"Required;Email;MaxSize(254)"`
}
// UpdateThemeForm form for updating a users' theme
type UpdateThemeForm struct {
middleware.FormDefaultValidator
Theme string `binding:"Required;MaxSize(255)"`
}
// ChangePasswordForm form for changing password
type ChangePasswordForm struct {
middleware.FormDefaultValidator
OldPassword string `form:"old_password" binding:"MaxSize(255)"`
Password string `form:"password" binding:"Required;MaxSize(255)"`
Retype string `form:"retype"`
}
// AddOpenIDForm is for changing openid uri
type AddOpenIDForm struct {
middleware.FormDefaultValidator
Openid string `binding:"Required;MaxSize(256)"`
}
// AddKeyForm form for adding SSH/GPG key
type AddKeyForm struct {
middleware.FormDefaultValidator
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
}
// AddSecretForm for adding secrets
type AddSecretForm struct {
middleware.FormDefaultValidator
Name string `binding:"Required;MaxSize(255)"`
Data string `binding:"Required;MaxSize(65535)"`
Description string `binding:"MaxSize(65535)"`
}
type EditVariableForm struct {
middleware.FormDefaultValidator
Name string `binding:"Required;MaxSize(255)"`
Data string `binding:"Required;MaxSize(65535)"`
Description string `binding:"MaxSize(65535)"`
}
// NewAccessTokenForm form for creating access token
type NewAccessTokenForm struct {
middleware.FormDefaultValidator
Name string `binding:"Required;MaxSize(255)" locale:"settings.token_name"`
}
// 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 ""
}
func (f *EditOAuth2ApplicationForm) Validate(ctx *middleware.ValidateContext, errs validation.BindingErrors) validation.BindingErrors {
invalidURI := DetectInvalidOAuth2ApplicationRedirectURI(util.SplitTrimSpace(f.RedirectURIs, "\n"))
if invalidURI != "" {
errs = middleware.AddValidationError(errs, "RedirectURIs", "RedirectURIs: "+ctx.Locale.TrString("form.url_error", `"`+invalidURI+`"`))
}
return errs
}
// TwoFactorAuthForm for logging in with 2FA token.
type TwoFactorAuthForm struct {
middleware.FormDefaultValidator
Passcode string `binding:"Required"`
}
// TwoFactorScratchAuthForm for logging in with 2FA scratch token.
type TwoFactorScratchAuthForm struct {
middleware.FormDefaultValidator
Token string `binding:"Required"`
}
// WebauthnRegistrationForm for reserving an WebAuthn name
type WebauthnRegistrationForm struct {
middleware.FormDefaultValidator
Name string `binding:"Required"`
}
// PackageSettingForm form for package settings
type PackageSettingForm struct {
middleware.FormDefaultValidator
Action string
RepoName string `form:"repo_name"`
}
type BlockUserForm struct {
middleware.FormDefaultValidator
Action string `binding:"Required;In(block,unblock,note)"`
Blockee string `binding:"Required"`
Note string
}

View File

@@ -0,0 +1,27 @@
// Copyright 2017 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package forms
import "gitea.dev/modules/web/middleware"
// SignInOpenIDForm form for signing in with OpenID
type SignInOpenIDForm struct {
middleware.FormDefaultValidator
Openid string `binding:"Required;MaxSize(256)"`
Remember bool
}
// SignUpOpenIDForm form for signin up with OpenID
type SignUpOpenIDForm struct {
middleware.FormDefaultValidator
UserName string `binding:"Required;Username;MaxSize(40)"`
Email string `binding:"Required;Email;MaxSize(254)"`
}
// ConnectOpenIDForm form for connecting an existing account to an OpenID URI
type ConnectOpenIDForm struct {
middleware.FormDefaultValidator
UserName string `binding:"Required;MaxSize(254)"`
Password string `binding:"Required;MaxSize(255)"`
}

View File

@@ -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
}

View File

@@ -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)
}