def get_credentials(self): """ Lists all stored signing credentials for authenticated user's account :return: List of dicts with needed credential info. Each stored credential gets its own dict """ url = '{}/v1/credentials/'.format(self.region['Python Web Services']) r = self.py_session.get(url) result = response_check(r, 'credentials') return result
def delete(self, group_psk): """ Permanently deletes a group from the authenticated user’s organization. :param group_psk: Unique ID assigned by EASE to the group. :result: Dict with deleted groups metadata. Dict keys are: psk, name, description """ url = '{}/v1/groups/{}'.format(self.region['Python Web Services'], group_psk) r = self.session.delete(url) result = response_check(r, 'deleted_group') return result
def create(self): """ Creates an entry in EASE for the publishing API to upload a file to. Uses a token from the auth function :return: Returns transaction ID """ self.payload['method'] = "com.apperian.eas.apps.create" r = self.php_session.post(self.region['PHP Web Services'], data=json.dumps(self.payload)) result = response_check(r, 'result', 'transactionID') return result
def get_media(self, psk): """ GET /applications/<app_psk>/related_media/ List data for a specific app :param psk: Unique ID of the app :return: Returns list of media files and their metadata in dicts. """ url = "{}/{}/related_media".format(self.base, str(psk)) r = self.session.get(url) resp = response_check(r, "related_media") return resp
def get_details(self, psk): """ GET /applications/<app_psk> List data for a specific app :param psk: Unique ID of the app :return: Returns dict of metadata about the specified application. Specify the app with app_psk. """ url = "{}/{}".format(self.base, str(psk)) r = self.session.get(url) resp = response_check(r, "application") return resp
def delete(self, psk): """ DELETE /applications/<app_psk> Deletes a specific application from your EASE organization :param psk: Unique ID for the app :return: psk of deleted app on success, dict of error on failure """ url = "{}/{}".format(self.base, psk) r = self.session.delete(url) resp = response_check(r, "deleted_application") return resp
def get_list(self): """ Lists all of the native apps in the organization you are authenticated to. Does not include webapps, or public app store links :return: List of dicts of app metadata. Dict keys are: ID, author, bundleID, longdescription, shortdescription, status, type, version, versionNotes """ self.payload['method'] = "com.apperian.eas.apps.getlist" r = self.php_session.post(self.region['PHP Web Services'], data=json.dumps(self.payload)) result = response_check(r, 'result', 'applications') return result
def add_members(self, group_psk, user_list): """ Adds a list of users to a specified group. Specify users by user_psk. :param group_psk: Unique ID assigned by EASE to the group. :param user_list: Comma-separated list of the user_psks for the users you want to add to the group. :return: Dict of lists. Dict keys are: users_failed, users_added """ url = '{}/v1/groups/{}/users'.format(self.region['Python Web Services'], group_psk) payload = json.dumps({"user_psk": user_list}) r = self.session.get(url, data=payload) result = response_check(r, 'response') return result
def update(self, group_psk, data): """ Updates data for an existing group in the authenticated user's organization. :param group_psk: Unique ID assigned by EASE to the group. :param data: Dict of group metadata to change. Required keys: group_name, group_description :return: Dict with updated metadata. Dict keys are: psk, name, description """ url = '{}/v1/groups/{}'.format(self.region['Python Web Services'], group_psk) payload = json.dumps({data}) r = self.session.put(url, data=payload) result = response_check(r, 'group') return result
def list_apps(self, group_psk): """ Returns a list of the applications that are in the specified group. :param group_psk: Unique ID assigned by EASE to the group. :return: List of dicts. See API docs for dict keys https://apidocs.apperian.com/v1/groups.html """ url = '{}/v1/groups/{}'.format(self.region['Python Web Services'], group_psk) r = self.session.get(url) result = response_check(r, 'applications') return result
def list(self): """ list of all the groups for the authenticated user’s organization. This list includes the number of users and number of applications belonging to each group. :return: List of dicts of the groups. Dict keys are: app_count, psk, user_count, name, description https://apidocs.apperian.com/v1/groups.html """ url = '%s/v1/groups/' % self.region['Python Web Services'] r = self.session.get(url) result = response_check(r, 'groups') return result
def delete_apps(self, group_psk, app_list): """ Removes applications from a group. Specify apps by app_psk :param group_psk: Unique ID assigned by EASE to the group. :param app_list: Comma-separated list of the app_psks for the applications you want to remove from the group. :return: Dict of lists. Dict keys are: apps_removed, apps_failed """ url = '{}/v1/groups/{}/applications'.format(self.region['Python Web Services'], group_psk) payload = json.dumps({"app_psk": app_list}) r = self.session.delete(url, data=payload) result = response_check(r, 'response') return result
def list_members(self, group_psk): """ Lists users who are members of a specified group. :param group_psk: Unique ID assigned by EASE to the group. :return: List of Dicts. See API docs for dict keys https://apidocs.apperian.com/v1/groups.html """ url = '{}/v1/groups/{}/users/'.format(self.region['Python Web Services'], group_psk) r = self.session.get(url) result = response_check(r, 'users_in_group') return result
def sign_application(self, app_psk, credentials_psk): """ Signs an app with the specified stored credential :param app_psk: Unique ID of app in ease. Can be found using list_apps() :param credentials_psk: Unique ID of the credentials to be used. Can be found via get_credentials() :return: """ url = '{}/v1/applications/{}/credentials/{}'.format(self.region['Python Web Services'], app_psk, credentials_psk) r = self.py_session.put(url) result = response_check(r, 'signing_status') return result
def toggle(self, app_psk, state): """ PUT /applications/<app_psk> Allows you do enable or disable and app in your account. :param app_psk: Unique ID of the app. Use the app_list_available() method :param state: Boolean Value of desired state of the app :return: Dict of request status """ url = "{}/{}".format(self.base, app_psk) r = self.session.put(url, data=json.dumps({"enabled": state})) resp = response_check(r, "update_application_result") return resp
def get_usage(self, psk, start_date, end_date): """ GET /applications/<app_psk>/stats List download and usage count for a specific app :param psk: Unique ID for the app. :param start_date: Start date for the statistical period. yyyy-mm-dd format :param end_date: End date for the statistical period. yyyy-mm-dd format :return:Returns Download Count and Usage Count for an application during a specified statistical time period. """ url = "{}/{}/stats?start_date={}&end_date={}".format(self.base, psk, start_date, end_date) r = self.session.get(url) resp = response_check(r, "app_stats") return resp
def add(self, data): """ Adds a new group to the authenticated user’s organization. :param data: Dict with metadata for group. Required keys are: group_name, group_description :return: Dict of new groups details. Dict keys are: psk, name, description https://apidocs.apperian.com/v1/groups.html """ url = '%s/v1/groups/' % self.region['Python Web Services'] payload = json.dumps(data) r = self.session.post(url, data=payload) result = response_check(r, 'group') return result
def publish(self, metadata, publishing_data): """ :param metadata: Dict of the metadata that is required to upload to ease :param publishing_data: Dict of the params needed to publish """ self.payload['method'] = 'com.apperian.eas.apps.publish' self.payload['params'].update( {"EASEmetadata": metadata, "files": {"application": publishing_data['file_id']}, "transactionID": publishing_data['transactionID'] } ) r = self.php_session.post(self.region['PHP Web Services'], data=json.dumps(self.payload)) result = response_check(r, 'result', 'appID') return result
def add_member(self, user_psk, groups): """ Adds a specified user to a list of groups. Specify groups by group_psk. :param user_psk: Unique ID assigned by EASE to the user you want to add to the list of groups :param groups: Comma-separated list of the group psks :return:Dict of lists. Dict keys are: added_groups, failed_groups https://apidocs.apperian.com/v1/groups.html """ url = '{}/v1/groups/users/{}'.format(self.region['Python Web Services'], user_psk) payload = json.dumps({"group_psk": groups}) r = self.session.get(url, data=payload) result = response_check(r, 'response') return result
def list_catalogs(self): """ GET /applications/app_catalogs List data for all app catalogs :return: Returns data about all the App Catalogs in the authenticated user's organization """ url = "{}/app_catalogs/".format(self.base) r = self.session.get(url) resp = response_check(r, "app_catalogs") if resp["status"] == 200: app_data = {} for i in resp["data"]: app_data.update({i["psk"]: i}) resp["data"] = app_data return resp
def list(self): """ GET /applications List application data about all the native applications stored in the EASE database for the authenticated user’s organization. :return: Dict with key:value pairs of the app psk and it's metadata. For example: {123:{METADATA}} """ url = self.base r = self.session.get(url) resp = response_check(r, "applications") # if resp['status'] == 200: # app_data = {} # for i in resp['resp']: # app_data.update({i['psk']: i}) # resp['resp'] = app_data return resp
def get_credentials(self, show=False): """ GET /credentials Returns data about all signing credentials stored in EASE for the authenticated user’s organization. Optional parameter to select from a list. If used it will return just the psk of the selected credential :param show: Optional, if set to True, you will select from a list of options :return: List of stored credentials for the """ url = "{}credentials".format(self.base) url = url.replace("applications", "") r = self.session.get(url) resp = response_check(r, "credentials") if show: choice = display_options(resp["result"], "credential", "description") resp["result"] = choice["psk"] return resp
def add_screenshot(self, psk, form, slot): """ POST /applications/<app_psk>/screenshots/[phone/tablet]/<slot> Upload a Screenshot for An Application :param psk: unique ID of the app :param form: Form factor of the app the screenshot it for. Valid Value: phone, tablet :param slot: Order in which the screenshot will display on the app's details page in the App Catalog. If you specify the same slot of a screenshot that is already stored for the same form factor (phone or tablet), the new file will overwrite the previously added file. Valid values: 1-5: :return: """ url = "{}/{}/screenshots/{}/{}".format(self.base, psk, form, slot) r = self.session.post(url) resp = response_check(r) return resp
def delete_screenshot(self, psk, form, slot): """ DELETE /applications/<app_psk>/screenshots/[phone/tablet]/<slot> Delete an Application Screenshot :param psk: unique ID of the app :param form: Form factor of the app the screenshot it for. Valid Value: phone, tablet :param slot: Specify the slot of the screenshot you want to delete. You can view a list with slot number of all the screenshots stored for an app by returning details about the app with the GET /applications/<app_psk> resource. Be sure to specify the correct form factor (phone or tablet) in the URL. There is a slot 1 - 5 for both phone and tablet. Valid values: 1-5 :return: """ url = "{}/{}/screenshots/{}/{}".format(self.base, psk, form, slot) r = self.session.delete(url) resp = response_check(r) return resp
def list_available(self): """ GET /applications/user List application data about all the applications available in EASE to the authenticated user. An application is available if it is assigned to a group to which the user belongs :return: Dict with key:value pairs of the app psk and it's metadata. For example: {123:{METADATA}} """ url = "{}/user".format(self.base) r = self.session.get(url) resp = response_check(r, "applications") if resp["status"] == 200: app_data = {} for i in resp["result"]: app_data.update({i["psk"]: i}) resp["result"] = app_data return resp
def get_status(self, app_psk): """ :param app_psk: :return: Returns: JSON Dict of: {"success" => TRUE, "ver_status" => $versionInfo['wrapstatus'], "ver_psk" => $versionInfo['psk'], "app_status" => $applicationInfo['status'], "apperian_wrapper_info" => $apperianWrapperInfo} """ self.payload['method'] = 'com.apperian.eas.apps.getversionstatus' self.payload['params'].update({'appPsk': app_psk}) resp = self.session.post(self.region['PHP Web Services'], data=json.dumps(self.payload)) resp = response_check(resp, 'result') return resp['result']
def update(self, app_id): self.payload['method'] = "com.apperian.eas.apps.update" self.payload['params'].update({'appID': app_id}) r = self.php_session.post(self.region['PHP Web Services'], data=json.dumps(self.payload)) result = response_check(r, 'result') return result
def gen_dynamic_policy_info(self, policies, app_psk, version_psk): r = self.session.get('{}/policies/dynamic/policy/version/{}'.format( self.region['PHP Web Services'], version_psk)) policy_response = response_check(r) if policy_response['status'] == 200: policy_response = policy_response['result'] policy_name = "MyDynamicPolicy_appPsk{0}".format(app_psk) policy_description = "Placeholder description for app psk {0}".format(app_psk) rules = [] if 'policies' not in policy_response: new_policy = True elif len(policy_response['policies']) > 0: new_policy = False else: new_policy = True policy_keys = {} if 'policies' not in policy_response: current_rules = [] elif len(policy_response['policies']) > 0: current_rules = policy_response['policies'][0]['rules'] else: current_rules = [] # Hardcoded rule name for now, in the future it will be customizable by the admin rule_names = { 'dynamicauth': "Enterprise SSO", 'remotecontrol': "Remote Control", 'datawipe': "Datawipe", 'app_usage': "App Usage", 'versioncontrol': "Version Control", 'emm_compliance': "EMM Compliance", 'crash_log': "Crash Log Collection", 'checksum_validation': "Checksum Validation", 'ibm_vpn': "IBM VPN", 'data_in_use': "Data In Use", 'data_at_rest': "Data At Rest", 'vpn_config': "VPN Config", 'iprestriction': "IP Restriction", 'rootprotection': "Root Protection", 'security_settings_check': "Security Settings Check", 'log_blocking': "Log Blocking", 'encrypted_checksum_validation': "Encrypted Checksum Validation", 'device_mdm': "Device MDM" } if not new_policy: policy_keys = {y[0]: x for x in current_rules for y in rule_names.iteritems() if x['name'] == y[1]} action_prefix = 'com.apperian.' # Dynamic Auth policy if policies['dynamicauth'] == 1: operation_pattern = "(facts['com.apperian.user.authenticated'])" actions_success = [{'id': "{0}keepcalmandcarryon.lol".format(action_prefix), 'params': ''}] actions_fail = [{'id': "{0}authenticate".format(action_prefix), 'params': ''}] dynamicauth_rule = {'name': rule_names['dynamicauth'], 'operationpattern': operation_pattern, 'description': 'Require user authentication for app access.', 'actions': {'onsuccess': actions_success, 'onfail': actions_fail}, 'ruleparams': {}} if 'dynamicauth' in policy_keys: dynamicauth_rule['psk'] = policy_keys['dynamicauth']['psk'] rules.append(dynamicauth_rule) # Remote Control Policy if policies['remotecontrol'] == 1: operation_pattern = "(true)" actions_success = [{'id': "{0}remotecontrol".format(action_prefix), 'params': ''}] actions_fail = [{'id': "{0}keepcalmandcarryon.lol".format(action_prefix), 'params': ''}] remotecontrol_rule = {'name': rule_names['remotecontrol'], 'operationpattern': operation_pattern, 'description': 'Turn remote control listening on for the app.', 'actions': {'onsuccess': actions_success, 'onfail': actions_fail}, 'ruleparams': {}} if 'remotecontrol' in policy_keys: remotecontrol_rule['psk'] = current_rules[policy_keys['remotecontrol']]['psk'] rules.append(remotecontrol_rule) # Datawipe Policy if policies['datawipe'] == 1: operation_pattern = "(facts['com.apperian.application.datawipe'])" actions_success = [{'id': "{0}datawipe".format(action_prefix), 'params': ''}] actions_fail = [{'id': "{0}keepcalmandcarryon.lol".format(action_prefix), 'params': ''}] datawipe_rule = {'name': rule_names['datawipe'], 'operationpattern': operation_pattern, 'description': 'Wipes all data from an application if requested by an administrator.', 'actions': {'onsuccess': actions_success, 'onfail': actions_fail}, 'ruleparams': {}} if 'datawipe' in policy_keys: datawipe_rule['psk'] = current_rules[policy_keys['datawipe']]['psk'] rules.append(datawipe_rule) # App Usage Policy if policies['app_usage'] == 1: operation_pattern = "(true)" # on success and failure we do the same thing which is "do nothing" actions_success = [{'id': "{0}appusage".format(action_prefix), 'params': ''}] actions_fail = [{'id': "{0}keepcalmandcarryon.lol".format(action_prefix), 'params': ''}] app_usage_rule = {'name': rule_names['app_usage'], 'operationpattern': operation_pattern, 'description': 'Tracks the application usage.', 'actions': {'onsuccess': actions_success, 'onfail': actions_fail}, 'ruleparams': {}} if 'app_usage' in policy_keys: app_usage_rule['psk'] = policy_keys['app_usage']['psk'] rules.append(app_usage_rule) # IBM VPN Policy if policies['ibm_vpn'] == 1: operation_pattern = "(true)" # on success and failure we do the same thing which is "do nothing" actions_success = [{'id': '{0}ibmvpn'.format(action_prefix), 'params': ''}] actions_fail = [{'id': '{0}keepcalmandcarryon.lol'.format(action_prefix), 'params': ''}] ibm_vpn_usage_rule = {'name': rule_names['ibm_vpn'], 'operationpattern': operation_pattern, 'description': 'Facilitates IBM VPN', 'actions': {'onsuccess': actions_success, 'onfail': actions_fail}, 'ruleparams': {}} if 'ibm_vpn' in policy_keys: ibm_vpn_usage_rule['psk'] = policy_keys['ibm_vpn']['psk'] rules.append(ibm_vpn_usage_rule) # Data in Use Encryption policy if policies['data_in_use'] == 1: operation_pattern = "(true)" # on success and failure we do the same thing which is "do nothing" actions_success = [{'id': '{0}keepcalmandcarryon.lol'.format(action_prefix), 'params': ''}] actions_fail = [{'id': '{0}keepcalmandcarryon.lol'.format(action_prefix), 'params': ''}] data_in_use_usage_rule = {'name': rule_names['data_in_use'], 'operationpattern': operation_pattern, 'description': 'Protects application data in memory', 'actions': {'onsuccess': actions_success, 'onfail': actions_fail}, 'ruleparams': {}} if 'data_in_use' in policy_keys: data_in_use_usage_rule['psk'] = policy_keys['data_in_use']['psk'] rules.append(data_in_use_usage_rule) # Data at Rest Encryption policy if policies['data_at_rest'] == 1: operation_pattern = "(true)" # on success and failure we do the same thing which is "do nothing" actions_success = [{'id': '{0}keepcalmandcarryon.lol'.format(action_prefix), 'params': ''}] actions_fail = [{'id': '{0}keepcalmandcarryon.lol'.format(action_prefix), 'params': ''}] data_at_rest_usage_rule = {'name': rule_names['data_at_rest'], 'operationpattern': operation_pattern, 'description': 'Protects application data on disk', 'actions': {'onsuccess': actions_success, 'onfail': actions_fail}, 'ruleparams': {}} if 'data_at_rest' in policy_keys: data_at_rest_usage_rule['psk'] = policy_keys['data_at_rest']['psk'] rules.append(data_at_rest_usage_rule) # VPN Configuration Policy if policies['vpn_config'] == 1: operation_pattern = "(true)" # on success and failure we do the same thing which is "do nothing" actions_success = [{'id': '{0}keepcalmandcarryon.lol'.format(action_prefix), 'params': ''}] actions_fail = [{'id': '{0}keepcalmandcarryon.lol'.format(action_prefix), 'params': ''}] vpn_config_usage_rule = {'name': rule_names['vpn_config'], 'operationpattern': operation_pattern, 'description': 'Configures VPN Apps', 'actions': {'onsuccess': actions_success, 'onfail': actions_fail}, 'ruleparams': {}} if 'vpn_config' in policy_keys: vpn_config_usage_rule['psk'] = policy_keys['vpn_config']['psk'] rules.append(vpn_config_usage_rule) # IP Restriction Policy if policies['iprestriction'] == 1: operation_pattern = "(true)" # on success and failure we do the same thing which is "do nothing" actions_success = [{'id': '{0}keepcalmandcarryon.lol'.format(action_prefix), 'params': ''}] actions_fail = [{'id': '{0}keepcalmandcarryon.lol'.format(action_prefix), 'params': ''}] iprestriction_usage_rule = {'name': rule_names['iprestriction'], 'operationpattern': operation_pattern, 'description': 'Set IP Restrictions', 'actions': {'onsuccess': actions_success, 'onfail': actions_fail}, 'ruleparams': {}} if 'iprestriction' in policy_keys: iprestriction_usage_rule['psk'] = policy_keys['iprestriction']['psk'] rules.append(iprestriction_usage_rule) # Root Protection Policy if policies['rootprotection'] == 1: operation_pattern = "(true)" # on success and failure we do the same thing which is "do nothing" actions_success = [{'id': '{0}keepcalmandcarryon.lol'.format(action_prefix), 'params': ''}] actions_fail = [{'id': '{0}keepcalmandcarryon.lol'.format(action_prefix), 'params': ''}] rootprotection_usage_rule = {'name': rule_names['rootprotection'], 'operationpattern': operation_pattern, 'description': 'Prevents rooted devices from running the app', 'actions': {'onsuccess': actions_success, 'onfail': actions_fail}, 'ruleparams': {}} if 'rootprotection' in policy_keys: rootprotection_usage_rule['psk'] = policy_keys['rootprotection']['psk'] rules.append(rootprotection_usage_rule) # Security Settings Check if policies['security_settings_check'] == 1: operation_pattern = "(true)" # on success and failure we do the same thing which is "do nothing" actions_success = [{'id': '{0}keepcalmandcarryon.lol'.format(action_prefix), 'params': ''}] actions_fail = [{'id': '{0}keepcalmandcarryon.lol'.format(action_prefix), 'params': ''}] security_settings_check_usage_rule = {'name': rule_names['security_settings_check'], 'operationpattern': operation_pattern, 'description': 'Ensures certain device-level settings are enabled', 'actions': {'onsuccess': actions_success, 'onfail': actions_fail}, 'ruleparams': {}} if 'security_settings_check' in policy_keys: security_settings_check_usage_rule['psk'] = policy_keys['security_settings_check']['psk'] rules.append(security_settings_check_usage_rule) # Log Blocking Policy if policies['log_blocking'] == 1: operation_pattern = "(true)" # on success and failure we do the same thing which is "do nothing" actions_success = [{'id': '{0}keepcalmandcarryon.lol'.format(action_prefix), 'params': ''}] actions_fail = [{'id': '{0}keepcalmandcarryon.lol'.format(action_prefix), 'params': ''}] log_blocking_usage_rule = {'name': rule_names['log_blocking'], 'operationpattern': operation_pattern, 'description': 'Prevents app from writing data to the system log', 'actions': {'onsuccess': actions_success, 'onfail': actions_fail}, 'ruleparams': {}} if 'log_blocking' in policy_keys: log_blocking_usage_rule['psk'] = policy_keys['log_blocking']['psk'] rules.append(log_blocking_usage_rule) # EMM Compliance Policy if policies['emm_compliance'] == 1: # if status is 1 run the app and do nothiing, else quit the app operation_pattern = "(facts['com.apperian.emmcompliance.status'] == 1)" actions_success = [{"id": '{0}keepcalmandcarryon.lol'.format(action_prefix), "params": ''}] actions_fail = [{"id": "{0}emmcompliance".format(action_prefix), "params": ''}] emm_compliance_rule = {"name": rule_names['emm_compliance'], "operationpattern": operation_pattern, "description": "Makes sure the app only runs when device is EMM Comnpliance.", "actions": {"onsuccess": actions_success, "onfail": actions_fail}, "ruleparams": {}} if "emm_compliance" in policy_keys: emm_compliance_rule["psk"] = policy_keys["emm_compliance"]["psk"] rules.append(emm_compliance_rule) # Crash log policy if policies['crash_log'] == 1: operation_pattern = "(true)" # on success and failure we do the same thing which is "do nothing" actions_success = [{'id': '{0}sendcrashlog'.format(action_prefix), 'params': ''}] actions_fail = [{'id': '{0}keepcalmandcarryon.lol'.format(action_prefix), 'params': ''}] crash_log_rule = {'name': rule_names['crash_log'], 'operationpattern': operation_pattern, 'description': 'Sends the latest crash data', 'actions': {'onsuccess': actions_success, 'onfail': actions_fail}, 'ruleparams': {}} if 'crash_log' in policy_keys: crash_log_rule['psk'] = policy_keys['crash_log']['psk'] rules.append(crash_log_rule) # Checksum validation policy if policies['checksum_validation'] == 1: operation_pattern = "(facts['com.apperian.apps.clientchecksumvalue'] === facts['com.apperian.apps." \ "checksumvalue']) || facts['com.apperian.apps.checksumvalue'] === 0" # on success we "do nothing" actions_success = [{'id': '{0}keepcalmandcarryon.lol'.format(action_prefix), 'params': ''}] actions_fail = [{'id': '{0}sendchecksummismatch'.format(action_prefix), 'params': ''}] checksum_validation_rule = {'name': rule_names['checksum_validation'], 'operationpattern': operation_pattern, 'description': 'Informs the server that there has been a checksum mismatch', 'actions': {'onsuccess': actions_success, 'onfail': actions_fail}, 'ruleparams': {}} if 'checksum_validation' in policy_keys: checksum_validation_rule['psk'] = policy_keys['checksum_validation']['psk'] rules.append(checksum_validation_rule) # Encrypted checksum validation policy if policies['encrypted_checksum_validation'] == 1: operation_pattern = "(true)" # on success and failure we do the same thing which is "do nothing" actions_success = [{'id': '{0}keepcalmandcarryon.lol'.format(action_prefix), 'params': ''}] actions_fail = [{'id': '{0}keepcalmandcarryon.lol'.format(action_prefix), 'params': ''}] encrypted_checksum_validation_rule = {'name': rule_names['encrypted_checksum_validation'], 'operationpattern': operation_pattern, 'description': 'Informs the server that there has been a checksum mismatch with Secure Element', 'actions': {'onsuccess': actions_success, 'onfail': actions_fail}, 'ruleparams': {}} if 'encrypted_checksum_validation' in policy_keys: encrypted_checksum_validation_rule['psk'] = policy_keys['encrypted_checksum_validation']['psk'] rules.append(encrypted_checksum_validation_rule) # Version Control Policy if policies['versioncontrol'] == 1: # If com.apperian.application.version is undefined, this is an older version of the wrapper which doesn't # have the version_psk baked in. Therefore, we use what the system has. If the app has the version psk # baked in, always use that because it's always accurate. operation_pattern = "((typeof(facts['com.apperian.application.version']) === 'undefined' && " \ "facts['com.apperian.apps.installedversion'] !== -1 && " \ "facts['com.apperian.apps.latestversion'] > " \ "facts['com.apperian.apps.installedversion']) || " \ "(facts['com.apperian.apps.latestversion'] > " \ "facts['com.apperian.application.version']))" actions_fail = [{"id": '{0}keepcalmandcarryon.lol'.format(action_prefix), "params": ''}] actions_success = [{"id": '{0}update'.format(action_prefix), "params": ''}] versioncontrol_rule = {"name": rule_names['versioncontrol'], "operationpattern": operation_pattern, "description": 'Check whether the application is up to date.', "actions": {"onsuccess": actions_success, "onfail": actions_fail}, "ruleparams": {}} if 'versioncontrol' in policy_keys: versioncontrol_rule['psk'] = policy_keys['versioncontrol']['psk'] rules.append(versioncontrol_rule) # Device MDM Policy if policies['device_mdm'] == 1: operation_pattern = "(facts['com.apperian.device.mdm_enrolled'])" actions_success = [{'id': "{0}keepcalmandcarryon.lol".format(action_prefix), 'params': ''}] actions_fail = [{ 'id': "{0}block".format(action_prefix), 'params': '{"block_reason": "This device is not enrolled in MDM. Contact your administrator to enroll your device so you can run this app."}' }] device_mdm_rule = {'name': rule_names['device_mdm'], 'operationpattern': operation_pattern, 'description': 'Makes sure the app only runs when device is under any MDM Enrollment.', 'actions': {'onsuccess': actions_success, 'onfail': actions_fail}, 'ruleparams': {}} if 'device_mdm' in policy_keys: device_mdm_rule['psk'] = policy_keys['device_mdm']['psk'] rules.append(device_mdm_rule) policy_op_pattern = Wrapper.format_policies(rules) return_policy_info = {'action': '', 'policy_data': None} try: policy_psk = policy_response.get('policies')[0].get('psk') except (IndexError, TypeError): policy_psk = None if len(rules) == 0: # if nothing is set now and nothing was set before, do nothing, we aren't changing # any policies if new_policy: return_policy_info['action'] = 'nothing' else: # Rules were set before, now nothing, therefore delete return_policy_info['action'] = 'delete' return_policy_info['policy_data'] = {'versionpsk': version_psk, 'policy_psk': policy_psk} # if new policy, don't pass any policy_psk as this constitutes a create elif new_policy: return_policy_info['action'] = 'save' return_policy_info['policy_data'] = {'name': policy_name, 'versionpsk': version_psk, 'description': policy_description, 'operationpattern': policy_op_pattern, 'rules': rules} # this is updating a policy, we reuse the existing policy_psk, and save all changes else: return_policy_info['action'] = 'save' return_policy_info['policy_data'] = {'policy_psk': policy_psk, 'name': policy_name, 'versionpsk': version_psk, 'description': policy_description, 'operationpattern': policy_op_pattern, 'rules': rules} return {'policy_data': return_policy_info}