Skip to content

Commit d769f9f

Browse files
committed
make student ID as register requird and add new challenge type Abstract
1 parent eaa4fe9 commit d769f9f

File tree

20 files changed

+112
-46
lines changed

20 files changed

+112
-46
lines changed

.github/workflows/ci.yml

+20-21
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ on:
44
push:
55
branches: ["develop", "ci/*", "v*"]
66
tags: ["v*"]
7-
paths: ["src/GZCTF/**"]
7+
paths: ["src/GZCTF/**", ".github/workflows/**"]
88
workflow_dispatch:
99

1010
jobs:
@@ -14,6 +14,10 @@ jobs:
1414
run:
1515
working-directory: src/GZCTF
1616

17+
permissions:
18+
packages: write
19+
contents: read
20+
1721
steps:
1822
- uses: actions/checkout@v4
1923

@@ -51,12 +55,6 @@ jobs:
5155
- name: Docker setup Buildx
5256
uses: docker/setup-buildx-action@v3
5357

54-
- name: Login to Docker Hub
55-
uses: docker/login-action@v3
56-
with:
57-
username: gztime
58-
password: ${{ secrets.DOCKER_PASSWORD }}
59-
6058
- name: Login to GitHub Container Registry
6159
uses: docker/login-action@v3
6260
with:
@@ -82,6 +80,7 @@ jobs:
8280
gztime/gzctf
8381
ghcr.io/${{ github.repository }}/gzctf
8482
registry.cn-shanghai.aliyuncs.com/gztime/gzctf
83+
github-token: ${{ secrets.GITHUB_TOKEN }}
8584
flavor: |
8685
latest=${{ env.RELEASE }}
8786
tags: |
@@ -100,17 +99,17 @@ jobs:
10099
platforms: linux/amd64,linux/arm64
101100
push: true
102101

103-
- name: Prune old packages
104-
uses: vlaurin/[email protected]
105-
with:
106-
dry-run: false
107-
token: ${{ secrets.PACKAGE_TOKEN }}
108-
container: ${{ github.event.repository.name }}/gzctf
109-
keep-tags-regexes: ^v\d+\.\d+\.\d+$
110-
prune-tags-regexes: ^[0-9a-f]{6,40}
111-
keep-tags: |
112-
latest
113-
main
114-
develop
115-
keep-last: 20
116-
prune-untagged: false
102+
#- name: Prune old packages
103+
# uses: vlaurin/[email protected]
104+
# with:
105+
# dry-run: false
106+
# token: ${{ secrets.PACKAGE_TOKEN }}
107+
# container: ${{ github.event.repository.name }}/gzctf
108+
# keep-tags-regexes: ^v\d+\.\d+\.\d+$
109+
# prune-tags-regexes: ^[0-9a-f]{6,40}
110+
# keep-tags: |
111+
# latest
112+
# main
113+
# develop
114+
# keep-last: 20
115+
# prune-untagged: false

src/GZCTF/ClientApp/src/Api.ts

+7
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ export type RegisterModel = ModelWithCaptcha & {
5353
* @minLength 1
5454
*/
5555
password: string;
56+
/**
57+
* 学号
58+
* @minLength 1
59+
* @pattern ^20\d{8}$
60+
*/
61+
stdNumber: string
5662
/**
5763
* 邮箱
5864
* @format email
@@ -633,6 +639,7 @@ export enum ChallengeTag {
633639
Mobile = "Mobile",
634640
PPC = "PPC",
635641
AI = "AI",
642+
Abstract = 'Abstract',
636643
}
637644

638645
/** 列表响应 */

src/GZCTF/ClientApp/src/components/GameJoinModal.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const GameJoinModal: FC<GameJoinModalProps> = (props) => {
2222

2323
const [inviteCode, setInviteCode] = useState('')
2424
const [organization, setOrganization] = useState('')
25-
const [team, setTeam] = useState('')
25+
const [team, setTeam] = useState(teams?.[0]?.id?.toString() ?? '')
2626
const [disabled, setDisabled] = useState(false)
2727

2828
const { t } = useTranslation()

src/GZCTF/ClientApp/src/components/WithNavbar.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ const WithNavBar: FC<WithNavBarProps> = ({
4848
const openColorModal = () => setColorModalOpened(true)
4949

5050
return (
51-
<WithWiderScreen minWidth={minWidth}>
51+
<WithWiderScreen minWidth={minWidth} override={true}>
5252
<Watermark
5353
text={user?.userId ?? ''}
5454
textColor={colorScheme === 'dark' ? theme.colors.gray[3] : theme.colors.gray[7]}

src/GZCTF/ClientApp/src/components/WithWiderScreen.tsx

+8-2
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,21 @@ import IconWiderScreenRequired from '@Components/icon/WiderScreenRequiredIcon'
66

77
interface WithWiderScreenProps extends React.PropsWithChildren {
88
minWidth?: number
9+
override?: boolean
910
}
1011

11-
const WithWiderScreen: FC<WithWiderScreenProps> = ({ children, minWidth = 1080 }) => {
12+
const WithWiderScreen: FC<WithWiderScreenProps> = ({
13+
children,
14+
minWidth = 1080,
15+
override = false,
16+
}) => {
1217
const view = useViewportSize()
1318

1419
const { t } = useTranslation()
1520
const theme = useMantineTheme()
1621

17-
const tooSmall = minWidth > 0 && view.width > 0 && view.width < minWidth
22+
let tooSmall = minWidth > 0 && view.width > 0 && view.width < minWidth
23+
if (override) tooSmall = false
1824

1925
return tooSmall ? (
2026
<Stack gap={0} align="center" justify="center" h="calc(100vh - 32px)">

src/GZCTF/ClientApp/src/locales/en_US/account.json

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"email_new": "New Email",
99
"real_name": "Real Name",
1010
"student_id": "Student ID",
11+
"stdNumber": "Student ID",
1112
"password_old": "Original password",
1213
"password_retype": "Confirm password",
1314
"username_or_email": "Username or Email"

src/GZCTF/ClientApp/src/locales/en_US/challenge.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,8 @@
153153
"ppc": "PPC",
154154
"pwn": "Pwn",
155155
"reverse": "Reverse",
156-
"web": "Web"
156+
"web": "Web",
157+
"abstract": "Abstract"
157158
},
158159
"type": {
159160
"dynamic_attachment": {

src/GZCTF/ClientApp/src/locales/ja_JP/account.json

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"email_new": "新メール",
99
"real_name": "氏名",
1010
"student_id": "学生番号",
11+
"stdNumber": "学生番号",
1112
"password_old": "現在のパスワード",
1213
"password_retype": "パスワード再確認",
1314
"username_or_email": "ユーザー名またはメール"

src/GZCTF/ClientApp/src/locales/ja_JP/challenge.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,8 @@
153153
"ppc": "プログラミング",
154154
"pwn": "Pwn",
155155
"reverse": "リバースエンジニアリング",
156-
"web": "Web"
156+
"web": "Web",
157+
"abstract": "抽象"
157158
},
158159
"type": {
159160
"dynamic_attachment": {

src/GZCTF/ClientApp/src/locales/zh_CN/account.json

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"email_new": "新邮箱",
99
"real_name": "真实姓名",
1010
"student_id": "学工号",
11+
"stdNumber": "学号",
1112
"password_old": "原密码",
1213
"password_retype": "确认密码",
1314
"username_or_email": "用户名或邮箱"

src/GZCTF/ClientApp/src/locales/zh_CN/challenge.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,8 @@
153153
"ppc": "编程",
154154
"pwn": "Pwn",
155155
"reverse": "逆向",
156-
"web": "Web"
156+
"web": "Web",
157+
"abstract": "抽象"
157158
},
158159
"type": {
159160
"dynamic_attachment": {

src/GZCTF/ClientApp/src/pages/account/Register.tsx

+24-9
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const Register: FC = () => {
1717
const [retypedPwd, setRetypedPwd] = useInputState('')
1818
const [uname, setUname] = useInputState('')
1919
const [email, setEmail] = useInputState('')
20+
const [stdNumber, setStdNumber] = useInputState('')
2021
const [disabled, setDisabled] = useState(false)
2122

2223
const navigate = useNavigate()
@@ -91,6 +92,7 @@ const Register: FC = () => {
9192
userName: uname,
9293
password: pwd,
9394
email: email,
95+
stdNumber: stdNumber,
9496
challenge: token,
9597
})
9698
const data = RegisterStatusMap.get(res.data.data)
@@ -127,23 +129,36 @@ const Register: FC = () => {
127129
<AccountView onSubmit={onRegister}>
128130
<TextInput
129131
required
130-
label={t('account.label.email')}
131-
type="email"
132-
placeholder="[email protected]"
132+
label={t('account.label.username')}
133+
type="text"
134+
placeholder="ctfer"
133135
w="100%"
134-
value={email}
136+
value={uname}
135137
disabled={disabled}
136-
onChange={(event) => setEmail(event.currentTarget.value)}
138+
onChange={(event) => setUname(event.currentTarget.value)}
137139
/>
138140
<TextInput
139141
required
140-
label={t('account.label.username')}
142+
label={t('account.label.stdNumber')}
141143
type="text"
142-
placeholder="ctfer"
144+
placeholder="2024000000"
143145
w="100%"
144-
value={uname}
146+
value={stdNumber}
145147
disabled={disabled}
146-
onChange={(event) => setUname(event.currentTarget.value)}
148+
onChange={(event) => [
149+
setStdNumber(event.currentTarget.value),
150+
setEmail(event.currentTarget.value + '@bupt.cn'),
151+
]}
152+
/>
153+
<TextInput
154+
required
155+
label={t('account.label.email')}
156+
type="email"
157+
placeholder="[email protected]"
158+
w="100%"
159+
value={email}
160+
disabled={disabled}
161+
onChange={(event) => setEmail(event.currentTarget.value)}
147162
/>
148163
<StrengthPasswordInput
149164
value={pwd}

src/GZCTF/ClientApp/src/utils/Shared.tsx

+11
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
mdiChip,
2222
mdiClose,
2323
mdiConsole,
24+
mdiEmoticonLolOutline,
2425
mdiEthereum,
2526
mdiFingerprint,
2627
mdiFlag,
@@ -216,6 +217,16 @@ export const useChallengeTagLabelMap = () => {
216217
colors: theme.colors['green'],
217218
},
218219
],
220+
[
221+
ChallengeTag.Abstract,
222+
{
223+
desrc: t('challenge.tag.abstract'),
224+
icon: mdiEmoticonLolOutline,
225+
name: ChallengeTag.Abstract,
226+
color: 'yellow',
227+
colors: theme.colors['yellow'],
228+
},
229+
],
219230
])
220231
}
221232

src/GZCTF/Controllers/AccountController.cs

+7-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public class AccountController(
2828
IOptionsSnapshot<AccountPolicy> accountPolicy,
2929
IOptionsSnapshot<GlobalConfig> globalConfig,
3030
UserManager<UserInfo> userManager,
31+
ITeamRepository teamRepository,
3132
SignInManager<UserInfo> signInManager,
3233
ILogger<AccountController> logger,
3334
IStringLocalizer<Program> localizer) : ControllerBase
@@ -58,7 +59,7 @@ public async Task<IActionResult> Register([FromBody] RegisterModel model, Cancel
5859
return BadRequest(new RequestResponse(localizer[nameof(Resources.Program.Account_AvailableEmailDomain),
5960
accountPolicy.Value.EmailDomainList]));
6061

61-
var user = new UserInfo { UserName = model.UserName, Email = model.Email, Role = Role.User };
62+
var user = new UserInfo { UserName = model.UserName, Email = model.Email, StdNumber = model.StdNumber, Role = Role.User };
6263

6364
user.UpdateByHttpContext(HttpContext);
6465

@@ -76,7 +77,12 @@ public async Task<IActionResult> Register([FromBody] RegisterModel model, Cancel
7677

7778
user = current;
7879
}
80+
var team = await teamRepository.CreateTeam(new(){ Name = model.UserName }, user);
7981

82+
if (team is null)
83+
{
84+
logger.Log("用户个人队伍创建失败", user, TaskStatus.Failed);
85+
}
8086
if (accountPolicy.Value.ActiveOnRegister)
8187
{
8288
user.EmailConfirmed = true;

src/GZCTF/Models/Request/Account/RegisterModel.cs

+9
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,15 @@ public class RegisterModel : ModelWithCaptcha
2626
ErrorMessageResourceType = typeof(Resources.Program))]
2727
public string Password { get; set; } = string.Empty;
2828

29+
/// <summary>
30+
/// 学号
31+
/// </summary>
32+
[Required(ErrorMessageResourceName = nameof(Resources.Program.Model_StdNumberRequired),
33+
ErrorMessageResourceType = typeof(Resources.Program))]
34+
[RegularExpression(@"^20\d{8}$", ErrorMessageResourceName = nameof(Resources.Program.Model_MalformedStdNumber),
35+
ErrorMessageResourceType = typeof(Resources.Program))]
36+
public string StdNumber { get; set; } = string.Empty;
37+
2938
/// <summary>
3039
/// 邮箱
3140
/// </summary>

src/GZCTF/Resources/Program.resx

+6
Original file line numberDiff line numberDiff line change
@@ -840,6 +840,12 @@
840840
<data name="Model_UserNameTooShort" xml:space="preserve">
841841
<value>用户名过短</value>
842842
</data>
843+
<data name="Model_StdNumberRequired" xml:space="preserve">
844+
<value>学号是必需的</value>
845+
</data>
846+
<data name="Model_MalformedStdNumber" xml:space="preserve">
847+
<value>学号格式错误</value>
848+
</data>
843849
<data name="Model_ValidationFailed" xml:space="preserve">
844850
<value>校验失败,请检查输入。</value>
845851
</data>

src/GZCTF/Services/Container/Manager/DockerManager.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,8 @@ CreateContainerParameters GetCreateContainerParameters(ContainerConfig config) =
210210
},
211211
Name = DockerMetadata.GetName(config),
212212
Env = config.Flag is null
213-
? [$"GZCTF_TEAM_ID={config.TeamId}"]
214-
: [$"GZCTF_FLAG={config.Flag}", $"GZCTF_TEAM_ID={config.TeamId}"],
213+
? [$"TEAM_ID={config.TeamId}"]
214+
: [$"FLAG={config.Flag}", $"TEAM_ID={config.TeamId}"],
215215
HostConfig = new()
216216
{
217217
Memory = config.MemoryLimit * 1024 * 1024,

src/GZCTF/Services/Container/Manager/KubernetesManager.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,11 @@ authSecretName is null
7777
ImagePullPolicy = "Always",
7878
Env =
7979
config.Flag is null
80-
? [new V1EnvVar("GZCTF_TEAM_ID", config.TeamId)]
80+
? [new V1EnvVar("TEAM_ID", config.TeamId)]
8181
:
8282
[
83-
new V1EnvVar("GZCTF_FLAG", config.Flag),
84-
new V1EnvVar("GZCTF_TEAM_ID", config.TeamId)
83+
new V1EnvVar("FLAG", config.Flag),
84+
new V1EnvVar("TEAM_ID", config.TeamId)
8585
],
8686
Ports = [new V1ContainerPort(config.ExposedPort)],
8787
Resources = new V1ResourceRequirements

src/GZCTF/Services/Container/Manager/SwarmManager.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,8 @@ ServiceCreateParameters GetServiceCreateParameters(ContainerConfig config) =>
177177
Image = config.Image,
178178
Env =
179179
config.Flag is null
180-
? [$"GZCTF_TEAM_ID={config.TeamId}"]
181-
: [$"GZCTF_FLAG={config.Flag}", $"GZCTF_TEAM_ID={config.TeamId}"],
180+
? [$"TEAM_ID={config.TeamId}"]
181+
: [$"FLAG={config.Flag}", $"GTEAM_ID={config.TeamId}"],
182182
},
183183
Resources = new()
184184
{

src/GZCTF/Utils/Enums.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,8 @@ public enum ChallengeTag : byte
345345
Hardware = 7,
346346
Mobile = 8,
347347
PPC = 9,
348-
AI = 10
348+
AI = 10,
349+
Abstract = 11,
349350
}
350351

351352
/// <summary>

0 commit comments

Comments
 (0)