Skip to content

Commit

Permalink
feat: add create app with appagent cred
Browse files Browse the repository at this point in the history
  • Loading branch information
cowan-macady committed Apr 24, 2023
1 parent cfb6051 commit c76bc37
Show file tree
Hide file tree
Showing 10 changed files with 275 additions and 7 deletions.
37 changes: 37 additions & 0 deletions indykite_sdk/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,15 @@ def main():
delete_application_agent_credential_parser = subparsers.add_parser("delete_application_agent_credential")
delete_application_agent_credential_parser.add_argument("application_agent_credential_id", help="Application agent credential id")

# create_application_with_agent_credentials
create_application_with_agent_credentials_parser = subparsers.add_parser("create_application_with_agent_credentials")
create_application_with_agent_credentials_parser.add_argument("app_space_id", help="AppSpace Id (gid)")
create_application_with_agent_credentials_parser.add_argument("tenant_id", help="Tenant Id (gid)")
create_application_with_agent_credentials_parser.add_argument("application_name", help="Application name")
create_application_with_agent_credentials_parser.add_argument("application_agent_name", help="Application Agent Name")
create_application_with_agent_credentials_parser.add_argument("application_agent_credentials_name", help="Application Agent Credentials Name")
create_application_with_agent_credentials_parser.add_argument("public_key_type", help="Key type: jwk or pem")

# service_account_id
service_account_id_parser = subparsers.add_parser("service_account_id")
service_account_id_parser.add_argument("service_account_id", help="Service account id (gid)")
Expand Down Expand Up @@ -1109,6 +1118,34 @@ def main():
print("Invalid delete_application_agent_credential_response response")
return delete_application_agent_credential_response

elif command == "create_application_with_agent_credentials":
# example public key
public_key = {
"kty": "EC",
"use": "sig",
"crv": "P-256",
"x": "INNm_kk3mHAJE5gs_quJUsE5meEFX7oOsWZQtm0NrYI",
"y": "yzpgNRuGDAHbnqayGCcA60UxGkuqCYfm2JWglHlGSC4",
"alg": "ES256"
}
public_key_encoded = json.dumps(public_key, indent=2).encode('utf-8')
create_application_with_agent_credentials_response = client_config.create_application_with_agent_credentials(
args.app_space_id,
args.tenant_id,
args.application_name,
args.application_agent_name,
args.application_agent_credentials_name,
args.public_key_type,
public_key=public_key_encoded,
expire_time=None)
if create_application_with_agent_credentials_response:
print_response(create_application_with_agent_credentials_response["response_application"])
print_response(create_application_with_agent_credentials_response["response_application_agent"])
print_credential(create_application_with_agent_credentials_response["response_application_agent_credentials"])
else:
print("Invalid create_application_with_agent_credentials_response")
return create_application_with_agent_credentials_response

elif command == "service_account_id":
service_account_id = args.service_account_id
service_account = client_config.read_service_account(service_account_id)
Expand Down
1 change: 1 addition & 0 deletions indykite_sdk/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,5 +67,6 @@ def __init__(self, local=False):
from .oauth2_provider import create_oauth2_provider, read_oauth2_provider, update_oauth2_provider, delete_oauth2_provider
from .oauth2_application import create_oauth2_application, read_oauth2_application, update_oauth2_application, \
delete_oauth2_application
from .create_application_with_agent_credentials import create_application_with_agent_credentials


2 changes: 1 addition & 1 deletion indykite_sdk/config/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def create_application(self, app_space_id, name, display_name, description="", b
if not response:
return None

return CreateApplication.deserialize(response)
return CreateApplication.deserialize(response, app_space_id, name)


def update_application(self, application_id, etag, display_name, description="", bookmarks=[]):
Expand Down
2 changes: 1 addition & 1 deletion indykite_sdk/config/application_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def create_application_agent(self, application_id, name, display_name, descripti
if not response:
return None

return CreateApplicationAgent.deserialize(response)
return CreateApplicationAgent.deserialize(response, application_id, name)


def update_application_agent(self, application_agent_id, etag, display_name, description="", bookmarks=[]):
Expand Down
83 changes: 83 additions & 0 deletions indykite_sdk/config/create_application_with_agent_credentials.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
from indykite_sdk.model.create_application import CreateApplication
from indykite_sdk.model.create_application_agent import CreateApplicationAgent
from indykite_sdk.model.register_application_agent_credential import RegisterApplicationAgentCredential
from indykite_sdk.model.key_type import KeyType
import sys
import indykite_sdk.utils.logger as logger
from indykite_sdk.config import helper
from datetime import datetime


def create_application_with_agent_credentials(self,
app_space_id,
default_tenant_id,
application_name,
application_agent_name,
application_agent_credentials_name,
public_key_type,
public_key=None,
expire_time=None):
"""
create application, application agent and application credentials for a tenant in an appSpace
:param self:
:param app_space_id: string
:param default_tenant_id: string
:param application_name: string
:param application_agent_name: string
:param application_agent_credentials_name: string
:param public_key_type: jwk | pem
:param public_key: bytes | None
:param expire_time: int (number of seconds from now) | None
:return:
"""
sys.excepthook = logger.handle_excepthook
try:
application_name_id = helper.change_display_to_name(str(application_name))
response_application = self.create_application(app_space_id,
application_name_id,
str(application_name),
str(application_name),
[])
if isinstance(response_application, CreateApplication):
application_agent_name_id = helper.change_display_to_name(str(application_agent_name))
response_application_agent = self.create_application_agent(response_application.id,
application_agent_name_id,
str(application_agent_name),
str(application_agent_name),
[])
if isinstance(response_application_agent, CreateApplicationAgent):
key_types = [k.value for k in KeyType]
if public_key_type not in key_types:
raise TypeError("public_key_type must be a member of KeyType: jwk, pem")

response_application_agent_credentials = None
t = datetime.now().timestamp()
if expire_time:
expire_time = int(t) + int(expire_time)
else:
expire_time = int(t) + 3600
if public_key_type == 'jwk':
response_application_agent_credentials = self.register_application_agent_credential_jwk(
response_application_agent.id,
application_agent_credentials_name,
public_key,
expire_time,
str(default_tenant_id),
[])
elif public_key_type == 'pem':
response_application_agent_credentials = self.register_application_agent_credential_pem(
response_application_agent.id,
application_agent_credentials_name,
public_key,
expire_time,
str(default_tenant_id),
[])
if isinstance(response_application_agent_credentials, RegisterApplicationAgentCredential):
response = {"response_application": response_application,
"response_application_agent": response_application_agent,
"response_application_agent_credentials": response_application_agent_credentials}
return response
return None

except Exception as exception:
return logger.logger_error(exception)
30 changes: 29 additions & 1 deletion indykite_sdk/config/helper.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import json
import time
import uuid

import unicodedata
import re
from authlib.jose import JsonWebKey, jwt
from datetime import datetime, timedelta, timezone

Expand Down Expand Up @@ -101,3 +102,30 @@ def create_property_batch_operations(value_dict):
property_batch_ops.append(e)

return property_batch_ops


def change_display_to_name(display):
s = remove_accent_chars_regex(display)
s = s.lower()
s = re.sub(r'[àáâãäåæ]', 'a', s)
s = re.sub(r'[èéêëē]', 'e', s)
s = re.sub(r'[ìíîï]', 'i', s)
s = re.sub(r'[òóôõöøœ]', 'o', s)
s = re.sub(r'[ùúûüŭ]', 'u', s)
s = re.sub(r'[šÞ]', 's', s)
s = re.sub(r'[čç]', 'c', s)
s = re.sub(r'[ňñ]', 'n', s)
s = re.sub(r'[ř]', 'r', s)
s = re.sub(r'[ž]', 'z', s)
s = re.sub(r'[ð]', 'd', s)
s = re.sub(r'[ýÿ]', 'y', s)
for i in range(0, len(s), 1):
if s[i] == ' ':
s.replace(s[i], '-')
s = re.sub(r"[^a-z0-9-]+", "-", s)
return s


def remove_accent_chars_regex(x: str):
nfkd_form = unicodedata.normalize('NFKD', x)
return u"".join([c for c in nfkd_form if not unicodedata.combining(c)])
8 changes: 6 additions & 2 deletions indykite_sdk/model/create_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@

class CreateApplication:
@classmethod
def deserialize(cls, message):
def deserialize(cls, message, app_space_id, name):
if message is None:
return None

create_application = CreateApplication(
str(message.id),
str(app_space_id),
str(name),
timestamp_to_date(message.create_time),
timestamp_to_date(message.update_time),
str(message.etag),
Expand All @@ -17,8 +19,10 @@ def deserialize(cls, message):

return create_application

def __init__(self, id, create_time, update_time, etag, bookmark):
def __init__(self, id, app_space_id, name, create_time, update_time, etag, bookmark):
self.id = id
self.app_space_id = app_space_id
self.name = name
self.create_time = create_time
self.update_time = update_time
self.etag = etag
Expand Down
8 changes: 6 additions & 2 deletions indykite_sdk/model/create_application_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@

class CreateApplicationAgent:
@classmethod
def deserialize(cls, message):
def deserialize(cls, message, application_id, name):
if message is None:
return None

create_application_agent = CreateApplicationAgent(
str(message.id),
str(application_id),
str(name),
timestamp_to_date(message.create_time),
timestamp_to_date(message.update_time),
str(message.etag),
Expand All @@ -17,8 +19,10 @@ def deserialize(cls, message):

return create_application_agent

def __init__(self, id, create_time, update_time, etag, bookmark):
def __init__(self, id, application_id, name, create_time, update_time, etag, bookmark):
self.id = id
self.application_id = application_id
self.name = name
self.create_time = create_time
self.update_time = update_time
self.etag = etag
Expand Down
6 changes: 6 additions & 0 deletions indykite_sdk/model/key_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from enum import Enum


class KeyType(Enum):
JWK = 'jwk'
PEM = 'pem'
105 changes: 105 additions & 0 deletions tests/test_create_application_with_agent_credentials.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import time

from indykite_sdk.config import ConfigClient
from indykite_sdk.model.create_application import CreateApplication
from indykite_sdk.model.create_application_agent import CreateApplicationAgent
from indykite_sdk.model.register_application_agent_credential import RegisterApplicationAgentCredential
from helpers import data


def test_create_application_with_agent_cred_success(capsys):
client = ConfigClient()
assert client is not None

app_space_id = data.get_app_space_id()
default_tenant_id = data.get_tenant_id()
right_now = int(time.time())
application_name = "automation-application-"+str(right_now)
application_agent_name = "automation-agent-"+str(right_now)
application_agent_credentials_name = "automation-agent-cred-"+str(right_now)
public_key_type = "jwk"
expire_time = right_now + 120

response = client.create_application_with_agent_credentials(
app_space_id,
default_tenant_id,
application_name,
application_agent_name,
application_agent_credentials_name,
public_key_type,
public_key=None,
expire_time=expire_time)
captured = capsys.readouterr()

assert response is not None
assert isinstance(response["response_application"], CreateApplication)
assert isinstance(response["response_application_agent"], CreateApplicationAgent)
assert isinstance(response["response_application_agent_credentials"], RegisterApplicationAgentCredential)


def test_create_application_with_agent_cred_exists(capsys):
client = ConfigClient()
assert client is not None

client = ConfigClient()
assert client is not None

app_space_id = data.get_app_space_id()
default_tenant_id = data.get_tenant_id()
right_now = int(time.time())
application_name = "automation-application-" + str(right_now)
application_agent_name = "automation-agent-" + str(right_now)
application_agent_credentials_name = "automation-agent-cred-" + str(right_now)
public_key_type = "jwk"
expire_time = right_now + 120

response = client.create_application_with_agent_credentials(
app_space_id,
default_tenant_id,
application_name,
application_agent_name,
application_agent_credentials_name,
public_key_type,
public_key=None,
expire_time=expire_time)

response2 = client.create_application_with_agent_credentials(
app_space_id,
default_tenant_id,
application_name,
application_agent_name,
application_agent_credentials_name,
public_key_type,
public_key=None,
expire_time=expire_time)
captured = capsys.readouterr()
assert "config entity with given name already exist" in captured.err


def test_create_application_with_agent_cred_no_expire_time(capsys):
client = ConfigClient()
assert client is not None

app_space_id = data.get_app_space_id()
default_tenant_id = data.get_tenant_id()
right_now = int(time.time())
application_name = "automation-application-"+str(right_now)
application_agent_name = "automation-agent-"+str(right_now)
application_agent_credentials_name = "automation-agent-cred-"+str(right_now)
public_key_type = "pem"

response = client.create_application_with_agent_credentials(
app_space_id,
default_tenant_id,
application_name,
application_agent_name,
application_agent_credentials_name,
public_key_type,
public_key=None,
expire_time=None)
captured = capsys.readouterr()

assert response is not None
assert isinstance(response["response_application"], CreateApplication)
assert isinstance(response["response_application_agent"], CreateApplicationAgent)
assert isinstance(response["response_application_agent_credentials"], RegisterApplicationAgentCredential)

0 comments on commit c76bc37

Please sign in to comment.