mirror of
				https://github.com/nitnelave/lldap.git
				synced 2023-04-12 14:25:13 +00:00 
			
		
		
		
	cli: introduce the export_graphql_schema command
Split the command line into subcommands `run` and `export_graphql_schema`.
This commit is contained in:
		
							parent
							
								
									e6852037cc
								
							
						
					
					
						commit
						9e5a8572fb
					
				
							
								
								
									
										5
									
								
								.github/workflows/rust.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.github/workflows/rust.yml
									
									
									
									
										vendored
									
									
								
							@ -21,6 +21,11 @@ jobs:
 | 
				
			|||||||
        run: cargo build --verbose --workspace
 | 
					        run: cargo build --verbose --workspace
 | 
				
			||||||
      - name: Run tests
 | 
					      - name: Run tests
 | 
				
			||||||
        run: cargo test --verbose --workspace
 | 
					        run: cargo test --verbose --workspace
 | 
				
			||||||
 | 
					      - name: Generate GraphQL schema
 | 
				
			||||||
 | 
					        run: cargo run -- export_graphql_schema -o generated_schema.graphql
 | 
				
			||||||
 | 
					      - name: Check schema
 | 
				
			||||||
 | 
					        run: diff schema.graphql generated_schema.graphql
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  clippy:
 | 
					  clippy:
 | 
				
			||||||
    name: cargo clippy
 | 
					    name: cargo clippy
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										38
									
								
								schema.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								schema.graphql
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					input EqualityConstraint {
 | 
				
			||||||
 | 
					  field: String!
 | 
				
			||||||
 | 
					  value: String!
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Group {
 | 
				
			||||||
 | 
					  id: String!
 | 
				
			||||||
 | 
					  "The groups to which this user belongs."
 | 
				
			||||||
 | 
					  users: [User!]!
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					  A filter for requests, specifying a boolean expression based on field constraints. Only one of
 | 
				
			||||||
 | 
					  the fields can be set at a time.
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					input RequestFilter {
 | 
				
			||||||
 | 
					  any: [RequestFilter!]
 | 
				
			||||||
 | 
					  all: [RequestFilter!]
 | 
				
			||||||
 | 
					  not: RequestFilter
 | 
				
			||||||
 | 
					  eq: EqualityConstraint
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Query {
 | 
				
			||||||
 | 
					  apiVersion: String!
 | 
				
			||||||
 | 
					  user(userId: String!): User!
 | 
				
			||||||
 | 
					  users(filters: RequestFilter): [User!]!
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type User {
 | 
				
			||||||
 | 
					  id: String!
 | 
				
			||||||
 | 
					  email: String!
 | 
				
			||||||
 | 
					  "The groups to which this user belongs."
 | 
				
			||||||
 | 
					  groups: [Group!]!
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					schema {
 | 
				
			||||||
 | 
					  query: Query
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -4,6 +4,23 @@ use clap::Clap;
 | 
				
			|||||||
#[derive(Debug, Clap, Clone)]
 | 
					#[derive(Debug, Clap, Clone)]
 | 
				
			||||||
#[clap(version = "0.1", author = "The LLDAP team")]
 | 
					#[clap(version = "0.1", author = "The LLDAP team")]
 | 
				
			||||||
pub struct CLIOpts {
 | 
					pub struct CLIOpts {
 | 
				
			||||||
 | 
					    /// Export
 | 
				
			||||||
 | 
					    #[clap(subcommand)]
 | 
				
			||||||
 | 
					    pub command: Command,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, Clap, Clone)]
 | 
				
			||||||
 | 
					pub enum Command {
 | 
				
			||||||
 | 
					    /// Export the GraphQL schema to *.graphql.
 | 
				
			||||||
 | 
					    #[clap(name = "export_graphql_schema")]
 | 
				
			||||||
 | 
					    ExportGraphQLSchema(ExportGraphQLSchemaOpts),
 | 
				
			||||||
 | 
					    /// Run the LDAP and GraphQL server.
 | 
				
			||||||
 | 
					    #[clap(name = "run")]
 | 
				
			||||||
 | 
					    Run(RunOpts),
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, Clap, Clone)]
 | 
				
			||||||
 | 
					pub struct RunOpts {
 | 
				
			||||||
    /// Change config file name
 | 
					    /// Change config file name
 | 
				
			||||||
    #[clap(short, long, default_value = "lldap_config.toml")]
 | 
					    #[clap(short, long, default_value = "lldap_config.toml")]
 | 
				
			||||||
    pub config_file: String,
 | 
					    pub config_file: String,
 | 
				
			||||||
@ -21,6 +38,13 @@ pub struct CLIOpts {
 | 
				
			|||||||
    pub verbose: bool,
 | 
					    pub verbose: bool,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, Clap, Clone)]
 | 
				
			||||||
 | 
					pub struct ExportGraphQLSchemaOpts {
 | 
				
			||||||
 | 
					    /// Output to a file. If not specified, the config is printed to the standard output.
 | 
				
			||||||
 | 
					    #[clap(short, long)]
 | 
				
			||||||
 | 
					    pub output_file: Option<String>,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn init() -> CLIOpts {
 | 
					pub fn init() -> CLIOpts {
 | 
				
			||||||
    CLIOpts::parse()
 | 
					    CLIOpts::parse()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -6,7 +6,7 @@ use figment::{
 | 
				
			|||||||
use lldap_model::opaque::{server::ServerSetup, KeyPair};
 | 
					use lldap_model::opaque::{server::ServerSetup, KeyPair};
 | 
				
			||||||
use serde::{Deserialize, Serialize};
 | 
					use serde::{Deserialize, Serialize};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::infra::cli::CLIOpts;
 | 
					use crate::infra::cli::RunOpts;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Clone, Debug, Deserialize, Serialize, derive_builder::Builder)]
 | 
					#[derive(Clone, Debug, Deserialize, Serialize, derive_builder::Builder)]
 | 
				
			||||||
#[builder(
 | 
					#[builder(
 | 
				
			||||||
@ -55,7 +55,7 @@ impl Configuration {
 | 
				
			|||||||
        self.get_server_setup().keypair()
 | 
					        self.get_server_setup().keypair()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn merge_with_cli(mut self: Configuration, cli_opts: CLIOpts) -> Configuration {
 | 
					    fn merge_with_cli(mut self: Configuration, cli_opts: RunOpts) -> Configuration {
 | 
				
			||||||
        if cli_opts.verbose {
 | 
					        if cli_opts.verbose {
 | 
				
			||||||
            self.verbose = true;
 | 
					            self.verbose = true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -110,7 +110,7 @@ fn get_server_setup(file_path: &str) -> Result<ServerSetup> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn init(cli_opts: CLIOpts) -> Result<Configuration> {
 | 
					pub fn init(cli_opts: RunOpts) -> Result<Configuration> {
 | 
				
			||||||
    let config_file = cli_opts.config_file.clone();
 | 
					    let config_file = cli_opts.config_file.clone();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let config: Configuration = Figment::from(Serialized::defaults(Configuration::default()))
 | 
					    let config: Configuration = Figment::from(Serialized::defaults(Configuration::default()))
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,7 @@ use crate::{
 | 
				
			|||||||
    domain::handler::BackendHandler,
 | 
					    domain::handler::BackendHandler,
 | 
				
			||||||
    infra::{
 | 
					    infra::{
 | 
				
			||||||
        auth_service::{check_if_token_is_valid, ValidationResults},
 | 
					        auth_service::{check_if_token_is_valid, ValidationResults},
 | 
				
			||||||
 | 
					        cli::ExportGraphQLSchemaOpts,
 | 
				
			||||||
        tcp_server::AppState,
 | 
					        tcp_server::AppState,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@ -34,6 +35,26 @@ fn schema<Handler: BackendHandler + Sync>() -> Schema<Handler> {
 | 
				
			|||||||
    )
 | 
					    )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn export_schema(opts: ExportGraphQLSchemaOpts) -> anyhow::Result<()> {
 | 
				
			||||||
 | 
					    use crate::domain::sql_backend_handler::SqlBackendHandler;
 | 
				
			||||||
 | 
					    use anyhow::Context;
 | 
				
			||||||
 | 
					    let output = schema::<SqlBackendHandler>().as_schema_language();
 | 
				
			||||||
 | 
					    match opts.output_file {
 | 
				
			||||||
 | 
					        None => println!("{}", output),
 | 
				
			||||||
 | 
					        Some(path) => {
 | 
				
			||||||
 | 
					            use std::fs::File;
 | 
				
			||||||
 | 
					            use std::io::prelude::*;
 | 
				
			||||||
 | 
					            use std::path::Path;
 | 
				
			||||||
 | 
					            let path = Path::new(&path);
 | 
				
			||||||
 | 
					            let mut file =
 | 
				
			||||||
 | 
					                File::create(&path).context(format!("unable to open '{}'", path.display()))?;
 | 
				
			||||||
 | 
					            file.write_all(output.as_bytes())
 | 
				
			||||||
 | 
					                .context(format!("unable to write in '{}'", path.display()))?;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
async fn graphiql_route() -> Result<HttpResponse, Error> {
 | 
					async fn graphiql_route() -> Result<HttpResponse, Error> {
 | 
				
			||||||
    graphiql_handler("/api/graphql", None).await
 | 
					    graphiql_handler("/api/graphql", None).await
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										17
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								src/main.rs
									
									
									
									
									
								
							@ -6,7 +6,7 @@ use crate::{
 | 
				
			|||||||
        handler::BackendHandler, sql_backend_handler::SqlBackendHandler,
 | 
					        handler::BackendHandler, sql_backend_handler::SqlBackendHandler,
 | 
				
			||||||
        sql_opaque_handler::register_password, sql_tables::PoolOptions,
 | 
					        sql_opaque_handler::register_password, sql_tables::PoolOptions,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    infra::{configuration::Configuration, db_cleaner::Scheduler},
 | 
					    infra::{cli::*, configuration::Configuration, db_cleaner::Scheduler},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
use actix::Actor;
 | 
					use actix::Actor;
 | 
				
			||||||
use anyhow::{anyhow, Result};
 | 
					use anyhow::{anyhow, Result};
 | 
				
			||||||
@ -65,14 +65,13 @@ async fn run_server(config: Configuration) -> Result<()> {
 | 
				
			|||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn main() -> Result<()> {
 | 
					fn run_server_command(opts: RunOpts) -> Result<()> {
 | 
				
			||||||
    let cli_opts = infra::cli::init();
 | 
					    let config = infra::configuration::init(opts.clone())?;
 | 
				
			||||||
    let config = infra::configuration::init(cli_opts.clone())?;
 | 
					 | 
				
			||||||
    infra::logging::init(config.clone())?;
 | 
					    infra::logging::init(config.clone())?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    info!("Starting LLDAP....");
 | 
					    info!("Starting LLDAP....");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    debug!("CLI: {:#?}", cli_opts);
 | 
					    debug!("CLI: {:#?}", opts);
 | 
				
			||||||
    debug!("Configuration: {:#?}", config);
 | 
					    debug!("Configuration: {:#?}", config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    actix::run(
 | 
					    actix::run(
 | 
				
			||||||
@ -82,3 +81,11 @@ fn main() -> Result<()> {
 | 
				
			|||||||
    info!("End.");
 | 
					    info!("End.");
 | 
				
			||||||
    Ok(())
 | 
					    Ok(())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn main() -> Result<()> {
 | 
				
			||||||
 | 
					    let cli_opts = infra::cli::init();
 | 
				
			||||||
 | 
					    match cli_opts.command {
 | 
				
			||||||
 | 
					        Command::ExportGraphQLSchema(opts) => infra::graphql::api::export_schema(opts),
 | 
				
			||||||
 | 
					        Command::Run(opts) => run_server_command(opts),
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user