123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319 |
- use crate::{cert, client_management, schema::{self, schema}, server, user_management, config, token};
- use clap::{Parser, Subcommand};
- use microrm::prelude::*;
- #[derive(Debug, Parser)]
- #[clap(author, version, about, long_about = None)]
- struct RootArgs {
- #[clap(short, long, default_value_t = String::from("uauth.db"))]
- /// Database path
- db: String,
- #[clap(short, long, default_value_t = String::from("primary"))]
- /// Which realm to use, for non-server only
- realm: String,
- #[clap(subcommand)]
- command: Command,
- }
- #[derive(Debug, Subcommand)]
- enum Command {
- Init,
- Cert(CertArgs),
- Client(ClientArgs),
- Config(ConfigArgs),
- Group(GroupArgs),
- Server(ServerArgs),
- Token(TokenArgs),
- User(UserArgs),
- }
- impl RootArgs {
- async fn run(&self) {
- if let Command::Init = self.command {
- return self.init().await;
- }
- let storage = microrm::DB::new(schema::schema(), &self.db, microrm::CreateMode::MustExist);
- if let Err(e) = storage {
- println!("Error occured while loading database: {}", e);
- return;
- }
- let storage = storage.unwrap();
- match &self.command {
- Command::Init => unreachable!(),
- Command::Cert(v) => v.run(&self, storage).await,
- Command::Config(v) => v.run(&self, storage).await,
- Command::Client(v) => v.run(&self, storage).await,
- Command::Group(v) => v.run(&self, storage).await,
- Command::Server(v) => v.run(&self, storage).await,
- Command::Token(v) => v.run(&self, storage).await,
- Command::User(v) => v.run(&self, storage).await,
- }
- }
- async fn init(&self) {
- // first check to see if the database is already vaguely set up
- let maybedb = microrm::DB::new(schema::schema(), &self.db, microrm::CreateMode::MustExist);
- if maybedb.is_ok() {
- println!("Database already initialized, not overwriting!");
- return;
- }
- println!("Initializing!");
- let db = microrm::DB::new(
- schema::schema(),
- &self.db,
- microrm::CreateMode::AllowNewDatabase,
- )
- .expect("Unable to initialize database!");
- // create primary realm
- db.query_interface()
- .add(&schema::Realm {
- shortname: "primary".to_string(),
- })
- .expect("couldn't add realm");
- }
- }
- #[derive(Debug, Subcommand)]
- enum CertCommand {
- Inspect,
- Generate,
- }
- #[derive(Debug, Parser)]
- struct CertArgs {
- #[clap(subcommand)]
- command: CertCommand,
- }
- impl CertArgs {
- async fn run(&self, root: &RootArgs, db: microrm::DB) {
- match &self.command {
- CertCommand::Inspect => {
- cert::inspect(&db, &root.realm);
- }
- CertCommand::Generate => {
- cert::generate(&db, &root.realm);
- }
- }
- }
- }
- #[derive(Debug, Subcommand)]
- enum ClientCommand {
- Create { name: String },
- List,
- Inspect { name: String },
- }
- #[derive(Debug, Parser)]
- struct ClientArgs {
- #[clap(subcommand)]
- command: ClientCommand,
- }
- impl ClientArgs {
- async fn run(&self, root: &RootArgs, db: microrm::DB) {
- match &self.command {
- ClientCommand::Create { name } => {
- client_management::create(&db, root.realm.as_str(), name);
- }
- ClientCommand::List => {}
- ClientCommand::Inspect { name } => {
- client_management::inspect(&db, name);
- }
- }
- }
- }
- #[derive(Debug, Subcommand)]
- enum ConfigCommand {
- Dump,
- Load {
- toml_path: String
- },
- Set {
- key: String,
- value: String,
- }
- }
- #[derive(Debug, Parser)]
- struct ConfigArgs {
- #[clap(subcommand)]
- command: ConfigCommand,
- }
- impl ConfigArgs {
- async fn run(&self, root: &RootArgs, db: microrm::DB) {
- match &self.command {
- ConfigCommand::Dump => {
- let qi = db.query_interface();
- let config = config::Config::build_from(&qi, None);
- println!("config: {:?}", config);
- },
- ConfigCommand::Set { key, value } => {
- todo!()
- },
- ConfigCommand::Load { toml_path } => {
- let config = {
- let qi = db.query_interface();
- config::Config::build_from(&qi, Some(toml_path))
- };
- {
- let qi = db.query_interface();
- config.save(&qi);
- drop(config);
- }
- },
- }
- }
- }
- #[derive(Debug, Subcommand)]
- enum GroupCommand {}
- #[derive(Debug, Parser)]
- struct GroupArgs {
- #[clap(subcommand)]
- command: GroupCommand,
- }
- impl GroupArgs {
- async fn run(&self, root: &RootArgs, db: microrm::DB) {}
- }
- #[derive(Debug, Parser)]
- struct ServerArgs {
- #[clap(short, long)]
- port: Option<u16>,
- #[clap(short, long)]
- config_path: Option<String>,
- }
- impl ServerArgs {
- async fn run(&self, root: &RootArgs, db: microrm::DB) {
- let config = config::Config::build_from(
- &db.query_interface(),
- self.config_path.as_ref().map(|x| x.as_str()),
- );
- server::run_server(db, config, self.port.unwrap_or(2114)).await
- }
- }
- #[derive(Debug, Subcommand)]
- enum TokenCommand {
- GenerateAuth {
- #[clap(short, long)]
- client: String,
- #[clap(short, long)]
- username: String,
- #[clap(short, long)]
- scopes: String
- },
- GenerateRefresh {
- #[clap(short, long)]
- client: String,
- #[clap(short, long)]
- username: String,
- #[clap(short, long)]
- scopes: String
- },
- Inspect { token: String },
- }
- #[derive(Debug, Parser)]
- struct TokenArgs {
- #[clap(subcommand)]
- command: TokenCommand,
- }
- impl TokenArgs {
- async fn run(&self, root: &RootArgs, db: microrm::DB) {
- let config = config::Config::build_from(&db.query_interface(), None);
- match &self.command {
- TokenCommand::GenerateAuth { client, username, scopes } => {
- let qi = db.query_interface();
- let realm_id = qi.get().by(schema::Realm::Shortname, &root.realm).one().unwrap().expect("no such realm").id();
- let token = token::generate_auth_token(
- &config,
- &qi,
- realm_id,
- qi.get().by(schema::Client::Realm, &realm_id).by(schema::Client::Shortname, client.as_str()).one().unwrap().expect("no such client").id(),
- qi.get().by(schema::User::Realm, &realm_id).by(schema::User::Username, username.as_str()).one().unwrap().expect("no such user").id(),
- scopes.split_whitespace(),
- );
- if let Some(t) = token {
- println!("token: {t}");
- }
- else {
- println!("Could not generate token");
- }
- },
- TokenCommand::GenerateRefresh { client, username, scopes } => {
-
- },
- TokenCommand::Inspect { token } => {
-
- },
- }
- }
- }
- #[derive(Debug, Parser)]
- struct CreateUserArgs {
- username: String,
- }
- #[derive(Debug, Parser)]
- struct AuthUserArgs {
- username: String,
- #[clap(short = 'p', long, parse(from_occurrences))]
- change_password: usize,
- }
- #[derive(Debug, Subcommand)]
- enum UserCommand {
- List,
- Create(CreateUserArgs),
- Auth(AuthUserArgs),
- }
- #[derive(Debug, Parser)]
- struct UserArgs {
- #[clap(subcommand)]
- command: UserCommand,
- }
- impl UserArgs {
- async fn run(&self, root: &RootArgs, db: microrm::DB) {
- match &self.command {
- UserCommand::List => user_management::list(&root.realm, db),
- UserCommand::Create(args) => {
- user_management::create(&root.realm, db, args.username.as_str())
- }
- UserCommand::Auth(args) => user_management::change_auth(
- &root.realm,
- db,
- args.username.as_str(),
- args.change_password > 0,
- ),
- }
- }
- }
- pub fn invoked() {
- let args = RootArgs::parse();
- smol::block_on(args.run());
- // async_std::task::block_on(args.run());
- }
|