diff --git a/local-environment/local-initializer/database_setup.py b/local-environment/local-initializer/database_setup.py deleted file mode 100644 index ffd14186..00000000 --- a/local-environment/local-initializer/database_setup.py +++ /dev/null @@ -1,113 +0,0 @@ -import bcrypt -import os -import psycopg2 -import sys -import uuid -from dotenv import load_dotenv - - -def str2bool(v): - return v.lower() in ("True") - - -load_dotenv(dotenv_path="env") - -isProduction = str2bool(os.getenv("IS_PRODUCITON")) - - -def create_schema(): - with open("./schema.sql", "r") as file: - cur.execute(file.read()) - conn.commit() - - -def store_account(): - password = str(uuid.uuid4()) if isProduction else "secret" - encodedPassword = pass_encoded(password) - print(f'default user password: {password}') - - cur.execute(f""" - INSERT INTO Account ( - account_non_expired, - account_non_locked, - credentials_non_expired, - enabled, - username, - password, - email, - email_verified, - first_name, - last_name, - birth_date, - phone, - locale, - mandatory_action - ) VALUES (True,True,True,True, - '{user_name}','{encodedPassword}','{user_name}',True,'Admin','',null,'','en','NO_ACTION') - """) - cur.execute(f"INSERT INTO ACCOUNT_ROLE (account_username, role_name) VALUES ('{user_name}','ROLE_USER')") - cur.execute(f"INSERT INTO ACCOUNT_ROLE (account_username, role_name) VALUES ('{user_name}','VAUTHENTICATOR_ADMIN')") - conn.commit() - - -def store_roles(): - cur.execute("INSERT INTO Role (name,description) VALUES ('ROLE_USER','Generic user role') ") - cur.execute("INSERT INTO Role (name,description) VALUES ('VAUTHENTICATOR_ADMIN','VAuthenticator admin role') ") - conn.commit() - - -def store_client_applications(): - client_id = str(uuid.uuid4()) if isProduction else "vauthenticator-management-ui" - print(f'client id: {client_id}') - - client_secret = str(uuid.uuid4()) if isProduction else "secret" - print(f'client secret: {client_secret}') - print(f'client_id={client_id}&client_secret={client_secret}') - - scopes = set( - ["openid", "profile", "email", "admin:reset-password", "admin:change-password", "admin:key-reader", - "admin:key-editor", - "admin:email-template-reader", "admin:email-template-writer"]) - - if isProduction: - scopes.add("mfa:always") - - serialized_scopes=','.join(scopes) - cur.execute( - f"INSERT INTO CLIENT_APPLICATION (client_app_id, secret,scopes,with_pkce,authorized_grant_types,web_server_redirect_uri,access_token_validity,refresh_token_validity,auto_approve,post_logout_redirect_uri,logout_uri) VALUES ('{client_id}','{pass_encoded(client_secret)}','false','{serialized_scopes}','AUTHORIZATION_CODE,REFRESH_TOKEN','http://local.management.vauthenticator.com:8080/login/oauth2/code/client','180','3600','true','http://local.management.vauthenticator.com:8080/secure/admin/index','http://local.management.vauthenticator.com:8080/logout')" - ) - - scopes.add("mfa:always") - serialized_scopes=','.join(scopes) - serialized_client_id=f"mfa-{client_id}" - cur.execute( - f"INSERT INTO CLIENT_APPLICATION (client_app_id, secret,scopes,with_pkce,authorized_grant_types,web_server_redirect_uri,access_token_validity,refresh_token_validity,auto_approve,post_logout_redirect_uri,logout_uri) VALUES ('{serialized_client_id}','{pass_encoded(client_secret)}','false','{serialized_scopes}','AUTHORIZATION_CODE,REFRESH_TOKEN','http://local.management.vauthenticator.com:8080/login/oauth2/code/client','180','3600','true','http://local.management.vauthenticator.com:8080/secure/admin/index','http://local.management.vauthenticator.com:8080/logout')" - ) - conn.commit() - - -def pass_encoded(password): - encode = str.encode(password) - return bcrypt.hashpw(encode, bcrypt.gensalt(12)).decode() - - -if __name__ == '__main__': - user_name = sys.argv[1] - database_host = sys.argv[2] - if os.getenv("experimental_database_persistence"): - conn = psycopg2.connect(database="postgres", - host=database_host, - user="postgres", - password="postgres", - port="5432") - cur = conn.cursor() - - create_schema() - - store_roles() - store_account() - - store_client_applications() - - cur.close() - conn.close() diff --git a/local-environment/local-initializer/init.sh b/local-environment/local-initializer/init.sh index 883326e1..265d3e00 100755 --- a/local-environment/local-initializer/init.sh +++ b/local-environment/local-initializer/init.sh @@ -12,9 +12,7 @@ echo "TABLES_SUFFIX: $TABLES_SUFFIX" echo "KMS_ENDPOINT: $KMS_ENDPOINT" echo "DYNAMO_DB_ENDPOINT: $DYNAMO_DB_ENDPOINT" -python3 key_setup.py $MASTER_KEY $TABLES_SUFFIX -python3 setup.py admin@email.com $TABLES_SUFFIX -python3 database_setup.py admin@email.com host.docker.internal +python3 setup.py admin@email.com $TABLES_SUFFIX $MASTER_KEY host.docker.internal aws iam create-access-key --user-name vauthenticator-local-dev --endpoint http://host.docker.internal:4566 > user-access-key.json echo "Local User IAM VAuthenticator AccessKeyId: "$(cat user-access-key.json | jq -r .AccessKey.AccessKeyId) diff --git a/local-environment/local-initializer/key_setup.py b/local-environment/local-initializer/key_setup.py deleted file mode 100644 index e55df793..00000000 --- a/local-environment/local-initializer/key_setup.py +++ /dev/null @@ -1,52 +0,0 @@ -import base64 -import boto3 -import os -import sys -import uuid -from dotenv import load_dotenv - -load_dotenv(dotenv_path="env") - - -def dynamodbClient(): - dynamodb_endpoint = os.getenv('DYNAMO_DB_ENDPOINT') - if dynamodb_endpoint is None: - client = boto3.resource('dynamodb') - else: - client = boto3.resource('dynamodb', endpoint_url=dynamodb_endpoint) - return client - - -def kmsClient(): - kms_endpoint = os.getenv('KMS_ENDPOINT') - print(f"kms_endpoint {kms_endpoint}") - if kms_endpoint is None: - client = boto3.client("kms") - else: - client = boto3.client('kms', endpoint_url=kms_endpoint) - return client - - -dynamodb = dynamodbClient() -kms_client = kmsClient() - - -def store_key(key_table_name, master_key): - table = dynamodb.Table(key_table_name) - key_pair = kms_client.generate_data_key_pair(KeyId=master_key, KeyPairSpec='RSA_2048') - table.put_item(Item={ - "master_key_id": key_pair["KeyId"].split("/")[1], - "key_id": str(uuid.uuid4()), - "encrypted_private_key": base64.b64encode(key_pair["PrivateKeyCiphertextBlob"]).decode(), - "public_key": base64.b64encode(key_pair["PublicKey"]).decode(), - "key_purpose": "SIGNATURE", - "key_type": "ASYMMETRIC", - "enabled": True - }) - - -if __name__ == '__main__': - input_master_key = sys.argv[1] - input_key_table_name = f'VAuthenticator_Signature_Keys{sys.argv[2]}' - - store_key(input_key_table_name, input_master_key) diff --git a/local-environment/local-initializer/setup.py b/local-environment/local-initializer/setup.py index e4f95807..fa43d650 100644 --- a/local-environment/local-initializer/setup.py +++ b/local-environment/local-initializer/setup.py @@ -3,12 +3,15 @@ import os import sys import uuid +import psycopg2 +import base64 from dotenv import load_dotenv def str2bool(v): return v.lower() in ("True") + load_dotenv(dotenv_path="env") isProduction = str2bool(os.getenv("IS_PRODUCITON")) @@ -37,14 +40,20 @@ def kmsClient(): kms_client = kmsClient() +def create_schema(): + with open("./schema.sql", "r") as file: + cur.execute(file.read()) + conn.commit() + + def store_account(): password = str(uuid.uuid4()) if isProduction else "secret" print(f'default user password: {password}') - + encodedPassword = pass_encoded(password) table = dynamodb.Table(f"VAuthenticator_Account{table_suffix}") table.put_item(Item={ "user_name": user_name, - "password": pass_encoded(password), + "password": encodedPassword, "phone": "", "birthDate": "", "locale": "en", @@ -59,6 +68,28 @@ def store_account(): "mandatory_action": "NO_ACTION", "authorities": set(["ROLE_USER", "VAUTHENTICATOR_ADMIN"]) }) + cur.execute(f""" + INSERT INTO Account ( + account_non_expired, + account_non_locked, + credentials_non_expired, + enabled, + username, + password, + email, + email_verified, + first_name, + last_name, + birth_date, + phone, + locale, + mandatory_action + ) VALUES (True,True,True,True, + '{user_name}','{encodedPassword}','{user_name}',True,'Admin','',null,'','en','NO_ACTION') + """) + cur.execute(f"INSERT INTO ACCOUNT_ROLE (account_username, role_name) VALUES ('{user_name}','ROLE_USER')") + cur.execute(f"INSERT INTO ACCOUNT_ROLE (account_username, role_name) VALUES ('{user_name}','VAUTHENTICATOR_ADMIN')") + conn.commit() def store_roles(): @@ -66,6 +97,10 @@ def store_roles(): table.put_item(Item={"role_name": "ROLE_USER", "description": "Generic user role"}) table.put_item(Item={"role_name": "VAUTHENTICATOR_ADMIN", "description": "VAuthenticator admin role"}) + cur.execute("INSERT INTO Role (name,description) VALUES ('ROLE_USER','Generic user role') ") + cur.execute("INSERT INTO Role (name,description) VALUES ('VAUTHENTICATOR_ADMIN','VAuthenticator admin role') ") + conn.commit() + def store_sso_client_applications(): client_id = str(uuid.uuid4()) if isProduction else "vauthenticator-management-ui" @@ -97,6 +132,12 @@ def store_sso_client_applications(): "post_logout_redirect_uris": "http://local.management.vauthenticator.com:8080/secure/admin/index", "logout_uris": "http://local.management.vauthenticator.com:8080/logout", }) + serialized_scopes = ','.join(scopes) + cur.execute( + f"INSERT INTO CLIENT_APPLICATION (client_app_id, secret,scopes,with_pkce,authorized_grant_types,web_server_redirect_uri,access_token_validity,refresh_token_validity,auto_approve,post_logout_redirect_uri,logout_uri) VALUES ('{client_id}','{pass_encoded(client_secret)}', '{serialized_scopes}',false,'AUTHORIZATION_CODE,REFRESH_TOKEN','http://local.management.vauthenticator.com:8080/login/oauth2/code/client','180','3600','true','http://local.management.vauthenticator.com:8080/secure/admin/index','http://local.management.vauthenticator.com:8080/logout')" + ) + + serialized_client_id = f"mfa-{client_id}" scopes.add("mfa:always") table.put_item(Item={ @@ -112,6 +153,11 @@ def store_sso_client_applications(): "post_logout_redirect_uris": "http://local.management.vauthenticator.com:8080/secure/admin/index", "logout_uris": "http://local.management.vauthenticator.com:8080/logout", }) + serialized_scopes = ','.join(scopes) + cur.execute( + f"INSERT INTO CLIENT_APPLICATION (client_app_id, secret,scopes,with_pkce,authorized_grant_types,web_server_redirect_uri,access_token_validity,refresh_token_validity,auto_approve,post_logout_redirect_uri,logout_uri) VALUES ('{serialized_client_id}','{pass_encoded(client_secret)}','{serialized_scopes}',false,'AUTHORIZATION_CODE,REFRESH_TOKEN','http://local.management.vauthenticator.com:8080/login/oauth2/code/client','180','3600','true','http://local.management.vauthenticator.com:8080/secure/admin/index','http://local.management.vauthenticator.com:8080/logout')" + ) + conn.commit() def store_client_applications(): @@ -123,18 +169,16 @@ def store_client_applications(): print(f'client_id={client_id}&client_secret={client_secret}') table = dynamodb.Table(f"VAuthenticator_ClientApplication{table_suffix}") + scopes = set( + ["openid", "profile", "email", "admin:signup", "admin:welcome", "admin:email-verify", "admin:reset-password", + "admin:change-password", "admin:key-reader", "admin:key-editor", "admin:client-app-reader", + "admin:client-app-writer", "admin:client-app-eraser", "admin:email-template-reader", + "admin:email-template-writer", "mfa:always"]) table.put_item(Item={ "client_id": client_id, "client_secret": pass_encoded(client_secret), "with_pkce": False, - "scopes": set([ - "openid", "profile", "email", - "admin:signup", "admin:welcome", "admin:email-verify", "admin:reset-password", "admin:change-password", - "admin:key-reader", "admin:key-editor", - "admin:client-app-reader", "admin:client-app-writer", "admin:client-app-eraser", - "admin:email-template-reader", "admin:email-template-writer", - "mfa:always" - ]), + "scopes": scopes, "authorized_grant_types": set(["CLIENT_CREDENTIALS"]), "web_server_redirect_uri": "", "access_token_validity": 180, @@ -143,6 +187,36 @@ def store_client_applications(): "post_logout_redirect_uris": "", "logout_uris": "", }) + serialized_scopes = ','.join(scopes) + cur.execute( + f"INSERT INTO CLIENT_APPLICATION (client_app_id, secret,scopes,with_pkce,authorized_grant_types,web_server_redirect_uri,access_token_validity,refresh_token_validity,auto_approve,post_logout_redirect_uri,logout_uri) VALUES ('{client_id}','{pass_encoded(client_secret)}','{serialized_scopes}',false,'CLIENT_CREDENTIALS','http://local.management.vauthenticator.com:8080/login/oauth2/code/client','180','3600','true','http://local.management.vauthenticator.com:8080/secure/admin/index','http://local.management.vauthenticator.com:8080/logout')" + ) + conn.commit() + + +def store_key(): + key_table_name=f'VAuthenticator_Signature_Keys{table_suffix}' + key_pair = kms_client.generate_data_key_pair(KeyId=input_master_key, KeyPairSpec='RSA_2048') + + master_key_id = key_pair["KeyId"].split("/")[1] + key_id = str(uuid.uuid4()) + encrypted_private_key = base64.b64encode(key_pair["PrivateKeyCiphertextBlob"]).decode() + public_key = base64.b64encode(key_pair["PublicKey"]).decode() + + table = dynamodb.Table(key_table_name) + table.put_item(Item={ + "master_key_id": master_key_id, + "key_id": key_id, + "encrypted_private_key": encrypted_private_key, + "public_key": public_key, + "key_purpose": "SIGNATURE", + "key_type": "ASYMMETRIC", + "enabled": True + }) + + cur.execute( + f"INSERT INTO KEYS (master_key_id, key_id, key_purpose, key_type, encrypted_private_key, public_key, enabled, key_expiration_date_timestamp) VALUES ('{master_key_id}', '{key_id}', 'SIGNATURE', 'ASYMMETRIC', '{encrypted_private_key}','{public_key}', true, 0)") + conn.commit() def pass_encoded(password): @@ -153,8 +227,22 @@ def pass_encoded(password): if __name__ == '__main__': user_name = sys.argv[1] table_suffix = sys.argv[2] + input_master_key = sys.argv[3] + database_host=sys.argv[4] + + conn = psycopg2.connect(database="postgres", + host=database_host, + user="postgres", + password="postgres", + port="5432") + cur = conn.cursor() + create_schema() store_roles() store_account() store_client_applications() store_sso_client_applications() + store_key() + + cur.close() + conn.close() diff --git a/src/main/resources/data/schema.sql b/src/main/resources/data/schema.sql index 5f691314..ee621ec5 100644 --- a/src/main/resources/data/schema.sql +++ b/src/main/resources/data/schema.sql @@ -88,7 +88,7 @@ CREATE TABLE CLIENT_APPLICATION ( client_app_id varchar(255) not null PRIMARY KEY, secret varchar(255) not null, - scopes varchar(255) not null, + scopes text not null, with_pkce boolean not null default false, authorized_grant_types varchar(255) not null, web_server_redirect_uri varchar(255) not null,