diff --git a/utils/authc.cr b/utils/authc.cr index 4aa2360..de148bb 100644 --- a/utils/authc.cr +++ b/utils/authc.cr @@ -1,4 +1,4 @@ -require "phreak" +require "option_parser" require "ipc" require "yaml" @@ -34,144 +34,7 @@ class Context class_property args : Array(String)? = nil end -opt_help = -> (root : Phreak::RootParser) { - root.bind(short_flag: 'h', long_flag: "help", description: "Get some help.") do |sub| - puts root - exit 0 - end - root.bind(short_flag: 'v', long_flag: "verbosity", description: "Verbosity.") do |sub| - next_token = root.next_token - Baguette::Context.verbosity = next_token.to_i - Baguette::Log.info "Verbosity: #{Baguette::Context.verbosity}." - end -} - -# frequently used functions -opt_authd_login = -> (root : Phreak::RootParser) { - root.bind(short_flag: 'l', long_flag: "login", description: "Authd user login.") do |sub| - next_token = root.next_token - Context.authd_login = next_token - Baguette::Log.info "User login for authd: #{Context.authd_login}." - end - root.bind(short_flag: 'p', long_flag: "password", description: "Authd user password.") do |sub| - next_token = root.next_token - Context.authd_pass = next_token - Baguette::Log.info "User password for authd: #{Context.authd_pass}." - end - root.bind(short_flag: 'k', long_flag: "key-file", description: "Read the authd shared key from a file.") do |sub| - next_token = root.next_token - key_file = next_token - Context.shared_key = File.read(key_file).chomp - Baguette::Log.info "Key for admin operations: #{Context.shared_key}." - end -} - -# frequently used functions -opt_user_add_mod = -> (root : Phreak::RootParser) { - root.bind(short_flag: 'P', long_flag: "profile", description: "Read the user profile from a file.") do |sub| - next_token = root.next_token - file = next_token - Context.user_profile = JSON.parse(File.read file).as_h - Baguette::Log.info "Reading the user profile: #{Context.user_profile}." - end -} - -opt_simulation = -> (root : Phreak::RootParser) { - root.bind(short_flag: 's', long_flag: "simulation", description: "Don't do anything.") do |sub| - Baguette::Log.info "This is a simulation." - Context.simulation = true - end -} - -opt_args = -> (root : Phreak::RootParser) { - # With the right args, these will be interpreted as serialized data. - # See "deal-add" for example. - root.unrecognized_args do |arg| - Baguette::Log.debug "Unrecognized argument: #{arg} (adding to Context.args)" - if Context.args.nil? - Context.args = Array(String).new - end - Context.args.not_nil! << arg - end -} - -parser_get_deals = -> (root : Phreak::RootParser) { - root.missing_args do |apex| - Baguette::Log.info "Missing an argument after #{apex}" - end - -# root.unrecognized_args do |arg| -# Baguette::Log.info "Unrecognized argument: #{arg}" -# end - - opt_args.call root - - # root.banner = "Usage: [...] [other options]" - # opt_help.call root -} - - -# Parsing arguments is reading and understanding the intent, not doing anything. -Phreak.parse! do |root| - - # Admin section. - root.bind(word: "user-add", description: "user-add") do |sub| - Baguette::Log.info "user-add" - Context.command = "user-add" - parser_get_deals.call root - opt_user_add_mod.call root - end - root.bind(word: "user-mod", description: "user-mod") do |sub| - Baguette::Log.info "user-mod" - Context.command = "user-mod" - parser_get_deals.call root - opt_user_add_mod.call root - end - root.bind(word: "delete", description: "Remove user.") do |sub| - Baguette::Log.info "Remove user." - Context.command = "delete" - parser_get_deals.call root - end - root.bind(word: "set-permissions", description: "Set permissions.") do |sub| - Baguette::Log.info "Set permissions." - Context.command = "set-permissions" - parser_get_deals.call root - end - root.bind(word: "check-permissions", description: "Check permissions.") do |sub| - Baguette::Log.info "Check permissions." - Context.command = "check-permissions" - parser_get_deals.call root - end - - root.bind(word: "registration", description: "Register a user.") do |sub| - Baguette::Log.info "Register a user." - Context.command = "registration" - parser_get_deals.call root - opt_user_add_mod.call root - end - - - root.default do - Baguette::Log.info "No arguments provided" - end - - root.missing_args do |apex| - Baguette::Log.info "Missing an argument after #{apex}" - end - - opt_args.call root - - root.banner = "Usage: #{PROGRAM_NAME} [opts] command subcommand [other options]" - opt_help.call root - opt_simulation.call root - opt_authd_login.call root - - root.bind(word: "help", description: "Get some help.") do |sub| - Baguette::Log.info "Help" - Baguette::Log.info root - exit 0 - end -end +require "./parse-me" class Actions @@ -203,6 +66,9 @@ class Actions end def user_registration + # pp! authd.register login, password.not_nil!, email, phone, profile: profile + rescue e : AuthD::Exception + puts "error: #{e.message}" end def user_deletion end @@ -218,9 +84,12 @@ class Actions end profile = Context.user_profile - password = Actions.ask_password exit 1 unless password + + # pp! authd.add_user login, password.not_nil!, email, phone, profile: profile + rescue e : AuthD::Exception + puts "error: #{e.message}" end def user_mod @@ -242,6 +111,20 @@ class Actions pp! @authd.check_permission user.to_i, application, resource end + # TODO + def validate + # pp! r = authd.validate_user login.not_nil!, activation_key.not_nil! + end + def search + # pp! r = authd.search_user login.not_nil! + end + def get + # pp! authd.get_user? login + end + def ask_password_recovery + # pp! authd.ask_password_recovery login + end + def set_permissions args = Context.args if args.nil? || args.size < 4 diff --git a/utils/better-parser.cr b/utils/better-parser.cr new file mode 100644 index 0000000..42ab202 --- /dev/null +++ b/utils/better-parser.cr @@ -0,0 +1,36 @@ +require "option_parser" + +OptionParser.parse do |parser| + parser.unknown_args do |args| + if args.size != 3 + puts "usage: #{PROGRAM_NAME} [options]" + puts parser + exit 1 + end + + cli_login, email, phone = args[0..2] + end + + parser.on "-p file", "--profile file", "Read the user profile from a file." do |file| + profile_file = file + end + + parser.on "-X user-password", "--user-password pass", "Read the new user password." do |pass| + password = pass + end + + parser.on "-K file", "--key-file file", "Read the authd shared key from a file." do |file| + key_file = file + end + + parser.on "-R", "--register", "Use a registration request instead of a add-user one." do + register = true + end + + parser.on "-h", "--help", "Prints this help message." do + puts "usage: #{PROGRAM_NAME} [options]" + puts parser + exit 0 + end +end + diff --git a/utils/parse-me.cr b/utils/parse-me.cr new file mode 100644 index 0000000..4c43ede --- /dev/null +++ b/utils/parse-me.cr @@ -0,0 +1,177 @@ +require "phreak" + +opt_help = -> (root : Phreak::RootParser) { + root.bind(short_flag: 'h', long_flag: "help", description: "Get some help.") do |sub| + puts root + exit 0 + end +} + +opt_help_sub = -> (root : Phreak::Subparser) { + root.bind(short_flag: 'h', long_flag: "help", description: "Get some help.") do |sub| + puts root + exit 0 + end +} + +opt_verbosity = -> (root : Phreak::RootParser) { + root.bind(short_flag: 'v', long_flag: "verbosity", description: "Verbosity.") do |sub| + next_token = root.next_token + Baguette::Context.verbosity = next_token.to_i + Baguette::Log.info "Verbosity: #{Baguette::Context.verbosity}." + end +} + +class Blah + class_property next_token = "bla" +end + +# frequently used functions +opt_authd_login = -> (root : Phreak::Subparser) { + root.bind(short_flag: 'l', long_flag: "login", description: "Authd user login.") do |sub| + sub.grab do |sub, name| + Blah.next_token = name + end + Context.authd_login = Blah.next_token + Baguette::Log.info "User login for authd: #{Context.authd_login}." + end + root.bind(short_flag: 'p', long_flag: "password", description: "Authd user password.") do |sub| + sub.grab do |sub, name| + Blah.next_token = name + end + Context.authd_pass = Blah.next_token + Baguette::Log.info "User password for authd: #{Context.authd_pass}." + end +} + +opt_authd_admin = -> (root : Phreak::Subparser) { + root.bind(short_flag: 'k', long_flag: "key-file", description: "Read the authd shared key from a file.") do |sub| + puts "Reading the next token !!" + sub.grab do |sub, name| + puts "here reading the next token: #{name}" + Blah.next_token = name + key_file = Blah.next_token + Context.shared_key = File.read(key_file).chomp + Baguette::Log.info "Key for admin operations: #{Context.shared_key}." + end + end +} + +# frequently used functions +opt_profile = -> (root : Phreak::Subparser) { + root.bind(short_flag: 'P', long_flag: "profile", description: "Read the user profile from a file.") do |sub| + sub.grab do |sub, name| + Blah.next_token = name + end + file = Blah.next_token + Context.user_profile = JSON.parse(File.read file).as_h + Baguette::Log.info "Reading the user profile: #{Context.user_profile}." + end +} + +opt_simulation = -> (root : Phreak::RootParser) { + root.bind(short_flag: 's', long_flag: "simulation", description: "Don't do anything.") do |sub| + Baguette::Log.info "This is a simulation." + Context.simulation = true + end +} + +opt_args = -> (root : Phreak::RootParser) { + # With the right args, these will be interpreted as serialized data. + # See "deal-add" for example. + root.unrecognized_args do |arg| + Baguette::Log.debug "Unrecognized argument: #{arg} (adding to Context.args)" + if Context.args.nil? + Context.args = Array(String).new + end + Context.args.not_nil! << arg + end +} + +parser_user_add = -> (root : Phreak::Subparser) { + root.missing_args do |apex| + Baguette::Log.info "Missing an argument after #{apex}" + end + + # TODO? + root.unrecognized_args do |arg| + Baguette::Log.warning "Unrecognized argument: #{arg}" + Baguette::Log.warning "#{root.banner}" + end + + # opt_args.call root + root.banner = "Usage: user-add user-id email phone [opt]" + opt_help_sub.call root +} + +class Phreak::Subparser + property parent : Phreak::Subparser? +end + +# Parsing arguments is reading and understanding the intent, not doing anything. +Phreak.parse! do |root| + + # Admin section. + root.bind(word: "user-add", description: "user-add") do |sub| + Baguette::Log.info "user-add" + Context.command = "user-add" + parser_user_add.call sub + opt_profile.call sub + opt_authd_admin.call sub + end + + root.bind(word: "user-mod", description: "user-mod") do |sub| + Baguette::Log.info "user-mod" + Context.command = "user-mod" + opt_profile.call sub + opt_authd_admin.call sub + end + + root.bind(word: "delete", description: "Remove user.") do |sub| + Baguette::Log.info "Remove user." + Context.command = "delete" + opt_authd_admin.call sub + end + + root.bind(word: "set-permissions", description: "Set permissions.") do |sub| + Baguette::Log.info "Set permissions." + Context.command = "set-permissions" + opt_authd_admin.call sub + end + + root.bind(word: "check-permissions", description: "Check permissions.") do |sub| + Baguette::Log.info "Check permissions." + Context.command = "check-permissions" + opt_authd_admin.call sub + end + + # Do not require to be admin. + root.bind(word: "registration", description: "Register a user.") do |sub| + Baguette::Log.info "Register a user." + Context.command = "registration" + opt_profile.call sub + opt_authd_login.call sub + end + + + root.default do + Baguette::Log.info "No arguments provided" + end + + root.missing_args do |apex| + Baguette::Log.info "Missing an argument after #{apex}" + end + + opt_args.call root + + root.banner = "Usage: #{PROGRAM_NAME} [opts] command [other options]" + opt_help.call root + opt_verbosity.call root + opt_simulation.call root + + root.bind(word: "help", description: "Get some help.") do |sub| + Baguette::Log.info "Help" + Baguette::Log.info root + exit 0 + end +end