Commit 3196fda3 authored by C. Albrecht's avatar C. Albrecht
Browse files

ENH: WIP Argparsing + naming

parent 3506e290
......@@ -5,16 +5,82 @@
GRANT_TYPES = ("client_credentials", "password")
def configure_client_parser(parser):
# Setup a parser for file input
subparsers = parser.add_subparsers(required=True, dest="client")
client_file_parser = subparsers.add_parser(
"cfi", help="Specify client and seceret via file input.")
client_file_parser.add_argument("cfp", help="Filepath")
# Setup a parser for user input
client_ui_parser = subparsers.add_parser(
"cui", help="Specify client and secret via terminal.")
client_ui_parser.add_argument("-c",
default="admin-cli",
help="Client name: admin-cli is default")
client_ui_parser.add_argument(
"-cs", default="", help="Client secret: empty string is default")
return client_file_parser, client_ui_parser
def configure_user_parser(parser):
# Setup a parser for file input
subparsers = parser.add_subparsers(required=True, dest="user")
user_file_parser = subparsers.add_parser(
"ufi", help="Specifiy username and password via file input.")
user_file_parser.add_argument("ufp", help="Filepath to credentials.")
# Setup a parser for user input
user_ui_parser = subparsers.add_parser(
"uui", help="Specify username and password via terminal.")
user_ui_parser.add_argument("-u", required=True, help="Username")
user_ui_parser.add_argument("-up", required=True, help="User password")
return user_file_parser, user_ui_parser
def configure_credentials_parser(parser):
parser.add_argument(
"--g", choices=GRANT_TYPES, default=GRANT_TYPES[0], help="grant type"
)
parser.add_argument("--d", action="store_false", help="Prompt for client")
parser.add_argument("--s", action="store_true", help="Prompt for scope")
parser.add_argument("--c", default=None, help="Filepath to credentials")
parser.add_argument("--g",
choices=GRANT_TYPES,
default=GRANT_TYPES[0],
help=f"Specify grant type ({GRANT_TYPES[0]} is default)")
parser.add_argument("--scope",
default="email",
help="Specifiy the scope (email is default)")
cfi_parser, cui_parser = configure_client_parser(parser)
cfi_ufi_parser, cfi_uui_parser = configure_user_parser(cfi_parser)
cui_ufi_parser, cui_uui_parser = configure_user_parser(cui_parser)
return parser
def get_username_and_password(filepath=None):
def get_token_from_args(args):
grant_type = args.g
scope = args.scope
client = None
secret = None
username = None
password = None
if args.client == "cfi":
filepath = args.cfp
client, secret = parse_client_id_and_secret(filepath)
else:
client = args.c
secret = args.cs
if args.user == "ufi":
filepath = args.ufp
username, password = parse_username_and_password(filepath)
else:
username = args.u
password = args.up
token = get_access_token(grant_type, client, secret, username, password,
scope)
return str(token)
def parse_username_and_password(filepath):
username = None
password = None
if filepath is not None:
......@@ -22,14 +88,10 @@ def get_username_and_password(filepath=None):
js_object = json.load(json_f)
username = js_object["name"]
password = js_object["password"]
else:
username = input("[S3I]: Please enter your username: ")
# TODO: Use getpass
password = input("[S3I]: Please enter your password: ")
return username, password
def get_client_id_and_secret(filepath=None):
def parse_client_id_and_secret(filepath):
client_id = None
client_secret = None
if filepath is not None:
......@@ -38,50 +100,14 @@ def get_client_id_and_secret(filepath=None):
client_id = js_object.get("thingId", None)
if not client_id:
client_id = js_object.get("identifier")
client_secret = js_object.get("client_secret")
if not client_secret:
client_secret = js_object.get("secret")
else:
client_id = input("[S3I]: Please enter client id: ")
# TODO: Use getpass
client_secret = input("[S3I]: Please enter client secret: ")
return client_id, client_secret
def get_credentials_dispatch(grant_type, filepath=None):
username = ""
password = ""
secret = ""
client_id = ""
if grant_type == GRANT_TYPES[0]:
client_id, secret = get_client_id_and_secret(filepath)
else:
username, password = get_username_and_password(filepath)
return client_id, secret, username, password
def authorize_client(default_client, with_scope):
client = "admin-cli"
client_secret = ""
scope = ""
if not default_client:
tmp = input(
"[S3I]: Please enter the thing (client) you want to "
"authorize (or leave blank to default to admin client): "
)
if tmp != "":
client = tmp
client_secret = input(
"[S3I]: Please enter the thing's secret (client secret): "
)
if with_scope:
scope = input(
"[S3I]: Please enter the client scope which is requested for the "
"access token and has been assigned to the client (or leave blank): "
)
return client, client_secret, scope
def get_access_token(grant_type, client_id, client_secret, username, password, scope):
def get_access_token(grant_type, client_id, client_secret, username, password,
scope):
idp = IdentityProvider(
grant_type=grant_type,
client_id=client_id,
......@@ -92,19 +118,3 @@ def get_access_token(grant_type, client_id, client_secret, username, password, s
identity_provider_url="https://idp.s3i.vswf.dev/",
)
return idp.get_token(TokenType.ACCESS_TOKEN, scope=scope)
def get_access_token_dispatch(file_path, grant_type, ask_client, ask_scope):
access_token = None
if grant_type == GRANT_TYPES[1]:
username, password = get_username_and_password(file_path)
client_id, client_secret, scope = authorize_client(ask_client, ask_scope)
access_token = get_access_token(
grant_type, client_id, client_secret, username, password, scope
)
else:
client_id, client_secret = get_client_id_and_secret(file_path)
access_token = get_access_token(
grant_type, client_id, client_secret, "", "", ""
)
return access_token
......@@ -2,28 +2,15 @@
sys.path.append("./")
import argparse
import json
# from s3i.identity_provider import IdentityProvider, TokenType
from ml.authentication import GRANT_TYPES
from ml.authentication import get_access_token_dispatch
def create_parser():
parser = argparse.ArgumentParser()
parser.add_argument("--i", default=None, help="Filepath to credentials")
parser.add_argument("--d", action="store_false", help="Prompt for client")
parser.add_argument("--s", action="store_true", help="Prompt for scope")
parser.add_argument(
"--g", choices=GRANT_TYPES, default=GRANT_TYPES[0], help="grant type"
)
return parser
from ml.authentication import configure_credentials_parser
from ml.authentication import get_token_from_args
def main():
parser = create_parser()
parser = argparse.ArgumentParser()
parser = configure_credentials_parser(parser)
args = parser.parse_args()
access_token = get_access_token_dispatch(args.i, args.g, args.d, args.s)
print("[S3I]: Access token:\n ", access_token)
token = get_token_from_args(args)
if __name__ == "__main__":
main()
......@@ -5,10 +5,11 @@
import sys
import json
import argparse
from s3i.validation import validate_s3i_uuid
from s3i import IdentityProvider, Config, Directory, TokenType
from ml.authentication import GRANT_TYPES
from ml.authentication import get_access_token_dispatch
from s3i.repository import Repository
from ml.authentication import configure_credentials_parser
from ml.authentication import get_token_from_args
config_s_url = "https://config.s3i.vswf.dev/"
logger = logging.getLogger(__name__)
......@@ -34,7 +35,8 @@ def person_from_config_response(new_person):
def print_person(person):
print("Created a person named: {}".format(person[0]))
print("Created person has an identity (uuid): {}".format(person[3]))
print("Created DT for person has thing identity (uuid): {}".format(person[1]))
print("Created DT for person has thing identity (uuid): {}".format(
person[1]))
print("Created DT for person has secret: {}".format(person[2]))
......@@ -56,21 +58,20 @@ def delete_thing(access_token, thing_id):
def create_person(token, verbose=False):
person_name = input("Please enter the selected username for new user: ")
person_password = input("Please enter the selected password for new user: ")
person_password = input(
"Please enter the selected password for new user: ")
s3i_config = Config(server_url=config_s_url, token=token)
new_person = s3i_config.create_person(
username=person_name, password=person_password
)
new_person = s3i_config.create_person(username=person_name,
password=person_password)
if new_person.status_code == 400:
logger.critical(
"Person could not be created because some key is missing.\n"
"Shutting down."
)
"Shutting down.")
sys.exit("400")
if new_person.status_code == 409:
logger.critical(
"Person could not be create because due to a conflict.\n" "Shutting down."
)
"Person could not be create because due to a conflict.\n"
"Shutting down.")
sys.exit("409")
person = person_from_config_response(new_person)
......@@ -82,7 +83,8 @@ def create_person(token, verbose=False):
def create_thing(access_token, encrypted):
s3i_new_user_config = Config(config_s_url, token=access_token)
"""Create a new thing."""
s3i_new_user_config = Config(url, token=access_token)
response = s3i_new_user_config.create_thing(encrypted=encrypted)
res = response.json()
if response.status_code == 201:
......@@ -97,9 +99,18 @@ def print_response(response):
print(json.dumps(response, indent=4))
def show_thing(token, thing_id, url):
s3i_dir = Directory(url, token=token)
response = s3i_dir.queryThingIDBased(thing_id)
def get_ditto_instance(token, use_repo):
"""Returns an instance of class Repository if use_repo is True,
otherwise it is of type Directory."""
if use_repo:
return Repository(token=token)
else:
return Directory(token=token)
def show_thing(token, thing_id, use_repo):
ditto = get_ditto_instance(token, use_repo)
response = ditto.queryThingIDBased(thing_id)
print_response(response)
......@@ -124,21 +135,37 @@ def update_thing(thing_id, access_token, body, url):
print_response(response)
def get_identifier_from_file(filepath):
with open(filepath, "r", encoding="utf-8") as cred_file:
obj = json.load(cred_file)
thing_id = obj.get("identifier", None)
if not thing_id:
thing_id = obj.get("thingId")
return thing_id
def configure_identifier_parser(parser):
# TODO: What about multiple ids?!
group = parser.add_mutually_exclusive_group(required=True)
group.add_argument(
"--i", default=None, help="Id (in s3i format) of the thing to be printed out."
)
group.add_argument(
"--f", default=None, help="Filepath to credentials in json format."
)
"--i",
default=None,
help="Id (in s3i format) of the thing to be printed out.")
group.add_argument("--f",
default=None,
help="Filepath to credentials in json format.")
def config_ditto_parser(parser):
parser.add_argument(
"--repo",
action="store_true",
help="Executes operation on repository if set (directory otherwise).")
def config_show_parser(parser):
config_ditto_parser(parser)
configure_credentials_parser(parser)
configure_identifier_parser(parser)
parser.add_argument("--repo", action="store_true")
def config_create_parser(parser):
......@@ -147,10 +174,8 @@ def config_create_parser(parser):
def config_update_parser(parser):
configure_credentials_parser(parser)
# configure_identifier_parser(parser)
parser.add_argument(
"config", help="Path to json formatted file that specifies the thing."
)
"config", help="Path to json formatted file that specifies the thing.")
def config_delete_parser(parser):
......@@ -163,15 +188,15 @@ def create_arg_parser():
description="This script allows creation, alteration and printing "
"of things located in the s3i directory.\n"
"Structure of credential file is as follows:\n"
'{ "name" : "...","password": "..." } '
)
'{ "name" : "...","password": "..." } ')
subparsers = parser.add_subparsers(dest="command")
show_parser = subparsers.add_parser(
"show", help="Prints json representation of a thing."
)
create_parser = subparsers.add_parser("create")
"show", help="Prints json representation of a thing.")
create_parser = subparsers.add_parser("create", help="Creates a thing")
update_parser = subparsers.add_parser("update", help="Updates a thing")
delete_parser = subparsers.add_parser("delete", help="Delete a thing")
config_show_parser(show_parser)
config_create_parser(create_parser)
config_update_parser(update_parser)
......@@ -179,39 +204,35 @@ def create_arg_parser():
return parser
def get_identifier_from_file(filepath):
with open(filepath, "r", encoding="utf-8") as cred_file:
obj = json.load(cred_file)
thing_id = obj.get("identifier", None)
if not thing_id:
thing_id = obj.get("thingId")
return thing_id
def main():
# TODO: Distinguish between Repository and Directory class,
parser = create_arg_parser()
args = parser.parse_args()
token = get_access_token_dispatch(args.c, args.g, args.d, args.s)
token = get_token_from_args(args)
url = "https://dir.s3i.vswf.dev/api/2/"
if args.repo:
url = "https://ditto.s3i.vswf.dev/api/2/"
if args.command == "show":
use_repo = args.repo
thing_id = None
if args.f:
thing_id = get_identifier_from_file(args.f)
if args.i:
thing_id = args.i
show_thing(token, thing_id, url)
if validate_s3i_uuid(thing_id):
show_thing(token, thing_id, use_repo)
else:
print("{} is not a valid s3i uuid.".format(thing_id))
elif args.command == "update":
with open(args.config, "r") as config_file:
body = json.load(config_file)
update_thing(body["thingId"], token, body, url)
elif args.command == "create":
create_thing(token, encrypted=False)
create_thing(url, token, encrypted=False)
elif args.command == "delete":
delete_thing(token, args.thingId)
if __name__ == "__main__":
# """username/password for creating new user in S3I"""
main()
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment