Merged trivial modules
This commit is contained in:
parent
2873f38e04
commit
822f3ed073
4 changed files with 255 additions and 260 deletions
263
src/app/user.rs
263
src/app/user.rs
|
@ -9,13 +9,29 @@ use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
use crate::app::settings::AuthSecret;
|
use crate::app::settings::AuthSecret;
|
||||||
use crate::db::{users, DB};
|
use crate::db::{users, DB};
|
||||||
|
|
||||||
mod error;
|
#[derive(thiserror::Error, Debug, PartialEq, Eq)]
|
||||||
mod preferences;
|
pub enum Error {
|
||||||
#[cfg(test)]
|
#[error("Cannot use empty username")]
|
||||||
mod test;
|
EmptyUsername,
|
||||||
|
#[error("Cannot use empty password")]
|
||||||
|
EmptyPassword,
|
||||||
|
#[error("Username does not exist")]
|
||||||
|
IncorrectUsername,
|
||||||
|
#[error("Password does not match username")]
|
||||||
|
IncorrectPassword,
|
||||||
|
#[error("Invalid auth token")]
|
||||||
|
InvalidAuthToken,
|
||||||
|
#[error("Incorrect authorization scope")]
|
||||||
|
IncorrectAuthorizationScope,
|
||||||
|
#[error("Unspecified")]
|
||||||
|
Unspecified,
|
||||||
|
}
|
||||||
|
|
||||||
pub use error::*;
|
impl From<anyhow::Error> for Error {
|
||||||
pub use preferences::*;
|
fn from(_: anyhow::Error) -> Self {
|
||||||
|
Error::Unspecified
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Insertable, Queryable)]
|
#[derive(Debug, Insertable, Queryable)]
|
||||||
#[diesel(table_name = users)]
|
#[diesel(table_name = users)]
|
||||||
|
@ -53,10 +69,16 @@ pub struct Authorization {
|
||||||
pub scope: AuthorizationScope,
|
pub scope: AuthorizationScope,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct Preferences {
|
||||||
|
pub lastfm_username: Option<String>,
|
||||||
|
pub web_theme_base: Option<String>,
|
||||||
|
pub web_theme_accent: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Manager {
|
pub struct Manager {
|
||||||
// TODO make this private and move preferences methods in this file
|
db: DB,
|
||||||
pub db: DB,
|
|
||||||
auth_secret: AuthSecret,
|
auth_secret: AuthSecret,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,6 +248,38 @@ impl Manager {
|
||||||
Ok(is_admin != 0)
|
Ok(is_admin != 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn read_preferences(&self, username: &str) -> Result<Preferences, Error> {
|
||||||
|
use crate::db::users::dsl::*;
|
||||||
|
let mut connection = self.db.connect()?;
|
||||||
|
let (theme_base, theme_accent, read_lastfm_username) = users
|
||||||
|
.select((web_theme_base, web_theme_accent, lastfm_username))
|
||||||
|
.filter(name.eq(username))
|
||||||
|
.get_result(&mut connection)
|
||||||
|
.map_err(|_| Error::Unspecified)?;
|
||||||
|
Ok(Preferences {
|
||||||
|
web_theme_base: theme_base,
|
||||||
|
web_theme_accent: theme_accent,
|
||||||
|
lastfm_username: read_lastfm_username,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn write_preferences(
|
||||||
|
&self,
|
||||||
|
username: &str,
|
||||||
|
preferences: &Preferences,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
use crate::db::users::dsl::*;
|
||||||
|
let mut connection = self.db.connect()?;
|
||||||
|
diesel::update(users.filter(name.eq(username)))
|
||||||
|
.set((
|
||||||
|
web_theme_base.eq(&preferences.web_theme_base),
|
||||||
|
web_theme_accent.eq(&preferences.web_theme_accent),
|
||||||
|
))
|
||||||
|
.execute(&mut connection)
|
||||||
|
.map_err(|_| Error::Unspecified)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn lastfm_link(
|
pub fn lastfm_link(
|
||||||
&self,
|
&self,
|
||||||
username: &str,
|
username: &str,
|
||||||
|
@ -298,3 +352,196 @@ fn verify_password(password_hash: &str, attempted_password: &str) -> bool {
|
||||||
Err(_) => false,
|
Err(_) => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
use crate::app::test;
|
||||||
|
use crate::test_name;
|
||||||
|
|
||||||
|
const TEST_USERNAME: &str = "Walter";
|
||||||
|
const TEST_PASSWORD: &str = "super_secret!";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn create_delete_user_golden_path() {
|
||||||
|
let ctx = test::ContextBuilder::new(test_name!()).build();
|
||||||
|
|
||||||
|
let new_user = NewUser {
|
||||||
|
name: TEST_USERNAME.to_owned(),
|
||||||
|
password: TEST_PASSWORD.to_owned(),
|
||||||
|
admin: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
ctx.user_manager.create(&new_user).unwrap();
|
||||||
|
assert_eq!(ctx.user_manager.list().unwrap().len(), 1);
|
||||||
|
|
||||||
|
ctx.user_manager.delete(&new_user.name).unwrap();
|
||||||
|
assert_eq!(ctx.user_manager.list().unwrap().len(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cannot_create_user_with_blank_username() {
|
||||||
|
let ctx = test::ContextBuilder::new(test_name!()).build();
|
||||||
|
let new_user = NewUser {
|
||||||
|
name: "".to_owned(),
|
||||||
|
password: TEST_PASSWORD.to_owned(),
|
||||||
|
admin: false,
|
||||||
|
};
|
||||||
|
assert_eq!(
|
||||||
|
ctx.user_manager.create(&new_user).unwrap_err(),
|
||||||
|
Error::EmptyUsername
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cannot_create_user_with_blank_password() {
|
||||||
|
let ctx = test::ContextBuilder::new(test_name!()).build();
|
||||||
|
let new_user = NewUser {
|
||||||
|
name: TEST_USERNAME.to_owned(),
|
||||||
|
password: "".to_owned(),
|
||||||
|
admin: false,
|
||||||
|
};
|
||||||
|
assert_eq!(
|
||||||
|
ctx.user_manager.create(&new_user).unwrap_err(),
|
||||||
|
Error::EmptyPassword
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn cannot_create_duplicate_user() {
|
||||||
|
let ctx = test::ContextBuilder::new(test_name!()).build();
|
||||||
|
let new_user = NewUser {
|
||||||
|
name: TEST_USERNAME.to_owned(),
|
||||||
|
password: TEST_PASSWORD.to_owned(),
|
||||||
|
admin: false,
|
||||||
|
};
|
||||||
|
ctx.user_manager.create(&new_user).unwrap();
|
||||||
|
ctx.user_manager.create(&new_user).unwrap_err();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn can_read_write_preferences() {
|
||||||
|
let ctx = test::ContextBuilder::new(test_name!()).build();
|
||||||
|
|
||||||
|
let new_preferences = Preferences {
|
||||||
|
web_theme_base: Some("very-dark-theme".to_owned()),
|
||||||
|
web_theme_accent: Some("#FF0000".to_owned()),
|
||||||
|
lastfm_username: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let new_user = NewUser {
|
||||||
|
name: TEST_USERNAME.to_owned(),
|
||||||
|
password: TEST_PASSWORD.to_owned(),
|
||||||
|
admin: false,
|
||||||
|
};
|
||||||
|
ctx.user_manager.create(&new_user).unwrap();
|
||||||
|
|
||||||
|
ctx.user_manager
|
||||||
|
.write_preferences(TEST_USERNAME, &new_preferences)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let read_preferences = ctx.user_manager.read_preferences("Walter").unwrap();
|
||||||
|
assert_eq!(new_preferences, read_preferences);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn login_rejects_bad_password() {
|
||||||
|
let ctx = test::ContextBuilder::new(test_name!()).build();
|
||||||
|
|
||||||
|
let new_user = NewUser {
|
||||||
|
name: TEST_USERNAME.to_owned(),
|
||||||
|
password: TEST_PASSWORD.to_owned(),
|
||||||
|
admin: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
ctx.user_manager.create(&new_user).unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
ctx.user_manager
|
||||||
|
.login(TEST_USERNAME, "not the password")
|
||||||
|
.unwrap_err(),
|
||||||
|
Error::IncorrectPassword
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn login_golden_path() {
|
||||||
|
let ctx = test::ContextBuilder::new(test_name!()).build();
|
||||||
|
let new_user = NewUser {
|
||||||
|
name: TEST_USERNAME.to_owned(),
|
||||||
|
password: TEST_PASSWORD.to_owned(),
|
||||||
|
admin: false,
|
||||||
|
};
|
||||||
|
ctx.user_manager.create(&new_user).unwrap();
|
||||||
|
assert!(ctx.user_manager.login(TEST_USERNAME, TEST_PASSWORD).is_ok())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn authenticate_rejects_bad_token() {
|
||||||
|
let ctx = test::ContextBuilder::new(test_name!()).build();
|
||||||
|
|
||||||
|
let new_user = NewUser {
|
||||||
|
name: TEST_USERNAME.to_owned(),
|
||||||
|
password: TEST_PASSWORD.to_owned(),
|
||||||
|
admin: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
ctx.user_manager.create(&new_user).unwrap();
|
||||||
|
let fake_token = AuthToken("fake token".to_owned());
|
||||||
|
assert!(ctx
|
||||||
|
.user_manager
|
||||||
|
.authenticate(&fake_token, AuthorizationScope::PolarisAuth)
|
||||||
|
.is_err())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn authenticate_golden_path() {
|
||||||
|
let ctx = test::ContextBuilder::new(test_name!()).build();
|
||||||
|
|
||||||
|
let new_user = NewUser {
|
||||||
|
name: TEST_USERNAME.to_owned(),
|
||||||
|
password: TEST_PASSWORD.to_owned(),
|
||||||
|
admin: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
ctx.user_manager.create(&new_user).unwrap();
|
||||||
|
let token = ctx
|
||||||
|
.user_manager
|
||||||
|
.login(TEST_USERNAME, TEST_PASSWORD)
|
||||||
|
.unwrap();
|
||||||
|
let authorization = ctx
|
||||||
|
.user_manager
|
||||||
|
.authenticate(&token, AuthorizationScope::PolarisAuth)
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
authorization,
|
||||||
|
Authorization {
|
||||||
|
username: TEST_USERNAME.to_owned(),
|
||||||
|
scope: AuthorizationScope::PolarisAuth,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn authenticate_validates_scope() {
|
||||||
|
let ctx = test::ContextBuilder::new(test_name!()).build();
|
||||||
|
|
||||||
|
let new_user = NewUser {
|
||||||
|
name: TEST_USERNAME.to_owned(),
|
||||||
|
password: TEST_PASSWORD.to_owned(),
|
||||||
|
admin: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
ctx.user_manager.create(&new_user).unwrap();
|
||||||
|
let token = ctx
|
||||||
|
.user_manager
|
||||||
|
.generate_lastfm_link_token(TEST_USERNAME)
|
||||||
|
.unwrap();
|
||||||
|
let authorization = ctx
|
||||||
|
.user_manager
|
||||||
|
.authenticate(&token, AuthorizationScope::PolarisAuth);
|
||||||
|
assert_eq!(
|
||||||
|
authorization.unwrap_err(),
|
||||||
|
Error::IncorrectAuthorizationScope
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
#[derive(thiserror::Error, Debug, PartialEq, Eq)]
|
|
||||||
pub enum Error {
|
|
||||||
#[error("Cannot use empty username")]
|
|
||||||
EmptyUsername,
|
|
||||||
#[error("Cannot use empty password")]
|
|
||||||
EmptyPassword,
|
|
||||||
#[error("Username does not exist")]
|
|
||||||
IncorrectUsername,
|
|
||||||
#[error("Password does not match username")]
|
|
||||||
IncorrectPassword,
|
|
||||||
#[error("Invalid auth token")]
|
|
||||||
InvalidAuthToken,
|
|
||||||
#[error("Incorrect authorization scope")]
|
|
||||||
IncorrectAuthorizationScope,
|
|
||||||
#[error("Unspecified")]
|
|
||||||
Unspecified,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<anyhow::Error> for Error {
|
|
||||||
fn from(_: anyhow::Error) -> Self {
|
|
||||||
Error::Unspecified
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,40 +0,0 @@
|
||||||
use anyhow::Result;
|
|
||||||
use diesel::prelude::*;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
|
||||||
pub struct Preferences {
|
|
||||||
pub lastfm_username: Option<String>,
|
|
||||||
pub web_theme_base: Option<String>,
|
|
||||||
pub web_theme_accent: Option<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Manager {
|
|
||||||
pub fn read_preferences(&self, username: &str) -> Result<Preferences> {
|
|
||||||
use self::users::dsl::*;
|
|
||||||
let mut connection = self.db.connect()?;
|
|
||||||
let (theme_base, theme_accent, read_lastfm_username) = users
|
|
||||||
.select((web_theme_base, web_theme_accent, lastfm_username))
|
|
||||||
.filter(name.eq(username))
|
|
||||||
.get_result(&mut connection)?;
|
|
||||||
Ok(Preferences {
|
|
||||||
web_theme_base: theme_base,
|
|
||||||
web_theme_accent: theme_accent,
|
|
||||||
lastfm_username: read_lastfm_username,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn write_preferences(&self, username: &str, preferences: &Preferences) -> Result<()> {
|
|
||||||
use crate::db::users::dsl::*;
|
|
||||||
let mut connection = self.db.connect()?;
|
|
||||||
diesel::update(users.filter(name.eq(username)))
|
|
||||||
.set((
|
|
||||||
web_theme_base.eq(&preferences.web_theme_base),
|
|
||||||
web_theme_accent.eq(&preferences.web_theme_accent),
|
|
||||||
))
|
|
||||||
.execute(&mut connection)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,189 +0,0 @@
|
||||||
use super::*;
|
|
||||||
use crate::app::test;
|
|
||||||
use crate::test_name;
|
|
||||||
|
|
||||||
const TEST_USERNAME: &str = "Walter";
|
|
||||||
const TEST_PASSWORD: &str = "super_secret!";
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn create_delete_user_golden_path() {
|
|
||||||
let ctx = test::ContextBuilder::new(test_name!()).build();
|
|
||||||
|
|
||||||
let new_user = NewUser {
|
|
||||||
name: TEST_USERNAME.to_owned(),
|
|
||||||
password: TEST_PASSWORD.to_owned(),
|
|
||||||
admin: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
ctx.user_manager.create(&new_user).unwrap();
|
|
||||||
assert_eq!(ctx.user_manager.list().unwrap().len(), 1);
|
|
||||||
|
|
||||||
ctx.user_manager.delete(&new_user.name).unwrap();
|
|
||||||
assert_eq!(ctx.user_manager.list().unwrap().len(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn cannot_create_user_with_blank_username() {
|
|
||||||
let ctx = test::ContextBuilder::new(test_name!()).build();
|
|
||||||
let new_user = NewUser {
|
|
||||||
name: "".to_owned(),
|
|
||||||
password: TEST_PASSWORD.to_owned(),
|
|
||||||
admin: false,
|
|
||||||
};
|
|
||||||
assert_eq!(
|
|
||||||
ctx.user_manager.create(&new_user).unwrap_err(),
|
|
||||||
Error::EmptyUsername
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn cannot_create_user_with_blank_password() {
|
|
||||||
let ctx = test::ContextBuilder::new(test_name!()).build();
|
|
||||||
let new_user = NewUser {
|
|
||||||
name: TEST_USERNAME.to_owned(),
|
|
||||||
password: "".to_owned(),
|
|
||||||
admin: false,
|
|
||||||
};
|
|
||||||
assert_eq!(
|
|
||||||
ctx.user_manager.create(&new_user).unwrap_err(),
|
|
||||||
Error::EmptyPassword
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn cannot_create_duplicate_user() {
|
|
||||||
let ctx = test::ContextBuilder::new(test_name!()).build();
|
|
||||||
let new_user = NewUser {
|
|
||||||
name: TEST_USERNAME.to_owned(),
|
|
||||||
password: TEST_PASSWORD.to_owned(),
|
|
||||||
admin: false,
|
|
||||||
};
|
|
||||||
ctx.user_manager.create(&new_user).unwrap();
|
|
||||||
ctx.user_manager.create(&new_user).unwrap_err();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn can_read_write_preferences() {
|
|
||||||
let ctx = test::ContextBuilder::new(test_name!()).build();
|
|
||||||
|
|
||||||
let new_preferences = Preferences {
|
|
||||||
web_theme_base: Some("very-dark-theme".to_owned()),
|
|
||||||
web_theme_accent: Some("#FF0000".to_owned()),
|
|
||||||
lastfm_username: None,
|
|
||||||
};
|
|
||||||
|
|
||||||
let new_user = NewUser {
|
|
||||||
name: TEST_USERNAME.to_owned(),
|
|
||||||
password: TEST_PASSWORD.to_owned(),
|
|
||||||
admin: false,
|
|
||||||
};
|
|
||||||
ctx.user_manager.create(&new_user).unwrap();
|
|
||||||
|
|
||||||
ctx.user_manager
|
|
||||||
.write_preferences(TEST_USERNAME, &new_preferences)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let read_preferences = ctx.user_manager.read_preferences("Walter").unwrap();
|
|
||||||
assert_eq!(new_preferences, read_preferences);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn login_rejects_bad_password() {
|
|
||||||
let ctx = test::ContextBuilder::new(test_name!()).build();
|
|
||||||
|
|
||||||
let new_user = NewUser {
|
|
||||||
name: TEST_USERNAME.to_owned(),
|
|
||||||
password: TEST_PASSWORD.to_owned(),
|
|
||||||
admin: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
ctx.user_manager.create(&new_user).unwrap();
|
|
||||||
assert_eq!(
|
|
||||||
ctx.user_manager
|
|
||||||
.login(TEST_USERNAME, "not the password")
|
|
||||||
.unwrap_err(),
|
|
||||||
Error::IncorrectPassword
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn login_golden_path() {
|
|
||||||
let ctx = test::ContextBuilder::new(test_name!()).build();
|
|
||||||
let new_user = NewUser {
|
|
||||||
name: TEST_USERNAME.to_owned(),
|
|
||||||
password: TEST_PASSWORD.to_owned(),
|
|
||||||
admin: false,
|
|
||||||
};
|
|
||||||
ctx.user_manager.create(&new_user).unwrap();
|
|
||||||
assert!(ctx.user_manager.login(TEST_USERNAME, TEST_PASSWORD).is_ok())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn authenticate_rejects_bad_token() {
|
|
||||||
let ctx = test::ContextBuilder::new(test_name!()).build();
|
|
||||||
|
|
||||||
let new_user = NewUser {
|
|
||||||
name: TEST_USERNAME.to_owned(),
|
|
||||||
password: TEST_PASSWORD.to_owned(),
|
|
||||||
admin: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
ctx.user_manager.create(&new_user).unwrap();
|
|
||||||
let fake_token = AuthToken("fake token".to_owned());
|
|
||||||
assert!(ctx
|
|
||||||
.user_manager
|
|
||||||
.authenticate(&fake_token, AuthorizationScope::PolarisAuth)
|
|
||||||
.is_err())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn authenticate_golden_path() {
|
|
||||||
let ctx = test::ContextBuilder::new(test_name!()).build();
|
|
||||||
|
|
||||||
let new_user = NewUser {
|
|
||||||
name: TEST_USERNAME.to_owned(),
|
|
||||||
password: TEST_PASSWORD.to_owned(),
|
|
||||||
admin: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
ctx.user_manager.create(&new_user).unwrap();
|
|
||||||
let token = ctx
|
|
||||||
.user_manager
|
|
||||||
.login(TEST_USERNAME, TEST_PASSWORD)
|
|
||||||
.unwrap();
|
|
||||||
let authorization = ctx
|
|
||||||
.user_manager
|
|
||||||
.authenticate(&token, AuthorizationScope::PolarisAuth)
|
|
||||||
.unwrap();
|
|
||||||
assert_eq!(
|
|
||||||
authorization,
|
|
||||||
Authorization {
|
|
||||||
username: TEST_USERNAME.to_owned(),
|
|
||||||
scope: AuthorizationScope::PolarisAuth,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn authenticate_validates_scope() {
|
|
||||||
let ctx = test::ContextBuilder::new(test_name!()).build();
|
|
||||||
|
|
||||||
let new_user = NewUser {
|
|
||||||
name: TEST_USERNAME.to_owned(),
|
|
||||||
password: TEST_PASSWORD.to_owned(),
|
|
||||||
admin: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
ctx.user_manager.create(&new_user).unwrap();
|
|
||||||
let token = ctx
|
|
||||||
.user_manager
|
|
||||||
.generate_lastfm_link_token(TEST_USERNAME)
|
|
||||||
.unwrap();
|
|
||||||
let authorization = ctx
|
|
||||||
.user_manager
|
|
||||||
.authenticate(&token, AuthorizationScope::PolarisAuth);
|
|
||||||
assert_eq!(
|
|
||||||
authorization.unwrap_err(),
|
|
||||||
Error::IncorrectAuthorizationScope
|
|
||||||
)
|
|
||||||
}
|
|
Loading…
Add table
Reference in a new issue