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
//! # Qonfucius SSO Utility //! //! `qonfucius-sso-utility` is a simple tool to implement Qonfucius's [SSO](https://gitlab.com/qonfucius/web/services/authorization/sso) and handle token and scope verification on your back-end resource web app. //! //! ## Environment variables //! //! | Name | Description | //! |---------------------|----------------------------------------------------| //! | SSO_URI | URL of the SSO instance | //! | SSO_SELF_DOMAIN | Domain of your application to identify your scopes | //! //! ## Setup //! //! After installation you need to define a *Scoped Resource* type, usually an `enum` that implements the following traits: //! - `Eq` //! - `Hash` //! - `Clone` //! - `Debug` //! - `FromStr` //! //! ### Example //! //! This is the definition used in one of our own API. //! //! ```rust //! use qonfucius_sso_utility::UtilityError; //! use std::str::FromStr; //! //! #[derive(Clone, Debug, PartialEq, Hash, Eq)] //! pub enum ScopedResource { //! Content, //! ContentSchema, //! Media, //! } //! //! impl FromStr for ScopedResource { //! type Err = UtilityError; //! //! fn from_str(s: &str) -> Result<Self, Self::Err> { //! match s.to_lowercase().as_str() { //! "content" => Ok(Self::Content), //! "content_schema" => Ok(Self::ContentSchema), //! "media" => Ok(Self::Media), //! _ => Err(UtilityError::ParsingError(String::from( //! r#"Scoped Resource part must be 'content', 'content_schema' or 'media"#, //! ))), //! } //! } //! } //! ``` //! //! Once your type is declared you can use it as the `T` value of `Scope<T>` //! //! ## Scopes //! //! When you verify a token the `scope` will look like this: //! //! ```json //! { //! "scopes": { //! "my_domain": ["content::read", "notifications::write", "medias::write"], //! "not_my_domain": ["some_resource::read", "stuff::write"] //! } //! } //! ``` //! //! The env var `SELF_SSO_DOMAIN` will define which subset to use, and the scopes will be parsed. Each scope looks like this: //! `$RESOURCE::$ACL`. //! While the `$ACL` is either `write` or `read`, the `$RESOURCE` is for you to define like we showed earlier. //! //! ## Steps //! //! To verify a token and access authorized scopes the steps are the following: //! //! ```rust ignore //! # use qonfucius_sso_utility::*; //! # use qonfucius_sso_utility::scope::Scope; //! # //! # use std::str::FromStr; //! # #[derive(Clone, Debug, PartialEq, Hash, Eq)] //! # pub enum ScopedResource { //! # Content, //! # ContentSchema, //! # Media, //! # } //! # impl FromStr for ScopedResource { //! # type Err = UtilityError; //! # fn from_str(s: &str) -> Result<Self, Self::Err> { //! # match s.to_lowercase().as_str() { //! # "content" => Ok(Self::Content), //! # "content_schema" => Ok(Self::ContentSchema), //! # "media" => Ok(Self::Media), //! # _ => Err(UtilityError::ParsingError(String::from( //! # r#"Scoped Resource part must be 'content', 'content_schema' or 'media"#, //! # ))), //! # } //! # } //! # } //! # #[actix_rt::main] //! async fn main() { //! let token = "TokenToCheck"; //! // Calls the SSO to verify the token and retrieves the `Token` response //! let token_response = Token::verify_token(&token).await.unwrap(); //! // Parse the scopes matching your domain (`SSO_SELF_DOMAIN`) //! let scope: Scope<ScopedResource> = token_response.parse_scope().unwrap(); //! // you can now use the `Scope<T>` object to handle your authorizations //! } //! ``` // #![forbid(missing_docs)] #[macro_use] extern crate lazy_static; pub use {authorize_scope::AuthorizeScope, error::UtilityError, token::Token, user::User}; mod authorize_scope; mod error; /// Scope handling module pub mod scope; mod token; mod user; lazy_static! { static ref SSO_URI: String = std::env::var("SSO_URI").unwrap(); static ref SSO_SELF_DOMAIN: String = std::env::var("SSO_SELF_DOMAIN").unwrap(); }