You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by sm...@apache.org on 2020/10/14 01:15:46 UTC
[airavata-custos] branch master updated: custos-python-sdk-demo
This is an automated email from the ASF dual-hosted git repository.
smarru pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/airavata-custos.git
The following commit(s) were added to refs/heads/master by this push:
new 2d34184 custos-python-sdk-demo
2d34184 is described below
commit 2d341849dd8ea8a7c2efec6cc73b01dfd495352e
Author: Suresh Marru <sm...@apache.org>
AuthorDate: Tue Oct 13 21:15:22 2020 -0400
custos-python-sdk-demo
---
custos-samples/configs/settings.ini | 8 +
custos-samples/samples/__init__.py | 0
custos-samples/samples/group_management_samples.py | 58 ++++
.../samples/identity_management_samples.py | 40 +++
.../samples/secret_management_samples.py | 62 ++++
.../secure_resources_with_custos_simulation.py | 361 +++++++++++++++++++++
.../samples/sharing_management_samples.py | 89 +++++
custos-samples/samples/user_management_samples.py | 66 ++++
8 files changed, 684 insertions(+)
diff --git a/custos-samples/configs/settings.ini b/custos-samples/configs/settings.ini
new file mode 100644
index 0000000..f6289bf
--- /dev/null
+++ b/custos-samples/configs/settings.ini
@@ -0,0 +1,8 @@
+[CustosServer]
+SERVER_HOST = custos.scigap.org
+SERVER_SSL_PORT = 31499
+;CLIENT_ID =
+;CLIENT_SEC =
+
+CLIENT_ID =
+CLIENT_SEC =
diff --git a/custos-samples/samples/__init__.py b/custos-samples/samples/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/custos-samples/samples/group_management_samples.py b/custos-samples/samples/group_management_samples.py
new file mode 100644
index 0000000..a0082ee
--- /dev/null
+++ b/custos-samples/samples/group_management_samples.py
@@ -0,0 +1,58 @@
+import os
+
+from custos.clients.group_management_client import GroupManagementClient
+
+from custos.transport.settings import CustosServerClientSettings
+import custos.clients.utils.utilities as utl
+
+# load root directoty
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+
+# get settings file path (settings file path reside in configs folder under home directory)
+settings_path = os.path.join(BASE_DIR, 'configs', "settings.ini")
+
+# read settings
+custos_settings = CustosServerClientSettings(configuration_file_location=settings_path)
+
+# create custos user management client
+group_management_client = GroupManagementClient(custos_settings)
+
+# obtain base 64 encoded token for tenant
+b64_encoded_custos_token = utl.get_token(custos_settings=custos_settings)
+
+
+def create_group(name, description, owner_id):
+ response = group_management_client.create_groups(token=b64_encoded_custos_token, name=name,
+ description=description,
+ owner_id=owner_id)
+ print(response)
+ return response
+
+
+def add_user_to_group(username, group_id, membership_type):
+ response = group_management_client.add_user_to_group(token=b64_encoded_custos_token,
+ username=username,
+ group_id=group_id,
+ membership_type=membership_type)
+ print(response)
+
+
+def add_child_group_to_parent_group(parent_group_id, child_group_id):
+ response = group_management_client.add_child_group(token=b64_encoded_custos_token, parent_group_id=parent_group_id,
+ child_group_id=child_group_id)
+ print(response)
+
+
+def remove_child_group(parent_group_id, child_group_id):
+ response = group_management_client.add_child_group(token=b64_encoded_custos_token, parent_group_id=parent_group_id,
+ child_group_id=child_group_id)
+ print(response)
+
+
+create_group("Group A", "Paren group", "TestUser4")
+create_group("Group B", "Child group", "TestUser4")
+
+add_user_to_group("Testuser5", "602336d5-e193-41ac-bde6-eb36a73f687e", "Member")
+
+add_child_group_to_parent_group("8b0f8241-e995-496e-a4f5-bdbde4235215", "602336d5-e193-41ac-bde6-eb36a73f687e")
+remove_child_group("8b0f8241-e995-496e-a4f5-bdbde4235215", "602336d5-e193-41ac-bde6-eb36a73f687e")
diff --git a/custos-samples/samples/identity_management_samples.py b/custos-samples/samples/identity_management_samples.py
new file mode 100644
index 0000000..d135f57
--- /dev/null
+++ b/custos-samples/samples/identity_management_samples.py
@@ -0,0 +1,40 @@
+import os
+
+from custos.clients.identity_management_client import IdentityManagementClient
+
+from custos.transport.settings import CustosServerClientSettings
+import custos.clients.utils.utilities as utl
+
+# load APIServerClient with default configuration
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+
+settings_path = os.path.join(BASE_DIR, 'configs', "settings.ini")
+
+# logger.info(settings_path)
+custos_settings = CustosServerClientSettings(configuration_file_location=settings_path)
+
+id_client = IdentityManagementClient(custos_settings)
+
+b64_encoded_custos_token = utl.get_token(custos_settings=custos_settings)
+
+
+def login(username, password):
+ resp = id_client.authenticate(token=b64_encoded_custos_token, username=username, password=password)
+ print(resp)
+
+
+def obtain_access_token_from_code(redirect_uri, code):
+ resp = id_client.token(token=b64_encoded_custos_token, redirect_uri=redirect_uri, code=code,
+ grant_type="authorization_code")
+ print(resp)
+
+
+def get_oidc_configuration(client_id):
+ response = id_client.get_oidc_configuration(token=b64_encoded_custos_token, client_id=client_id)
+ print(response)
+
+
+def logout(refresh_token):
+ response = id_client.end_user_session(token=b64_encoded_custos_token, refresh_token=refresh_token)
+ print(response)
+
diff --git a/custos-samples/samples/secret_management_samples.py b/custos-samples/samples/secret_management_samples.py
new file mode 100644
index 0000000..229a6a4
--- /dev/null
+++ b/custos-samples/samples/secret_management_samples.py
@@ -0,0 +1,62 @@
+import os
+
+from custos.clients.resource_secret_management_client import ResourceSecretManagementClient
+
+from custos.transport.settings import CustosServerClientSettings
+import custos.clients.utils.utilities as utl
+
+# load root directoty
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+
+# get settings file path (settings file path reside in configs folder under home directory)
+settings_path = os.path.join(BASE_DIR, 'configs', "settings.ini")
+
+# read settings
+custos_settings = CustosServerClientSettings(configuration_file_location=settings_path)
+
+# create custos user management client
+resource_management_client = ResourceSecretManagementClient(custos_settings)
+
+# obtain base 64 encoded token for tenant
+b64_encoded_custos_token = utl.get_token(custos_settings=custos_settings)
+
+
+def generateSSH_key(owner_id, description):
+ response = resource_management_client.add_ssh_credential(token=b64_encoded_custos_token,
+ client_id=custos_settings.CUSTOS_CLIENT_ID,
+ owner_id=owner_id,
+ description=description)
+ print(response)
+ return response
+
+
+def getSSHKey(ssh_credential_token):
+ response = resource_management_client.get_ssh_credential(token=b64_encoded_custos_token,
+ client_id=custos_settings.CUSTOS_CLIENT_ID,
+ ssh_credential_token=ssh_credential_token)
+ print(response)
+ return response
+
+
+def addPasswordCredential(owner_id, description, password):
+ response = resource_management_client.add_password_credential(token=b64_encoded_custos_token,
+ client_id=custos_settings.CUSTOS_CLIENT_ID,
+ owner_id=owner_id,
+ description=description,
+ password=password)
+ print(response)
+ return response
+
+
+def getPasswordCredential(password_credential_token):
+ response = resource_management_client.get_password_credential(token=b64_encoded_custos_token,
+ client_id=custos_settings.CUSTOS_CLIENT_ID,
+ password_credential_token=password_credential_token)
+ print(response)
+ return response
+
+
+generateSSH_key("TestUser5", "My Gateway SSH Key")
+addPasswordCredential("TestUser5", "My admin password", "asaxsxasxasx")
+getSSHKey("655e8845-9afa-4251-bb0e-c1eb42bec2fc")
+getPasswordCredential("a575726a-3e2a-41d1-ad08-06a97dbae903")
diff --git a/custos-samples/samples/secure_resources_with_custos_simulation.py b/custos-samples/samples/secure_resources_with_custos_simulation.py
new file mode 100644
index 0000000..7877a43
--- /dev/null
+++ b/custos-samples/samples/secure_resources_with_custos_simulation.py
@@ -0,0 +1,361 @@
+import os
+import json
+
+from custos.clients.user_management_client import UserManagementClient
+from custos.clients.group_management_client import GroupManagementClient
+from custos.clients.resource_secret_management_client import ResourceSecretManagementClient
+from custos.clients.sharing_management_client import SharingManagementClient
+
+from custos.transport.settings import CustosServerClientSettings
+import custos.clients.utils.utilities as utl
+
+from google.protobuf.json_format import MessageToJson
+
+# load root directoty
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+
+# get settings file path (settings file path reside in configs folder under home directory)
+settings_path = os.path.join(BASE_DIR, 'configs', "settings.ini")
+
+# read settings
+custos_settings = CustosServerClientSettings(configuration_file_location=settings_path)
+
+# create custos user management client
+user_management_client = UserManagementClient(custos_settings)
+
+# create custos group management client
+group_management_client = GroupManagementClient(custos_settings)
+
+# create custos resource secret client
+resource_secret_client = ResourceSecretManagementClient(custos_settings)
+
+# create sharing management client
+sharing_management_client = SharingManagementClient(custos_settings)
+
+# obtain base 64 encoded token for tenant
+b64_encoded_custos_token = utl.get_token(custos_settings=custos_settings)
+
+owner_id = "admin"
+
+created_groups = {}
+
+resource_ids = []
+
+
+def verifiy_admin_user():
+ response = user_management_client.get_user(token=b64_encoded_custos_token, username=owner_id)
+ user_management_client.update_user_profile(
+ token=b64_encoded_custos_token,
+ username=response.username,
+ email=response.email,
+ first_name=response.first_name,
+ last_name=response.last_name)
+
+
+def register_users(users):
+ for user in users:
+ print("Registering user: " + user['username'])
+ user_management_client.register_user(token=b64_encoded_custos_token,
+ username=user['username'],
+ first_name=user['first_name'],
+ last_name=user['last_name'],
+ password=user['password'],
+ email=user['email'],
+ is_temp_password=False)
+
+ user_management_client.enable_user(token=b64_encoded_custos_token, username=user['username'])
+
+
+def create_groups(groups):
+ for group in groups:
+ print("Creating group: " + group['name'])
+ grResponse = group_management_client.create_groups(token=b64_encoded_custos_token,
+ name=group['name'],
+ description=group['description'],
+ owner_id=group['owner_id'])
+ resp = MessageToJson(grResponse)
+ respData = json.loads(resp)
+ created_groups[respData['groups'][0]['name']] = respData['groups'][0]['id']
+
+
+def allocate_users_to_groups(user_group_mapping):
+ for usr_map in user_group_mapping:
+ group_id = created_groups[usr_map['group_name']]
+ print("Assigning user " + usr_map['username'] + " to group " + usr_map['group_name'])
+ group_management_client.add_user_to_group(token=b64_encoded_custos_token,
+ username=usr_map['username'],
+ group_id=group_id,
+ membership_type='Member'
+ )
+
+
+def allocate_child_group_to_parent_group(gr_gr_mapping):
+ for gr_map in gr_gr_mapping:
+ child_id = created_groups[gr_map['child_name']]
+ parent_id = created_groups[gr_map['parent_name']]
+ print("Assigning child group " + gr_map['child_name'] + " to parent group " + gr_map['parent_name'])
+ group_management_client.add_child_group(token=b64_encoded_custos_token,
+ parent_group_id=parent_id,
+ child_group_id=child_id)
+
+
+def create_resource():
+ response = resource_secret_client.add_ssh_credential(
+ token=b64_encoded_custos_token,
+ client_id=custos_settings.CUSTOS_CLIENT_ID,
+ owner_id='admin',
+ description='Testing SSH Key')
+ resource_ids.append(response.token)
+
+
+def create_permissions(permissions):
+ for perm in permissions:
+ print("Creating permission " + perm['id'])
+ sharing_management_client.create_permission_type(token=b64_encoded_custos_token,
+ client_id=custos_settings.CUSTOS_CLIENT_ID,
+ id=perm['id'],
+ name=perm['name'],
+ description=perm['description'])
+
+
+def create_entity_types(entity_types):
+ for type in entity_types:
+ print("Creating entity types " + type['id'])
+ sharing_management_client.create_entity_type(token=b64_encoded_custos_token,
+ client_id=custos_settings.CUSTOS_CLIENT_ID,
+ id=type['id'],
+ name=type['name'],
+ description=type['description'])
+
+
+def register_resources(resources):
+ for resource in resources:
+ print("Register resources " + resource['id'])
+ sharing_management_client.create_entity(token=b64_encoded_custos_token,
+ client_id=custos_settings.CUSTOS_CLIENT_ID,
+ id=resource['id'],
+ name=resource['name'],
+ description=resource['description'],
+ owner_id=resource['user_id'],
+ type=resource['type'],
+ parent_id='')
+
+
+def share_resource_with_user(sharings):
+ for shr in sharings:
+ print("Sharing entity " + shr['entity_id'] + " with user " + shr['user_id'] + " with permission " + shr[
+ 'permission_type'])
+ sharing_management_client.share_entity_with_users(token=b64_encoded_custos_token,
+ client_id=custos_settings.CUSTOS_CLIENT_ID,
+ entity_id=shr['entity_id'],
+ permission_type=shr['permission_type'],
+ user_id=shr['user_id']
+ )
+
+
+def share_resource_with_group(gr_sharings):
+ for shr in gr_sharings:
+ group_id = created_groups[shr['group_name']]
+ print("Sharing entity " + shr['entity_id'] + " with group " + shr['group_name'] + " with permission " + shr[
+ 'permission_type'])
+ sharing_management_client.share_entity_with_groups(token=b64_encoded_custos_token,
+ client_id=custos_settings.CUSTOS_CLIENT_ID,
+ entity_id=shr['entity_id'],
+ permission_type=shr['permission_type'],
+ group_id=group_id)
+
+
+def check_user_permissions(users):
+ for user in users:
+ access = sharing_management_client.user_has_access(token=b64_encoded_custos_token,
+ client_id=custos_settings.CUSTOS_CLIENT_ID,
+ entity_id=resource_ids[0],
+ permission_type="READ",
+ user_id=user['username'])
+ usr = user['username']
+ print("Access for user " + usr + " : " + str(access))
+
+
+users = [
+ {
+ 'username': 'UserA',
+ 'first_name': 'Aaron',
+ 'last_name': 'Bob',
+ 'password': '1234',
+ 'email': 'a@gmail.com'
+ },
+ {
+ 'username': 'UserB',
+ 'first_name': 'Baron',
+ 'last_name': 'Bob',
+ 'password': '1234',
+ 'email': 'b@gmail.com'
+ },
+ {
+ 'username': 'UserC',
+ 'first_name': 'Caron',
+ 'last_name': 'Bob',
+ 'password': '1234',
+ 'email': 'c@gmail.com'
+ },
+ {
+ 'username': 'UserD',
+ 'first_name': 'Daron',
+ 'last_name': 'Bob',
+ 'password': '1234',
+ 'email': 'd@gmail.com'
+ },
+ {
+ 'username': 'UserE',
+ 'first_name': 'Earon',
+ 'last_name': 'Bob',
+ 'password': '1234',
+ 'email': 'e@gmail.com'
+ },
+ {
+ 'username': 'UserF',
+ 'first_name': 'Faron',
+ 'last_name': 'Bob',
+ 'password': '1234',
+ 'email': 'f@gmail.com'
+ }
+]
+
+groups = [
+ {
+ 'name': 'groupA',
+ 'description': 'Group L',
+ 'owner_id': 'admin'
+ },
+ {
+ 'name': 'groupB',
+ 'description': 'Group B',
+ 'owner_id': 'admin'
+ },
+ {
+ 'name': 'groupC',
+ 'description': 'Group C',
+ 'owner_id': 'admin'
+ }
+]
+
+user_group_mapping = [
+ {
+ 'group_name': 'groupA',
+ 'username': 'UserA'
+ },
+ {
+ 'group_name': 'groupA',
+ 'username': 'UserB'
+ },
+ {
+ 'group_name': 'groupB',
+ 'username': 'UserC'
+ },
+ {
+ 'group_name': 'groupB',
+ 'username': 'UserD'
+ },
+ {
+ 'group_name': 'groupC',
+ 'username': 'UserE'
+ },
+ {
+ 'group_name': 'groupC',
+ 'username': 'UserF'
+ }
+]
+
+child_gr_parent_gr_mapping = [
+ {
+ "child_name": "groupB",
+ "parent_name": "groupA"
+ }
+]
+
+permissions = [
+ {
+ 'id': 'OWNER',
+ 'name': 'OWNER',
+ 'description': 'Owner permission'
+ },
+ {
+ 'id': 'READ',
+ 'name': 'READ',
+ 'description': 'Read permission'
+ },
+ {
+ 'id': 'WRITE',
+ 'name': 'WRITE',
+ 'description': 'WRITE permission'
+ }
+]
+entity_types = [
+ {
+ 'id': 'SECRET',
+ 'name': 'SECRET',
+ 'description': 'SECRET Keys'
+ }
+]
+
+verifiy_admin_user()
+
+# Register users
+register_users(users)
+
+# Create groups
+create_groups(groups)
+
+# Allocate users to groups
+allocate_users_to_groups(user_group_mapping)
+
+# Allocate child groups to parent group
+allocate_child_group_to_parent_group(child_gr_parent_gr_mapping)
+
+# Creare resource
+create_resource()
+
+# Create permissions
+create_permissions(permissions)
+
+# Create entity types
+create_entity_types(entity_types)
+
+resources = [
+ {
+ 'id': resource_ids[0],
+ 'name': 'SECRET',
+ 'description': 'Register SSH Key Id',
+ 'user_id': 'admin',
+ 'type': 'SECRET'
+ }
+]
+
+sharings = [
+ {
+ "entity_id": resource_ids[0],
+ "permission_type": "READ",
+ "type": "SECRET",
+ "user_id": "UserF"
+ }
+]
+
+gr_sharings = [{
+
+ "entity_id": resource_ids[0],
+ "permission_type": "READ",
+ "type": "SSH_KEY",
+ "group_name": 'groupA'
+}]
+
+# Register resources
+register_resources(resources)
+
+# Share resource with users
+share_resource_with_user(sharings)
+
+# Share resource with group
+share_resource_with_group(gr_sharings)
+
+# Check user permissions
+check_user_permissions(users)
diff --git a/custos-samples/samples/sharing_management_samples.py b/custos-samples/samples/sharing_management_samples.py
new file mode 100644
index 0000000..d94eeae
--- /dev/null
+++ b/custos-samples/samples/sharing_management_samples.py
@@ -0,0 +1,89 @@
+import os
+
+from custos.clients.sharing_management_client import SharingManagementClient
+
+from custos.transport.settings import CustosServerClientSettings
+import custos.clients.utils.utilities as utl
+
+# load root directoty
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+
+# get settings file path (settings file path reside in configs folder under home directory)
+settings_path = os.path.join(BASE_DIR, 'configs', "settings.ini")
+
+# read settings
+custos_settings = CustosServerClientSettings(configuration_file_location=settings_path)
+
+# create custos user management client
+sharing_management_client = SharingManagementClient(custos_settings)
+
+# obtain base 64 encoded token for tenant
+b64_encoded_custos_token = utl.get_token(custos_settings=custos_settings)
+
+
+def create_permission_type(id, name, description):
+ response = sharing_management_client.create_permission_type(token=b64_encoded_custos_token,
+ client_id=custos_settings.CUSTOS_CLIENT_ID,
+ id=id,
+ name=name,
+ description=description)
+ print(response)
+
+
+def create_entity_type(id, name, description):
+ response = sharing_management_client.create_entity_type(token=b64_encoded_custos_token,
+ client_id=custos_settings.CUSTOS_CLIENT_ID,
+ id=id,
+ name=name,
+ description=description)
+ print(response)
+
+
+def create_entity(id, name, description, owner_id, type):
+ response = sharing_management_client.create_entity(token=b64_encoded_custos_token,
+ client_id=custos_settings.CUSTOS_CLIENT_ID,
+ id=id,
+ name=name,
+ description=description,
+ owner_id=owner_id,
+ type=type,
+ parent_id='')
+ print(response)
+
+
+def share_entity_with_user(entity_id, permission_type, user_id):
+ response = sharing_management_client.share_entity_with_users(token=b64_encoded_custos_token,
+ client_id=custos_settings.CUSTOS_CLIENT_ID,
+ entity_id=entity_id,
+ permission_type=permission_type,
+ user_id=user_id)
+ print(response)
+
+
+def share_entity_with_group(entity_id, permission_type, group_id):
+ response = sharing_management_client.share_entity_with_groups(token=b64_encoded_custos_token,
+ client_id=custos_settings.CUSTOS_CLIENT_ID,
+ entity_id=entity_id,
+ permission_type=permission_type,
+ group_id=group_id)
+ print(response)
+
+
+def check_user_has_access(entity_id, permission_type, user_id):
+ response = sharing_management_client.user_has_access(token=b64_encoded_custos_token,
+ client_id=custos_settings.CUSTOS_CLIENT_ID,
+ entity_id=entity_id,
+ permission_type=permission_type,
+ user_id=user_id)
+ print(response)
+
+
+# create_permission_type('RW', 'Read and Write', 'Read write permissions')
+# create_entity_type("CRED_TOKEN", "Credential Token", "This is credential token")
+
+create_entity('655e8845-9afa-4251-bb0e-c1ebasasx42bec2fcASD', 'Password Token', 'This is password token', 'TestUser5',
+ 'CRED_TOKEN')
+# share_entity_with_user('655e8845-9afa-4251-bb0e-c1eb42bec2fc', 'RW', 'TestUser4')
+# share_entity_with_group('655e8845-9afa-4251-bb0e-c1eb42bec2fc', 'RW', '602336d5-e193-41ac-bde6-eb36a73f687e')
+#
+# check_user_has_access('655e8845-9afa-4251-bb0e-c1eb42bec2fc', 'RW', 'TestUser4')
diff --git a/custos-samples/samples/user_management_samples.py b/custos-samples/samples/user_management_samples.py
new file mode 100644
index 0000000..6b0b489
--- /dev/null
+++ b/custos-samples/samples/user_management_samples.py
@@ -0,0 +1,66 @@
+import os
+
+from custos.clients.user_management_client import UserManagementClient
+
+from custos.transport.settings import CustosServerClientSettings
+import custos.clients.utils.utilities as utl
+
+# load root directoty
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+
+#get settings file path (settings file path reside in configs folder under home directory)
+settings_path = os.path.join(BASE_DIR, 'configs', "settings.ini")
+
+# read settings
+custos_settings = CustosServerClientSettings(configuration_file_location=settings_path)
+
+# create custos user management client
+user_management_client = UserManagementClient(custos_settings)
+
+# obtain base 64 encoded token for tenant
+b64_encoded_custos_token = utl.get_token(custos_settings=custos_settings)
+
+
+def register_user():
+ response = user_management_client.register_user(token=b64_encoded_custos_token,
+ username="TestUser5",
+ first_name="Watson",
+ last_name="Christe",
+ password="1234",
+ email="wat@gmail.com",
+ is_temp_password=False)
+ print(response)
+
+
+def enable_user():
+ response = user_management_client.enable_user(token=b64_encoded_custos_token,
+ username="TestUser5")
+ print(response)
+
+
+def get_user():
+ response = user_management_client.get_user(token=b64_encoded_custos_token,
+ username="TestUser5")
+ print(response)
+
+
+def update_user():
+ response = user_management_client.update_user_profile(token=b64_encoded_custos_token,
+ username="TestUser5",
+ first_name="Jimmy",
+ last_name="Jhon",
+ email="wat@gmail.com")
+ print(response)
+
+
+def find_users():
+ response = user_management_client.find_users(token=b64_encoded_custos_token, offset=0, limit=1,
+ username="TestUser5")
+ print(response)
+
+
+register_user()
+enable_user()
+get_user()
+update_user()
+find_users()