Skip to content

Commit 4e544b0

Browse files
committed
Add a way to ignore verification for unsupported games
This also fixes an issue where validation would not even trigger if a YAML name contained one of the auto incremented fields.
1 parent ffaa4fe commit 4e544b0

File tree

13 files changed

+116
-34
lines changed

13 files changed

+116
-34
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- This file should undo anything in `up.sql`
2+
ALTER TABLE rooms DROP COLUMN allow_unsupported;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- Your SQL goes here
2+
ALTER TABLE rooms ADD COLUMN allow_unsupported BOOLEAN NOT NULL DEFAULT FALSE;

src/db.rs

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ pub struct NewRoom<'a> {
2323
pub author_id: Option<i64>,
2424
pub private: bool,
2525
pub yaml_validation: bool,
26+
pub allow_unsupported: bool,
2627
}
2728

2829
#[derive(Insertable)]
@@ -46,6 +47,7 @@ pub struct Room {
4647
pub author_id: i64,
4748
pub private: bool,
4849
pub yaml_validation: bool,
50+
pub allow_unsupported: bool,
4951
}
5052

5153
impl Room {

src/main.rs

+2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ struct TplContext<'a> {
3232
cur_module: &'a str,
3333
user_id: Option<i64>,
3434
err_msg: Vec<String>,
35+
warning_msg: Vec<String>,
3536
css_version: &'a str,
3637
}
3738

@@ -43,6 +44,7 @@ impl<'a> TplContext<'a> {
4344
is_logged_in: session.is_logged_in,
4445
user_id: session.user_id,
4546
err_msg: session.err_msg.drain(..).collect(),
47+
warning_msg: session.warning_msg.drain(..).collect(),
4648
css_version: CSS_VERSION,
4749
};
4850

src/schema.rs

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ diesel::table! {
1717
author_id -> BigInt,
1818
private -> Bool,
1919
yaml_validation -> Bool,
20+
allow_unsupported -> Bool,
2021
}
2122
}
2223

src/views/auth.rs

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub struct Session {
1919
pub is_admin: bool,
2020
pub is_logged_in: bool,
2121
pub err_msg: Vec<String>,
22+
pub warning_msg: Vec<String>,
2223
pub user_id: Option<i64>,
2324
pub redirect_on_login: Option<String>,
2425
}
@@ -36,6 +37,7 @@ impl Into<Session> for SessionRecovery {
3637
is_admin: self.is_admin,
3738
is_logged_in: self.is_logged_in,
3839
err_msg: vec![],
40+
warning_msg: vec![],
3941
user_id: self.user_id,
4042
redirect_on_login: None,
4143
}

src/views/mod.rs

+29-14
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,8 @@ async fn upload_yaml(
114114
redirect_to: &RedirectTo,
115115
uuid: Uuid,
116116
yaml: Form<&[u8]>,
117-
session: LoggedInSession,
117+
mut session: LoggedInSession,
118+
cookies: &CookieJar<'_>,
118119
ctx: &State<Context>,
119120
) -> Result<Redirect> {
120121
redirect_to.set(&format!("/room/{}", uuid));
@@ -138,7 +139,9 @@ async fn upload_yaml(
138139
anyhow::bail!("Invalid yaml file. Syntax error.")
139140
};
140141
let Ok(parsed) = serde_yaml::from_str(&doc) else {
141-
anyhow::bail!("Invalid yaml file. This does not look like an archipelago game YAML.")
142+
anyhow::bail!(
143+
"Invalid yaml file. This does not look like an archipelago game YAML."
144+
)
142145
};
143146
Ok((doc, parsed))
144147
})
@@ -156,14 +159,12 @@ async fn upload_yaml(
156159

157160
for (document, parsed) in documents.iter() {
158161
let mut player_name = parsed.name.clone();
159-
player_name.truncate(16);
160162

161-
if player_name.contains("{NUMBER}") || player_name.contains("{number}") {
162-
continue;
163-
}
164-
if player_name.contains("{PLAYER}") || player_name.contains("{player}") {
165-
continue;
166-
}
163+
let ignore_dupe = player_name.contains("{NUMBER}")
164+
|| player_name.contains("{number}")
165+
|| player_name.contains("{PLAYER}")
166+
|| player_name.contains("{player}");
167+
player_name.truncate(16);
167168

168169
if player_name == "meta" || player_name == "Archipelago" {
169170
return Err(Error(anyhow::anyhow!(format!(
@@ -172,14 +173,27 @@ async fn upload_yaml(
172173
))));
173174
}
174175

175-
if players_in_room.contains(&player_name) {
176+
if !ignore_dupe && players_in_room.contains(&player_name) {
176177
return Err(Error(anyhow::anyhow!(
177178
"Adding this yaml would duplicate a player name"
178179
)));
179180
}
180181

181182
if room.yaml_validation {
182-
validate_yaml(document, ctx).await?;
183+
let unsupported_games = validate_yaml(document, ctx).await?;
184+
if room.allow_unsupported {
185+
session.0.warning_msg.push(format!(
186+
"Uploaded a YAML with unsupported games: {}. Couldn't verify it.",
187+
unsupported_games.iter().join("; ")
188+
));
189+
session.0.save(cookies)?;
190+
} else {
191+
return Err(anyhow::anyhow!(format!(
192+
"Your YAML contains the following unsupported games: {}. Can't upload.",
193+
unsupported_games.iter().join("; ")
194+
))
195+
.into());
196+
}
183197
}
184198

185199
players_in_room.insert(player_name);
@@ -192,14 +206,15 @@ async fn upload_yaml(
192206
Ok(Redirect::to(uri!(room(uuid))))
193207
}
194208

195-
async fn validate_yaml(yaml: &str, ctx: &State<Context>) -> Result<()> {
209+
async fn validate_yaml(yaml: &str, ctx: &State<Context>) -> Result<Vec<String>> {
196210
if ctx.yaml_validator_url.is_none() {
197-
return Ok(());
211+
return Ok(vec![]);
198212
}
199213

200214
#[derive(serde::Deserialize)]
201215
struct ValidationResponse {
202216
error: Option<String>,
217+
unsupported: Vec<String>,
203218
}
204219

205220
let client = reqwest::Client::new();
@@ -218,7 +233,7 @@ async fn validate_yaml(yaml: &str, ctx: &State<Context>) -> Result<()> {
218233
return Err(anyhow::anyhow!(error).into());
219234
}
220235

221-
Ok(())
236+
Ok(response.unsupported)
222237
}
223238

224239
#[get("/room/<room_id>/delete/<yaml_id>")]

src/views/room_manager.rs

+3
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ struct CreateRoomForm<'a> {
3232
room_url: &'a str,
3333
private: bool,
3434
yaml_validation: bool,
35+
allow_unsupported: bool,
3536
}
3637

3738
#[derive(Template)]
@@ -116,6 +117,7 @@ fn create_room_submit(
116117
author_id: Some(author_id),
117118
private: room_form.private,
118119
yaml_validation: room_form.yaml_validation,
120+
allow_unsupported: room_form.allow_unsupported,
119121
};
120122
let new_room = db::create_room(&new_room, ctx)?;
121123

@@ -174,6 +176,7 @@ fn edit_room_submit(
174176
author_id: None, // (Skips updating that field)
175177
private: room_form.private,
176178
yaml_validation: room_form.yaml_validation,
179+
allow_unsupported: room_form.allow_unsupported,
177180
};
178181

179182
crate::db::update_room(&new_room, ctx)?;

static/css/base.css

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

static/css/base.css.map

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

static/sass/base.sass

+16-11
Original file line numberDiff line numberDiff line change
@@ -167,13 +167,14 @@ form
167167
color: white
168168
text-align: center
169169

170+
formset
171+
input + label
172+
margin-left: 2em
173+
width: calc(100% - 2em) !important
170174

171-
fieldset
172-
padding: 0.5em
173-
margin: 1em 0em
174-
border: none
175-
border: 3px solid hsla(0,0%,0%,0.4)
176-
box-shadow: inset 0 0 0 1px hsla(0,0%,100%,0.075), 0 0 0 1px hsla(0,0%,100%,0.075)
175+
&:first-of-type
176+
margin-left: 0em
177+
width: 100% !important
177178

178179

179180
legend
@@ -557,8 +558,6 @@ h6
557558
background: linear-gradient(hsl(135, 0%, 34%), hsl(135, 0%, 26%) )
558559

559560

560-
/* == ERROR BOX == */
561-
562561
.error
563562
background-color: hsl(0,75%,50%) !important
564563
background-image: url("../images/background.png")
@@ -569,9 +568,15 @@ h6
569568
text-shadow: 1px 1px black !important
570569
margin: 1em 0
571570

572-
573-
574-
/* == Confirmation box == */
571+
.warning
572+
background-color: hsl(30,95%,40%) !important
573+
background-image: url("../images/background.png")
574+
padding: 0.5em
575+
box-shadow: inset 0 0 0 1px hsla(30,0%,100%,0.2), 0 0 0 1px hsl(3,75%,20%)
576+
font-weight: bold !important
577+
color: hsl(0,100%,95%) !important
578+
text-shadow: 1px 1px black !important
579+
margin: 1em 0
575580

576581
.confirm
577582
background-color: hsl(125,50%,40%) !important

templates/base.html

+3
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@
4242
{% for error in base.err_msg %}
4343
<p class="error">{{ error }}</p>
4444
{% endfor %}
45+
{% for warning in base.warning_msg %}
46+
<p class="warning">{{ warning }}</p>
47+
{% endfor %}
4548
{% block messages %}{% endblock messages %}
4649
</div>
4750
{% block main %}{% endblock main %}

templates/room_manager/create_room.html

+52-7
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,23 @@
4646
{%- endmatch -%}
4747
<label for="private">Private room</label>
4848

49-
{% match room %}
50-
{% when Some with (room) %}
51-
<input type="checkbox" name="yaml_validation" id="yaml_validation" {% if room.yaml_validation %} checked {% endif %}/>
52-
{%- when None -%}
53-
<input type="checkbox" name="yaml_validation" id="yaml_validation" checked/>
54-
{%- endmatch -%}
55-
<label for="yaml_validation">Validate uploaded YAML files</label>
49+
<formset>
50+
{% match room %}
51+
{% when Some with (room) %}
52+
<input type="checkbox" name="yaml_validation" id="yaml_validation" {% if room.yaml_validation %} checked {% endif %}/>
53+
{%- when None -%}
54+
<input type="checkbox" name="yaml_validation" id="yaml_validation" checked/>
55+
{%- endmatch -%}
56+
<label for="yaml_validation">Validate uploaded YAML files</label>
57+
58+
{% match room %}
59+
{% when Some with (room) %}
60+
<input type="checkbox" name="allow_unsupported" id="allow_unsupported" {% if room.allow_unsupported%} checked {% endif %}/>
61+
{%- when None -%}
62+
<input type="checkbox" name="allow_unsupported" id="allow_unsupported"/>
63+
{%- endmatch -%}
64+
<label for="allow_unsupported">Allow bypassing validation for unsupported games</label>
65+
</formset>
5666

5767
{% match room %}
5868
{% when Some with (room) %}
@@ -97,5 +107,40 @@
97107
closeDate.setSeconds(0)
98108
closeDateEl.value = dateToISOLikeButLocal(closeDate);
99109
{%- endif %}
110+
111+
function updateFormset(formset) {
112+
const inputs = Array.from(formset.getElementsByTagName("input"));
113+
if (!inputs) {
114+
return;
115+
}
116+
117+
const first_input = inputs[0];
118+
if (first_input.type != "checkbox") {
119+
return;
120+
}
121+
122+
inputs.splice(0, 1);
123+
const display = first_input.checked ? "inline-block" : "none";
124+
for (const input of inputs) {
125+
if (input.type != "checkbox") {
126+
input.style.display = display;
127+
}
128+
129+
for (const label of input.labels) {
130+
label.style.display = display;
131+
}
132+
}
133+
134+
return first_input;
135+
}
136+
137+
const formsets = document.getElementsByTagName("formset");
138+
for (const formset of formsets) {
139+
const first_input = updateFormset(formset);
140+
if (first_input) {
141+
first_input.onchange = () => updateFormset(formset);
142+
}
143+
}
144+
100145
</script>
101146
{% endblock %}

0 commit comments

Comments
 (0)