surrealdb/api/opt/auth.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
//! Authentication types
use serde::Deserialize;
use serde::Serialize;
use std::fmt;
/// A signup action
#[derive(Debug)]
pub struct Signup;
/// A signin action
#[derive(Debug)]
pub struct Signin;
/// Credentials for authenticating with the server
pub trait Credentials<Action, Response>: Serialize {}
/// Credentials for the root user
#[derive(Debug, Clone, Copy, Serialize)]
pub struct Root<'a> {
/// The username of the root user
#[serde(rename = "user")]
pub username: &'a str,
/// The password of the root user
#[serde(rename = "pass")]
pub password: &'a str,
}
impl Credentials<Signin, Jwt> for Root<'_> {}
/// Credentials for the namespace user
#[derive(Debug, Clone, Copy, Serialize)]
pub struct Namespace<'a> {
/// The namespace the user has access to
#[serde(rename = "ns")]
pub namespace: &'a str,
/// The username of the namespace user
#[serde(rename = "user")]
pub username: &'a str,
/// The password of the namespace user
#[serde(rename = "pass")]
pub password: &'a str,
}
impl Credentials<Signin, Jwt> for Namespace<'_> {}
/// Credentials for the database user
#[derive(Debug, Clone, Copy, Serialize)]
pub struct Database<'a> {
/// The namespace the user has access to
#[serde(rename = "ns")]
pub namespace: &'a str,
/// The database the user has access to
#[serde(rename = "db")]
pub database: &'a str,
/// The username of the database user
#[serde(rename = "user")]
pub username: &'a str,
/// The password of the database user
#[serde(rename = "pass")]
pub password: &'a str,
}
impl Credentials<Signin, Jwt> for Database<'_> {}
/// Credentials for the scope user
#[derive(Debug, Serialize)]
pub struct Scope<'a, P> {
/// The namespace the user has access to
#[serde(rename = "ns")]
pub namespace: &'a str,
/// The database the user has access to
#[serde(rename = "db")]
pub database: &'a str,
/// The scope to use for signin and signup
#[serde(rename = "sc")]
pub scope: &'a str,
/// The additional params to use
#[serde(flatten)]
pub params: P,
}
impl<T, P> Credentials<T, Jwt> for Scope<'_, P> where P: Serialize {}
/// A JSON Web Token for authenticating with the server.
///
/// This struct represents a JSON Web Token (JWT) that can be used for authentication purposes.
/// It is important to note that this implementation provide some security measures to
/// protect the token:
/// * the debug implementation just prints `Jwt(REDACTED)`,
/// * `Display` is not implemented so you can't call `.to_string()` on it
///
/// You can still have access to the token string using either
/// [`as_insecure_token`](Jwt::as_insecure_token) or [`into_insecure_token`](Jwt::into_insecure_token) functions.
/// However, you should take care to ensure that only authorized users have access to the JWT.
/// For example:
/// * it can be stored in a secure cookie,
/// * stored in a database with restricted access,
/// * or encrypted in conjunction with other encryption mechanisms.
#[derive(Clone, Serialize, Deserialize)]
pub struct Jwt(pub(crate) String);
impl Jwt {
/// Returns the underlying token string.
///
/// ⚠️: It is important to note that the token should be handled securely and protected from unauthorized access.
pub fn as_insecure_token(&self) -> &str {
&self.0
}
/// Returns the underlying token string.
///
/// ⚠️: It is important to note that the token should be handled securely and protected from unauthorized access.
pub fn into_insecure_token(self) -> String {
self.0
}
}
impl From<String> for Jwt {
fn from(jwt: String) -> Self {
Jwt(jwt)
}
}
impl<'a> From<&'a String> for Jwt {
fn from(jwt: &'a String) -> Self {
Jwt(jwt.to_owned())
}
}
impl<'a> From<&'a str> for Jwt {
fn from(jwt: &'a str) -> Self {
Jwt(jwt.to_owned())
}
}
impl fmt::Debug for Jwt {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Jwt(REDACTED)")
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn as_insecure_token() {
let jwt = Jwt("super-long-jwt".to_owned());
assert_eq!(jwt.as_insecure_token(), "super-long-jwt");
}
#[test]
fn into_insecure_token() {
let jwt = Jwt("super-long-jwt".to_owned());
assert_eq!(jwt.into_insecure_token(), "super-long-jwt");
}
}