Skip to content

Commit 42adb4d

Browse files
authored
feat: bump CTFd to 3.8.0, add configuration attributes (#188)
1 parent 75a7516 commit 42adb4d

File tree

7 files changed

+122
-5
lines changed

7 files changed

+122
-5
lines changed

.github/workflows/ci.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
runs-on: ubuntu-latest
1515
services:
1616
ctfd:
17-
image: ctfd/ctfd:3.7.7@sha256:9847758cdafc5ab86bdc121353dcf5a27a29ce313587270ee90a71bfbda2b910
17+
image: ctfd/ctfd:3.8.0@sha256:61712c4af6e9cddccfafc4503484c8091f6325be286d407595b922dc9552b5ae
1818
ports:
1919
- 8000:8000
2020
steps:

action.yaml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ inputs:
4848
description: 'Whether to allow team creation by players or not.'
4949
accounts_team_size:
5050
description: 'Maximum size (number of players) in a team.'
51+
accounts_password_min_length:
52+
description: 'Minimal length of password.'
5153
accounts_num_teams:
5254
description: 'The total number of teams allowed.'
5355
accounts_num_users:
@@ -58,6 +60,17 @@ inputs:
5860
description: 'Maximum number of invalid submissions per minute (per user/team). We suggest you use it as part of an anti-brute-force strategy (rate limiting).'
5961
accounts_name_changes:
6062
description: 'Whether a user can change its name or not.'
63+
# Challenges
64+
challenges_view_self_submissions:
65+
description: 'Whether a player can see itw own previous submissions.'
66+
challenges_max_attempts_behavior:
67+
description: 'The behavior to adopt in case a player reached the submission rate limiting.'
68+
challenges_max_attempts_timeout:
69+
description: 'The duration of the submission rate limit for further submissions.'
70+
challenges_hints_free_public_access:
71+
description: 'Control whether users must be logged in to see free hints.'
72+
challenges_challenge_ratings:
73+
description: 'Who can see and submit challenge ratings.'
6174
# Pages
6275
pages_robots_txt:
6376
description: 'Define the /robots.txt file content, for web crawlers indexing.'
@@ -133,6 +146,8 @@ inputs:
133146
# Social
134147
social_shares:
135148
description: 'Whether to enable users share they solved a challenge or not.'
149+
social_template:
150+
description: 'A template for social shares. Provide a path to a locally-accessible file.'
136151
# Legal
137152
legal_tos_url:
138153
description: 'The Terms of Services URL.'
@@ -175,11 +190,17 @@ runs:
175190
ACCOUNTS_VERIFY_EMAILS: ${{ inputs.accounts_verify_emails }}
176191
ACCOUNTS_TEAM_CREATION: ${{ inputs.accounts_team_creation }}
177192
ACCOUNTS_TEAM_SIZE: ${{ inputs.accounts_team_size }}
193+
ACCOUNTS_PASSWORD_MIN_LENGTH: ${{ inputs.accounts_password_min_length }}
178194
ACCOUNTS_NUM_TEAMS: ${{ inputs.accounts_num_teams }}
179195
ACCOUNTS_NUM_USERS: ${{ inputs.accounts_num_users }}
180196
ACCOUNTS_TEAM_DISBANDING: ${{ inputs.accounts_team_disbanding }}
181197
ACCOUNTS_INCORRECT_SUBMISSIONS_PER_MINUTE: ${{ inputs.accounts_incorrect_submissions_per_minute }}
182198
ACCOUNTS_NAME_CHANGES: ${{ inputs.accounts_name_changes }}
199+
CHALLENGES_VIEW_SELF_SUBMISSIONS: ${{ inputs.challenges_view_self_submissions }}
200+
CHALLENGES_MAX_ATTEMPTS_BEHAVIOR: ${{ inputs.challenges_max_attempts_behavior }}
201+
CHALLENGES_MAX_ATTEMPTS_TIMEOUT: ${{ inputs.challenges_max_attempts_timeout }}
202+
CHALLENGES_HINTS_FREE_PUBLIC_ACCESS: ${{ inputs.challenges_hints_free_public_access }}
203+
CHALLENGES_CHALLENGE_RATINGS: ${{ inputs.challenges_challenge_ratings }}
183204
PAGES_ROBOTS_TXT: ${{ inputs.pages_robots_txt }}
184205
MAJOR_LEAGUE_CYBER_CLIENT_ID: ${{ inputs.major_league_cyber_client_id }}
185206
MAJOR_LEAGUE_CYBER_CLIENT_SECRET: ${{ inputs.major_league_cyber_client_secret }}
@@ -212,6 +233,7 @@ runs:
212233
TIME_FREEZE: ${{ inputs.time_freeze }}
213234
TIME_VIEW_AFTER: ${{ inputs.time_view_after }}
214235
SOCIAL_SHARES: ${{ inputs.social_shares }}
236+
SOCIAL_TEMPLATE: ${{ inputs.social_template }}
215237
LEGAL_TOS_URL: ${{ inputs.legal_tos_url }}
216238
LEGAL_TOS_CONTENT: ${{ inputs.legal_tos_content }}
217239
LEGAL_PRIVACY_POLICY_URL: ${{ inputs.legal_privacy_policy_url }}

cmd/ctfd-setup/main.go

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,12 @@ func main() {
155155
Sources: cli.EnvVars("ACCOUNTS_TEAM_SIZE", "PLUGIN_ACCOUNTS_TEAM_SIZE"),
156156
Category: configuration,
157157
},
158+
&cli.IntFlag{
159+
Name: "accounts.password_min_length",
160+
Usage: "Minimal length of password.",
161+
Sources: cli.EnvVars("ACCOUNTS_PASSWORD_MIN_LENGTH", "PLUGIN_ACCOUNTS_PASSWORD_MIN_LENGTH"),
162+
Category: configuration,
163+
},
158164
&cli.IntFlag{
159165
Name: "accounts.num_teams",
160166
Usage: "The total number of teams allowed.",
@@ -185,6 +191,39 @@ func main() {
185191
Sources: cli.EnvVars("ACCOUNTS_NAME_CHANGES", "PLUGIN_ACCOUNTS_NAME_CHANGES"),
186192
Category: configuration,
187193
},
194+
// => Challenges
195+
&cli.BoolFlag{
196+
Name: "challenges.view_self_submissions",
197+
Usage: "Whether a player can see itw own previous submissions.",
198+
Sources: cli.EnvVars("CHALLENGES_VIEW_SELF_SUBMISSIONS", "PLUGIN_CHALLENGES_VIEW_SELF_SUBMISSIONS"),
199+
Category: configuration,
200+
},
201+
&cli.StringFlag{
202+
Name: "challenges.max_attempts_behavior",
203+
Usage: "The behavior to adopt in case a player reached the submission rate limiting.",
204+
Value: "lockout",
205+
Sources: cli.EnvVars("CHALLENGES_MAX_ATTEMPTS_BEHAVIOR", "PLUGIN_CHALLENGES_MAX_ATTEMPTS_BEHAVIOR"),
206+
Category: configuration,
207+
},
208+
&cli.IntFlag{
209+
Name: "challenges.max_attempts_timeout",
210+
Usage: "The duration of the submission rate limit for further submissions.",
211+
Sources: cli.EnvVars("CHALLENGES_MAX_ATTEMPTS_TIMEOUT", "PLUGIN_CHALLENGES_MAX_ATTEMPTS_TIMEOUT"),
212+
Category: configuration,
213+
},
214+
&cli.BoolFlag{
215+
Name: "challenges.hints_free_public_access",
216+
Usage: "Control whether users must be logged in to see free hints.",
217+
Sources: cli.EnvVars("CHALLENGES_HINTS_FREE_PUBLIC_ACCESS", "PUBLIC_CHALLENGES_HINTS_FREE_PUBLIC_ACCESS"),
218+
Category: configuration,
219+
},
220+
&cli.StringFlag{
221+
Name: "challenges.challenge_ratings",
222+
Usage: "Who can see and submit challenge ratings.",
223+
Value: "public",
224+
Sources: cli.EnvVars("CHALLENGES_CHALLENGE_RATINGS", "PUBLIC_CHALLENGES_CHALLENGE_RATINGS"),
225+
Category: configuration,
226+
},
188227
// => Pages
189228
&cli.StringFlag{
190229
Name: "pages.robots_txt",
@@ -388,6 +427,12 @@ func main() {
388427
Sources: cli.EnvVars("SOCIAL_SHARES", "PLUGIN_SOCIAL_SHARES"),
389428
Category: configuration,
390429
},
430+
&cli.StringFlag{
431+
Name: "social.template",
432+
Usage: "A template for social shares. Provide a path to a locally-accessible file.",
433+
Sources: cli.EnvVars("SOCIAL_TEMPLATE", "PUBLIC_SOCIAL_TEMPLATE"),
434+
Category: configuration,
435+
},
391436
// => Legal
392437
&cli.StringFlag{
393438
Name: "legal.tos.url",
@@ -516,6 +561,11 @@ func run(ctx context.Context, cmd *cli.Command) error {
516561
if err != nil {
517562
return err
518563
}
564+
socialTpl, err := filePtr(cmd, "social.template")
565+
if err != nil {
566+
return err
567+
}
568+
519569
tos, err := filePtr(cmd, "legal.tos.content")
520570
if err != nil {
521571
return err
@@ -545,12 +595,20 @@ func run(ctx context.Context, cmd *cli.Command) error {
545595
VerifyEmails: cmd.Bool("accounts.verify_emails"),
546596
TeamCreation: boolPtr(cmd, "accounts.team_creation"),
547597
TeamSize: intPtr(cmd, "accounts.team_size"),
598+
PasswordMinLength: intPtr(cmd, "accounts.password_min_length"),
548599
NumTeams: intPtr(cmd, "accounts.num_teams"),
549600
NumUsers: intPtr(cmd, "accounts.num_users"),
550601
TeamDisbanding: stringPtr(cmd, "accounts.team_disbanding"),
551602
IncorrectSubmissionsPerMinute: intPtr(cmd, "accounts.incorrect_submissions_per_minute"),
552603
NameChanges: boolPtr(cmd, "accounts.name_changes"),
553604
},
605+
Challenges: &ctfdsetup.Challenges{
606+
ViewSelfSubmission: cmd.Bool("challenges.view_self_submissions"),
607+
MaxAttemptsBehavior: cmd.String("challenges.max_attempts_behavior"),
608+
MaxAttemptsTimeout: cmd.Int("challenges.max_attempts_timeout"),
609+
HintsFreePublicAccess: cmd.Bool("challenges.hints_free_public_access"),
610+
ChallengeRatings: cmd.String("challenges.challenge_ratings"),
611+
},
554612
Pages: &ctfdsetup.Pages{
555613
RobotsTxt: robotsTxt,
556614
},
@@ -603,7 +661,8 @@ func run(ctx context.Context, cmd *cli.Command) error {
603661
ViewAfter: boolPtr(cmd, "time.view_after"),
604662
},
605663
Social: &ctfdsetup.Social{
606-
Shares: boolPtr(cmd, "social.shares"),
664+
Shares: boolPtr(cmd, "social.shares"),
665+
Template: socialTpl,
607666
},
608667
Legal: &ctfdsetup.Legal{
609668
TOS: ctfdsetup.ExternalReference{

config.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type (
1717
Appearance Appearance `yaml:"appearance" json:"appearance" jsonschema:"required"`
1818
Theme *Theme `yaml:"theme,omitempty" json:"theme,omitempty"`
1919
Accounts *Accounts `yaml:"accounts,omitempty" json:"accounts,omitempty"`
20+
Challenges *Challenges `yaml:"challenges,omitempty" json:"challenges,omitempty"`
2021
Pages *Pages `yaml:"pages,omitempty" json:"pages,omitempty"`
2122
MajorLeagueCyber *MajorLeagueCyber `yaml:"major_league_cyber,omitempty" json:"major_league_cyber,omitempty"`
2223
Settings *Settings `yaml:"settings,omitempty" json:"settings,omitempty"`
@@ -88,6 +89,9 @@ type (
8889
// Maximum size (number of players) in a team.
8990
TeamSize *int `yaml:"team_size,omitempty" json:"team_size,omitempty"`
9091

92+
// Minimal length of passwords.
93+
PasswordMinLength *int `yaml:"password_min_length,omitempty" json:"password_min_length,omitempty"`
94+
9195
// The total number of teams allowed.
9296
NumTeams *int `yaml:"num_teams,omitempty" json:"num_teams,omitempty"`
9397

@@ -104,6 +108,24 @@ type (
104108
NameChanges *bool `yaml:"name_changes,omitempty" json:"name_changes,omitempty"`
105109
}
106110

111+
// Challenge-related configurations.
112+
Challenges struct {
113+
// Whether a player can see itw own previous submissions.
114+
ViewSelfSubmission bool `yaml:"view_self_submissions" json:"view_self_submissions"`
115+
116+
// The behavior to adopt in case a player reached the submission rate limiting.
117+
MaxAttemptsBehavior string `yaml:"max_attempts_behavior" json:"max_attempts_behavior" jsonschema:"enum=lockout,enum=timeout,default=lockout"`
118+
119+
// The duration of the submission rate limit for further submissions.
120+
MaxAttemptsTimeout int `yaml:"max_attempts_timeout" json:"max_attempts_timeout"`
121+
122+
// Control whether users must be logged in to see free hints.
123+
HintsFreePublicAccess bool `yaml:"hints_free_public_access" json:"hints_free_public_access"`
124+
125+
// Who can see and submit challenge ratings.
126+
ChallengeRatings string `yaml:"challenge_ratings" json:"challenge_ratings" jsonschema:"enum=public,enum=private,enum=disabled,default=public"`
127+
}
128+
107129
// Pages global configuration.
108130
Pages struct {
109131
// Define the /robots.txt file content, for web crawlers indexing.
@@ -238,6 +260,9 @@ type (
238260
Social struct {
239261
// Whether to enable users share they solved a challenge or not.
240262
Shares *bool `yaml:"shares,omitempty" json:"shares,omitempty"`
263+
264+
// A template for social shares.
265+
Template *File `yaml:"template,omitempty" json:"template,omitempty"`
241266
}
242267

243268
// Legal contents for players.
@@ -293,6 +318,10 @@ func NewConfig() *Config {
293318
Settings: &File{},
294319
},
295320
Accounts: &Accounts{},
321+
Challenges: &Challenges{
322+
MaxAttemptsBehavior: "lockout",
323+
ChallengeRatings: "public",
324+
},
296325
Pages: &Pages{
297326
RobotsTxt: &File{},
298327
},

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module github.com/ctfer-io/ctfd-setup
33
go 1.22.2
44

55
require (
6-
github.com/ctfer-io/go-ctfd v0.14.0
6+
github.com/ctfer-io/go-ctfd v0.15.0
77
github.com/invopop/jsonschema v0.13.0
88
github.com/pkg/errors v0.9.1
99
github.com/stretchr/testify v1.11.1

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPn
22
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
33
github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs=
44
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
5-
github.com/ctfer-io/go-ctfd v0.14.0 h1:yEETB4oMWzvEJjyWwQPt/rUrNKyLBFx7NB6e2/IcgII=
6-
github.com/ctfer-io/go-ctfd v0.14.0/go.mod h1:ebgSW8LdP/qtRCpglK4djBp+g6kU5YM98XBZKowiCeY=
5+
github.com/ctfer-io/go-ctfd v0.15.0 h1:gdZK83cOIWassyW+PsyMqlSBFxHhsKh+yjU+fsc5A58=
6+
github.com/ctfer-io/go-ctfd v0.15.0/go.mod h1:cUAbm6dv5OhjR3E3/QaJBGTJ/GJ7vsXdL92SmyN/aQo=
77
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
88
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
99
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

setup.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,13 @@ func updateSetup(ctx context.Context, client *api.Client, conf *Config) error {
144144
TeamCreation: conf.Accounts.TeamCreation,
145145
TeamDisbanding: conf.Accounts.TeamDisbanding,
146146
TeamSize: conf.Accounts.TeamSize,
147+
PasswordMinLength: conf.Accounts.PasswordMinLength,
147148
VerifyEmails: &conf.Accounts.VerifyEmails,
149+
ViewSelfSubmission: conf.Challenges.ViewSelfSubmission,
150+
MaxAttemptsBehavior: conf.Challenges.MaxAttemptsBehavior,
151+
MaxAttemptsTimeout: conf.Challenges.MaxAttemptsTimeout,
152+
HintsFreePublicAccess: conf.Challenges.HintsFreePublicAccess,
153+
ChallengeRatings: conf.Challenges.ChallengeRatings,
148154
RobotsTxt: ptr(string(conf.Pages.RobotsTxt.Content)),
149155
OauthClientID: conf.MajorLeagueCyber.ClientID,
150156
OauthClientSecret: conf.MajorLeagueCyber.ClientSecret,
@@ -180,6 +186,7 @@ func updateSetup(ctx context.Context, client *api.Client, conf *Config) error {
180186
Freeze: conf.Time.Freeze,
181187
ViewAfterCTF: conf.Time.ViewAfter,
182188
SocialShares: conf.Social.Shares,
189+
SocialSharesTemplate: string(conf.Social.Template.Content),
183190
PrivacyURL: conf.Legal.PrivacyPolicy.URL,
184191
PrivacyText: ptr(string(conf.Legal.PrivacyPolicy.Content.Content)),
185192
TOSURL: conf.Legal.TOS.URL,

0 commit comments

Comments
 (0)