2022-08-06 20:09:30 +02:00
|
|
|
extern crate serde_derive;
|
|
|
|
|
|
|
|
use actix_admin::prelude::*;
|
|
|
|
use actix_session::{Session, SessionMiddleware, storage::CookieSessionStore};
|
|
|
|
use actix_web::{cookie::Key, web, App, HttpResponse, HttpServer, middleware};
|
|
|
|
use azure_auth::{AppDataTrait as AzureAuthAppDataTrait, AzureAuth, UserInfo};
|
|
|
|
use oauth2::basic::BasicClient;
|
|
|
|
use oauth2::RedirectUrl;
|
2023-06-27 13:05:44 +02:00
|
|
|
use sea_orm::{ConnectOptions};
|
2022-08-06 20:09:30 +02:00
|
|
|
use std::env;
|
|
|
|
use std::time::Duration;
|
|
|
|
use tera::{Context, Tera};
|
2022-08-29 13:06:44 +02:00
|
|
|
use actix_web::Error;
|
2022-08-06 20:09:30 +02:00
|
|
|
|
|
|
|
mod entity;
|
|
|
|
use entity::{Post, Comment};
|
|
|
|
|
2022-08-16 00:17:35 +02:00
|
|
|
#[derive(Clone)]
|
2022-08-06 20:09:30 +02:00
|
|
|
pub struct AppState {
|
|
|
|
pub oauth: BasicClient,
|
2023-06-27 13:05:44 +02:00
|
|
|
pub tmpl: Tera
|
2022-08-29 13:06:44 +02:00
|
|
|
}
|
|
|
|
|
2022-08-06 20:09:30 +02:00
|
|
|
impl AzureAuthAppDataTrait for AppState {
|
|
|
|
fn get_oauth(&self) -> &BasicClient {
|
|
|
|
&self.oauth
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-27 13:05:44 +02:00
|
|
|
async fn custom_handler(
|
2022-08-29 13:06:44 +02:00
|
|
|
session: Session,
|
2023-06-27 13:05:44 +02:00
|
|
|
data: web::Data<AppState>,
|
|
|
|
actix_admin: web::Data<ActixAdmin>,
|
2022-08-28 17:06:23 +02:00
|
|
|
_text: String
|
2022-08-29 13:06:44 +02:00
|
|
|
) -> Result<HttpResponse, Error> {
|
|
|
|
|
|
|
|
let mut ctx = Context::new();
|
2023-06-27 13:05:44 +02:00
|
|
|
ctx.extend(get_admin_ctx(session, &actix_admin));
|
2022-08-29 13:06:44 +02:00
|
|
|
|
2023-06-27 13:05:44 +02:00
|
|
|
let body = data.tmpl.render("custom_handler.html", &ctx).unwrap();
|
2022-08-29 13:06:44 +02:00
|
|
|
|
|
|
|
Ok(HttpResponse::Ok().content_type("text/html").body(body))
|
2022-08-28 17:06:23 +02:00
|
|
|
}
|
|
|
|
|
2023-06-27 13:05:44 +02:00
|
|
|
async fn custom_index(
|
2022-08-29 13:06:44 +02:00
|
|
|
session: Session,
|
2023-06-27 13:05:44 +02:00
|
|
|
data: web::Data<AppState>,
|
|
|
|
actix_admin: web::Data<ActixAdmin>,
|
2022-08-29 13:06:44 +02:00
|
|
|
_text: String
|
|
|
|
) -> Result<HttpResponse, Error> {
|
|
|
|
|
|
|
|
let mut ctx = Context::new();
|
2023-06-27 13:05:44 +02:00
|
|
|
ctx.extend(get_admin_ctx(session, &actix_admin));
|
2022-08-29 13:06:44 +02:00
|
|
|
|
2023-06-27 13:05:44 +02:00
|
|
|
let body = data.tmpl.render("custom_index.html", &ctx).unwrap();
|
2022-08-29 13:06:44 +02:00
|
|
|
|
|
|
|
Ok(HttpResponse::Ok().content_type("text/html").body(body))
|
|
|
|
}
|
|
|
|
|
2022-08-06 20:09:30 +02:00
|
|
|
async fn index(session: Session, data: web::Data<AppState>) -> HttpResponse {
|
|
|
|
let login = session.get::<UserInfo>("user_info").unwrap();
|
|
|
|
let web_auth_link = if login.is_some() {
|
2022-08-06 21:49:52 +02:00
|
|
|
"azure-auth/logout"
|
2022-08-06 20:09:30 +02:00
|
|
|
} else {
|
2022-08-06 21:49:52 +02:00
|
|
|
"azure-auth/login"
|
2022-08-06 20:09:30 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
let mut ctx = Context::new();
|
|
|
|
ctx.insert("web_auth_link", web_auth_link);
|
|
|
|
let rendered = data.tmpl.render("index.html", &ctx).unwrap();
|
|
|
|
HttpResponse::Ok().body(rendered)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn create_actix_admin_builder() -> ActixAdminBuilder {
|
|
|
|
let post_view_model = ActixAdminViewModel::from(Post);
|
|
|
|
let comment_view_model = ActixAdminViewModel::from(Comment);
|
|
|
|
|
2022-08-06 21:49:52 +02:00
|
|
|
let configuration = ActixAdminConfiguration {
|
2022-11-08 17:10:27 +01:00
|
|
|
enable_auth: true,
|
2022-08-16 00:17:35 +02:00
|
|
|
user_is_logged_in: Some(|session: &Session| -> bool {
|
|
|
|
let user_info = session.get::<UserInfo>("user_info").unwrap();
|
|
|
|
user_info.is_some()
|
|
|
|
}),
|
2022-08-27 14:41:08 +02:00
|
|
|
login_link: Some("/azure-auth/login".to_string()),
|
2022-12-29 19:56:20 +01:00
|
|
|
logout_link: Some("/azure-auth/logout".to_string()),
|
2023-06-15 13:03:44 +02:00
|
|
|
file_upload_directory: "./file_uploads",
|
|
|
|
navbar_title: "ActixAdmin Example"
|
2022-08-06 21:49:52 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
let mut admin_builder = ActixAdminBuilder::new(configuration);
|
2023-06-27 13:05:44 +02:00
|
|
|
admin_builder.add_custom_handler_for_index(
|
|
|
|
web::get().to(custom_index)
|
2023-01-21 14:49:00 +01:00
|
|
|
);
|
2023-06-27 13:05:44 +02:00
|
|
|
admin_builder.add_entity::<Post>(&post_view_model);
|
|
|
|
admin_builder.add_custom_handler("Custom Route in Menu", "/custom_route_in_menu", web::get().to(custom_index), true);
|
|
|
|
admin_builder.add_custom_handler("Custom Route not in Menu", "/custom_route_not_in_menu", web::get().to(custom_index), false);
|
2022-09-12 21:22:25 +02:00
|
|
|
|
|
|
|
let some_category = "Some Category";
|
2023-06-27 13:05:44 +02:00
|
|
|
admin_builder.add_entity_to_category::<Comment>(&comment_view_model, some_category);
|
|
|
|
admin_builder.add_custom_handler_for_entity_in_category::<Comment>(
|
2022-09-29 16:23:49 +02:00
|
|
|
"My custom handler",
|
2022-08-28 17:06:23 +02:00
|
|
|
"/custom_handler",
|
2023-06-27 13:05:44 +02:00
|
|
|
web::get().to(custom_handler),
|
2022-10-11 18:54:45 +02:00
|
|
|
some_category,
|
|
|
|
true
|
2022-08-28 17:06:23 +02:00
|
|
|
);
|
2022-08-06 20:09:30 +02:00
|
|
|
|
|
|
|
admin_builder
|
|
|
|
}
|
|
|
|
|
|
|
|
#[actix_rt::main]
|
|
|
|
async fn main() {
|
2022-12-29 19:56:20 +01:00
|
|
|
dotenv::from_filename("./examples/azure_auth/.env.example").ok();
|
|
|
|
dotenv::from_filename("./examples/azure_auth/.env").ok();
|
2022-09-02 17:23:06 +02:00
|
|
|
|
2022-11-08 17:10:27 +01:00
|
|
|
let oauth2_client_id = env::var("OAUTH2_CLIENT_ID").expect("Missing the OAUTH2_CLIENT_ID environment variable.");
|
|
|
|
let oauth2_client_secret = env::var("OAUTH2_CLIENT_SECRET").expect("Missing the OAUTH2_CLIENT_SECRET environment variable.");
|
|
|
|
let oauth2_server= env::var("OAUTH2_SERVER").expect("Missing the OAUTH2_SERVER environment variable.");
|
2022-09-02 17:23:06 +02:00
|
|
|
|
2022-08-06 20:09:30 +02:00
|
|
|
let azure_auth = AzureAuth::new(&oauth2_server, &oauth2_client_id, &oauth2_client_secret);
|
|
|
|
|
|
|
|
// Set up the config for the OAuth2 process.
|
|
|
|
let client = azure_auth
|
|
|
|
.clone()
|
|
|
|
.get_oauth_client()
|
|
|
|
// This example will be running its own server at 127.0.0.1:5000.
|
|
|
|
.set_redirect_uri(
|
2022-08-06 21:49:52 +02:00
|
|
|
RedirectUrl::new("http://localhost:5000/azure-auth/auth".to_string())
|
2022-08-06 20:09:30 +02:00
|
|
|
.expect("Invalid redirect URL"),
|
|
|
|
);
|
|
|
|
|
|
|
|
|
2022-09-02 17:23:06 +02:00
|
|
|
let db_url = "sqlite::memory:".to_string();
|
2022-08-06 20:09:30 +02:00
|
|
|
let mut opt = ConnectOptions::new(db_url);
|
|
|
|
opt.max_connections(100)
|
|
|
|
.min_connections(5)
|
|
|
|
.connect_timeout(Duration::from_secs(8))
|
|
|
|
.idle_timeout(Duration::from_secs(8))
|
|
|
|
.sqlx_logging(true);
|
|
|
|
|
|
|
|
let conn = sea_orm::Database::connect(opt).await.unwrap();
|
|
|
|
let _ = entity::create_post_table(&conn).await;
|
|
|
|
|
2022-08-16 00:17:35 +02:00
|
|
|
let cookie_secret_key = Key::generate();
|
2022-08-06 20:09:30 +02:00
|
|
|
HttpServer::new(move || {
|
2022-11-08 17:10:27 +01:00
|
|
|
let actix_admin_builder = create_actix_admin_builder();
|
2023-03-20 18:29:37 +01:00
|
|
|
|
|
|
|
let actix_admin = actix_admin_builder.get_actix_admin();
|
|
|
|
let mut tera = Tera::parse(concat!(env!("CARGO_MANIFEST_DIR"), "/templates/**/*")).unwrap();
|
|
|
|
tera.extend(&actix_admin.tera).unwrap();
|
|
|
|
let _tera_res = tera.build_inheritance_chains();
|
2022-11-08 17:10:27 +01:00
|
|
|
|
|
|
|
let app_state = AppState {
|
|
|
|
oauth: client.clone(),
|
2023-06-27 13:05:44 +02:00
|
|
|
tmpl: tera.clone()
|
2022-11-08 17:10:27 +01:00
|
|
|
};
|
|
|
|
|
2022-08-06 20:09:30 +02:00
|
|
|
App::new()
|
|
|
|
.app_data(web::Data::new(app_state.clone()))
|
2023-06-27 13:05:44 +02:00
|
|
|
.app_data(web::Data::new(conn.clone()))
|
|
|
|
.app_data(web::Data::new(actix_admin.clone()))
|
2022-08-16 00:17:35 +02:00
|
|
|
.wrap(SessionMiddleware::new(CookieSessionStore::default(), cookie_secret_key.clone()))
|
2022-08-06 20:09:30 +02:00
|
|
|
.route("/", web::get().to(index))
|
|
|
|
.service(azure_auth.clone().create_scope::<AppState>())
|
|
|
|
.service(
|
2023-06-27 13:05:44 +02:00
|
|
|
actix_admin_builder.get_scope()
|
2022-08-06 20:09:30 +02:00
|
|
|
)
|
|
|
|
.wrap(middleware::Logger::default())
|
|
|
|
})
|
|
|
|
.bind("127.0.0.1:5000")
|
|
|
|
.expect("Can not bind to port 5000")
|
|
|
|
.run()
|
|
|
|
.await
|
|
|
|
.unwrap();
|
|
|
|
}
|