Skip to content

Commit

Permalink
feat(challenge)!: split ctfd_challenge in two separate resources
Browse files Browse the repository at this point in the history
Closes #131
Closes #132
  • Loading branch information
pandatix committed Jan 16, 2025
1 parent 5563586 commit 72c2353
Show file tree
Hide file tree
Showing 17 changed files with 1,033 additions and 360 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ provider "ctfd" {

We recommend setting the environment variable `CTFD_API_KEY` to enable the provider to communicate with your CTFd instance.

Then, you could use a `ctfd_challenge` resource to setup your CTFd challenge, with for instance the following configuration.
Then, you could use a `ctfd_challenge_standard` resource to setup your CTFd challenges, with for instance the following configuration.
```hcl
resource "ctfd_challenge" "my_challenge" {
name = "My Challenge"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "ctfd_challenges Data Source - terraform-provider-ctfd"
page_title: "ctfd_challenges_dynamic Data Source - terraform-provider-ctfd"
subcategory: ""
description: |-
---

# ctfd_challenges (Data Source)
# ctfd_challenges_dynamic (Data Source)



Expand All @@ -28,19 +28,15 @@ Read-Only:
- `attribution` (String) Attribution to the creator(s) of the challenge.
- `category` (String) Category of the challenge that CTFd groups by on the web UI.
- `connection_info` (String) Connection Information to connect to the challenge instance, useful for pwn or web pentest.
- `decay` (Number)
- `description` (String) Description of the challenge, consider using multiline descriptions for better style.
- `function` (String) Decay function to define how the challenge value evolve through solves, either linear or logarithmic.
- `id` (String) Identifier of the challenge.
- `max_attempts` (Number) Maximum amount of attempts before being unable to flag the challenge.
- `minimum` (Number)
- `name` (String) Name of the challenge, displayed as it.
- `next` (Number) Suggestion for the end-user as next challenge to work on.
- `requirements` (Attributes) List of required challenges that needs to get flagged before this one being accessible. Useful for skill-trees-like strategy CTF. (see [below for nested schema](#nestedatt--challenges--requirements))
- `state` (String) State of the challenge, either hidden or visible.
- `tags` (List of String) List of challenge tags that will be displayed to the end-user. You could use them to give some quick insights of what a challenge involves.
- `topics` (List of String) List of challenge topics that are displayed to the administrators for maintenance and planification.
- `type` (String) Type of the challenge defining its layout, either standard or dynamic.
- `value` (Number)

<a id="nestedatt--challenges--requirements"></a>
Expand Down
47 changes: 47 additions & 0 deletions docs/data-sources/challenges_standard.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "ctfd_challenges_standard Data Source - terraform-provider-ctfd"
subcategory: ""
description: |-
---

# ctfd_challenges_standard (Data Source)





<!-- schema generated by tfplugindocs -->
## Schema

### Read-Only

- `challenges` (Attributes List) (see [below for nested schema](#nestedatt--challenges))
- `id` (String) The ID of this resource.

<a id="nestedatt--challenges"></a>
### Nested Schema for `challenges`

Read-Only:

- `category` (String) Category of the challenge that CTFd groups by on the web UI.
- `connection_info` (String) Connection Information to connect to the challenge instance, useful for pwn or web pentest.
- `description` (String) Description of the challenge, consider using multiline descriptions for better style.
- `id` (String) Identifier of the challenge.
- `max_attempts` (Number) Maximum amount of attempts before being unable to flag the challenge.
- `name` (String) Name of the challenge, displayed as it.
- `next` (Number) Suggestion for the end-user as next challenge to work on.
- `requirements` (Attributes) List of required challenges that needs to get flagged before this one being accessible. Useful for skill-trees-like strategy CTF. (see [below for nested schema](#nestedatt--challenges--requirements))
- `state` (String) State of the challenge, either hidden or visible.
- `tags` (List of String) List of challenge tags that will be displayed to the end-user. You could use them to give some quick insights of what a challenge involves.
- `topics` (List of String) List of challenge topics that are displayed to the administrators for maintenance and planification.
- `value` (Number)

<a id="nestedatt--challenges--requirements"></a>
### Nested Schema for `challenges.requirements`

Read-Only:

- `behavior` (String) Behavior if not unlocked, either hidden or anonymized.
- `prerequisites` (List of String) List of the challenges ID.
Original file line number Diff line number Diff line change
@@ -1,89 +1,43 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "ctfd_challenge Resource - terraform-provider-ctfd"
page_title: "ctfd_challenge_dynamic Resource - terraform-provider-ctfd"
subcategory: ""
description: |-
CTFd is built around the Challenge resource, which contains all the attributes to define a part of the Capture The Flag event.
This provider builds a cleaner API on top of CTFd's one to improve its adoption and lifecycle management.
This implementation has support of a more dynamic behavior for its scoring through time/solves thus is different from a standard challenge.
---

# ctfd_challenge (Resource)
# ctfd_challenge_dynamic (Resource)

CTFd is built around the Challenge resource, which contains all the attributes to define a part of the Capture The Flag event.

This provider builds a cleaner API on top of CTFd's one to improve its adoption and lifecycle management.
This implementation has support of a more dynamic behavior for its scoring through time/solves thus is different from a standard challenge.

## Example Usage

```terraform
resource "ctfd_challenge" "http" {
name = "My Challenge"
category = "misc"
description = "..."
value = 500
decay = 100
minimum = 50
state = "visible"
function = "logarithmic"
topics = [
"Misc"
]
tags = [
"misc",
"basic"
]
}
resource "ctfd_flag" "http_flag" {
challenge_id = ctfd_challenge.http.id
content = "CTF{some_flag}"
}
resource "ctfd_hint" "http_hint_1" {
challenge_id = ctfd_challenge.http.id
content = "Some super-helpful hint"
cost = 50
}
resource "ctfd_hint" "http_hint_2" {
challenge_id = ctfd_challenge.http.id
content = "Even more helpful hint !"
cost = 50
requirements = [ctfd_hint.http_hint_1.id]
}
resource "ctfd_file" "http_file" {
challenge_id = ctfd_challenge.http.id
name = "image.png"
contentb64 = filebase64(".../image.png")
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `category` (String) Category of the challenge that CTFd groups by on the web UI.
- `decay` (Number) The decay defines from each number of solves does the decay function triggers until reaching minimum. This function is defined by CTFd and could be configured through `.function`.
- `description` (String) Description of the challenge, consider using multiline descriptions for better style.
- `minimum` (Number) The minimum points for a dynamic-score challenge to reach with the decay function. Once there, no solve could have more value.
- `name` (String) Name of the challenge, displayed as it.
- `value` (Number) The value (points) of the challenge once solved. Internally, the provider will handle what target is legitimate depending on the `.type` value, i.e. either `value` for "standard" or `initial` for "dynamic".
- `value` (Number) The value (points) of the challenge once solved. It is mapped to `initial` under the hood, but displayed as `value` for consistency with the standard challenge.

### Optional

- `attribution` (String) Attribution to the creator(s) of the challenge.
- `connection_info` (String) Connection Information to connect to the challenge instance, useful for pwn, web and infrastructure pentests.
- `decay` (Number) The decay defines from each number of solves does the decay function triggers until reaching minimum. This function is defined by CTFd and could be configured through `.function`.
- `function` (String) Decay function to define how the challenge value evolve through solves, either linear or logarithmic.
- `max_attempts` (Number) Maximum amount of attempts before being unable to flag the challenge.
- `minimum` (Number) The minimum points for a dynamic-score challenge to reach with the decay function. Once there, no solve could have more value.
- `next` (Number) Suggestion for the end-user as next challenge to work on.
- `requirements` (Attributes) List of required challenges that needs to get flagged before this one being accessible. Useful for skill-trees-like strategy CTF. (see [below for nested schema](#nestedatt--requirements))
- `state` (String) State of the challenge, either hidden or visible.
- `tags` (List of String) List of challenge tags that will be displayed to the end-user. You could use them to give some quick insights of what a challenge involves.
- `topics` (List of String) List of challenge topics that are displayed to the administrators for maintenance and planification.
- `type` (String) Type of the challenge defining its layout/behavior, either standard or dynamic (default).

### Read-Only

Expand Down
48 changes: 48 additions & 0 deletions docs/resources/challenge_standard.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "ctfd_challenge_standard Resource - terraform-provider-ctfd"
subcategory: ""
description: |-
CTFd is built around the Challenge resource, which contains all the attributes to define a part of the Capture The Flag event.
It is the first historic implementation of its kind, with basic functionalities.
---

# ctfd_challenge_standard (Resource)

CTFd is built around the Challenge resource, which contains all the attributes to define a part of the Capture The Flag event.

It is the first historic implementation of its kind, with basic functionalities.



<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `category` (String) Category of the challenge that CTFd groups by on the web UI.
- `description` (String) Description of the challenge, consider using multiline descriptions for better style.
- `name` (String) Name of the challenge, displayed as it.
- `value` (Number) The value (points) of the challenge once solved.

### Optional

- `connection_info` (String) Connection Information to connect to the challenge instance, useful for pwn, web and infrastructure pentests.
- `max_attempts` (Number) Maximum amount of attempts before being unable to flag the challenge.
- `next` (Number) Suggestion for the end-user as next challenge to work on.
- `requirements` (Attributes) List of required challenges that needs to get flagged before this one being accessible. Useful for skill-trees-like strategy CTF. (see [below for nested schema](#nestedatt--requirements))
- `state` (String) State of the challenge, either hidden or visible.
- `tags` (List of String) List of challenge tags that will be displayed to the end-user. You could use them to give some quick insights of what a challenge involves.
- `topics` (List of String) List of challenge topics that are displayed to the administrators for maintenance and planification.

### Read-Only

- `id` (String) Identifier of the challenge.

<a id="nestedatt--requirements"></a>
### Nested Schema for `requirements`

Optional:

- `behavior` (String) Behavior if not unlocked, either hidden or anonymized.
- `prerequisites` (List of String) List of the challenges ID.
39 changes: 39 additions & 0 deletions provider/challenge_common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package provider

import (
"github.com/ctfer-io/terraform-provider-ctfd/provider/utils"
"github.com/hashicorp/terraform-plugin-framework/types"
)

var (
BehaviorHidden = types.StringValue("hidden")
BehaviorAnonymized = types.StringValue("anonymized")

FunctionLinear = types.StringValue("linear")
FunctionLogarithmic = types.StringValue("logarithmic")
)

type RequirementsSubresourceModel struct {
Behavior types.String `tfsdk:"behavior"`
Prerequisites []types.String `tfsdk:"prerequisites"`
}

func GetAnon(str types.String) *bool {
switch {
case str.Equal(BehaviorHidden):
return nil
case str.Equal(BehaviorAnonymized):
return utils.Ptr(true)
}
panic("invalid anonymization value: " + str.ValueString())
}

func FromAnon(b *bool) types.String {
if b == nil {
return BehaviorHidden
}
if *b {
return BehaviorAnonymized
}
panic("invalid anonymization value, got boolean false")
}
Loading

0 comments on commit 72c2353

Please sign in to comment.