You've already forked authentication-service
mirror of
https://github.com/matrix-org/matrix-authentication-service.git
synced 2025-11-21 23:00:50 +03:00
Link between login & register + "back to client" link
This commit is contained in:
@@ -14,10 +14,16 @@
|
||||
|
||||
//! Additional functions, tests and filters used in templates
|
||||
|
||||
use std::{collections::HashMap, str::FromStr};
|
||||
|
||||
use tera::{helpers::tests::number_args_allowed, Tera, Value};
|
||||
use url::Url;
|
||||
|
||||
pub fn register(tera: &mut Tera) {
|
||||
tera.register_tester("empty", self::tester_empty);
|
||||
tera.register_function("add_params_to_uri", function_add_params_to_uri);
|
||||
tera.register_function("merge", function_merge);
|
||||
tera.register_function("dict", function_dict);
|
||||
}
|
||||
|
||||
fn tester_empty(value: Option<&Value>, params: &[Value]) -> Result<bool, tera::Error> {
|
||||
@@ -28,3 +34,84 @@ fn tester_empty(value: Option<&Value>, params: &[Value]) -> Result<bool, tera::E
|
||||
Some(_) => Ok(false),
|
||||
}
|
||||
}
|
||||
|
||||
enum ParamsWhere {
|
||||
Fragment,
|
||||
Query,
|
||||
}
|
||||
|
||||
fn function_add_params_to_uri(params: &HashMap<String, Value>) -> Result<Value, tera::Error> {
|
||||
use ParamsWhere::{Fragment, Query};
|
||||
|
||||
// First, get the `uri`, `mode` and `params` parameters
|
||||
let uri = params
|
||||
.get("uri")
|
||||
.and_then(Value::as_str)
|
||||
.ok_or_else(|| tera::Error::msg("Invalid parameter `uri`"))?;
|
||||
let uri = Url::from_str(uri).map_err(|e| tera::Error::chain(uri, e))?;
|
||||
let mode = params
|
||||
.get("mode")
|
||||
.and_then(Value::as_str)
|
||||
.ok_or_else(|| tera::Error::msg("Invalid parameter `mode`"))?;
|
||||
let mode = match mode {
|
||||
"fragment" => Fragment,
|
||||
"query" => Query,
|
||||
_ => return Err(tera::Error::msg("Invalid mode")),
|
||||
};
|
||||
let params = params
|
||||
.get("params")
|
||||
.and_then(Value::as_object)
|
||||
.ok_or_else(|| tera::Error::msg("Invalid parameter `params`"))?;
|
||||
|
||||
// Get the relevant part of the URI and parse for existing parameters
|
||||
let existing = match mode {
|
||||
Fragment => uri.fragment(),
|
||||
Query => uri.query(),
|
||||
};
|
||||
let existing: HashMap<String, Value> = existing
|
||||
.map(serde_urlencoded::from_str)
|
||||
.transpose()
|
||||
.map_err(|e| tera::Error::chain(e, "Could not parse existing `uri` parameters"))?
|
||||
.unwrap_or_default();
|
||||
|
||||
// Merge the exising and the additional parameters together
|
||||
let params: HashMap<&String, &Value> = params
|
||||
.iter()
|
||||
// Filter out the `uri` and `mode` params
|
||||
.filter(|(k, _v)| k != &"uri" && k != &"mode")
|
||||
.chain(existing.iter())
|
||||
.collect();
|
||||
|
||||
// Transform them back to urlencoded
|
||||
let params = serde_urlencoded::to_string(params)
|
||||
.map_err(|e| tera::Error::chain(e, "Could not serialize back parameters"))?;
|
||||
|
||||
let uri = {
|
||||
let mut uri = uri;
|
||||
match mode {
|
||||
Fragment => uri.set_fragment(Some(¶ms)),
|
||||
Query => uri.set_query(Some(¶ms)),
|
||||
};
|
||||
uri
|
||||
};
|
||||
|
||||
Ok(Value::String(uri.to_string()))
|
||||
}
|
||||
|
||||
fn function_merge(params: &HashMap<String, Value>) -> Result<Value, tera::Error> {
|
||||
let mut ret = serde_json::Map::new();
|
||||
for (k, v) in params {
|
||||
let v = v
|
||||
.as_object()
|
||||
.ok_or_else(|| tera::Error::msg(format!("Parameter {:?} should be an object", k)))?;
|
||||
ret.extend(v.clone());
|
||||
}
|
||||
|
||||
Ok(Value::Object(ret))
|
||||
}
|
||||
|
||||
#[allow(clippy::unnecessary_wraps)]
|
||||
fn function_dict(params: &HashMap<String, Value>) -> Result<Value, tera::Error> {
|
||||
let ret = params.clone().into_iter().collect();
|
||||
Ok(Value::Object(ret))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user