Administrative tasks

Relution is executing several automatic background tasks, which are scheduled as one time jobs or recurring jobs. For example, these tasks can be used to handle the system maintenance or create various reports or notifications.

Creating organizations

You are logged in as system administrator.

To create a new organization, you need to log in to the web portal as the administrator of the system organization.

  • Navigate to Settings > Organizations

  • Click on Add and provide the required attributes in the sections

    • Organization

    • Organization Administrator

  • Click Save to save your changes

After the organization is created, you can now sign in as the organization administrator you created in the previous step. Either click on the Login as organization administrator button or sign out and sign in with the credentials you provided.

Setup multi-tenancy

The multi-tenancy use-case is primarily intended for the role Organization Administrator.

You are logged in as system administrator.

To enable a user to switch between different organizations the following steps need to be done:

  • Navigate to Settings > Groups

  • Select the desired group, e.g. Orga1_Administrator

  • Click on Edit

  • Click on button Select users or groups next to members

  • Select desired users or groups that should be members of this group

  • Click Ok

  • Click Save

The selected users and groups are now members of the organization the Orga1_Administrator group belongs to (Orga1).

If the selected users originally belong to a different organization (e.g. Orga2), the users can now switch between those two organizations. Likewise, the members of the selected groups can now switch between those two organizations.

image

The primary organization a specific user belongs to, is always the organization the user was created in. When a user signs in, they are always signed in to their primary organization.

Certificate expiration notifications

Certificate expiration is executed for all system keystores (see Relution Configuration > Security > Keysore) and all organization APNS certificates (see Relution Portal > Settings > Organization > Certificates).

For any of the above mentioned certificates a notification e-mail is created:

  • 30 days before expiration

  • 7 days before expiration

  • on the day of the expiration

  • repeatedly each 30 days after expiration

Certificate notification types:

  • System keystores are reported to the Keystore Notification Recipients (see Relution Configuration > Other > Common Relution Configuration), because system keystores are used globally and Relution support should be notified

  • APNS certificates with following UIDs com.mwaysolutions.enterprise.mway.relutionclient, com.mwaysolutions.store.relution, com.apple.mgmt.mway.mwaysolutions are reported to the Keystore Notification Recipients. Additionally Relution support should be notified

  • Custom APNS certificates are reported to the organization administrators, because these certificates are organization specific and the organization needs to take action

If the Keystore Notification Recipients are not defined, then a log entry is created instead of the e-mail.

Notes:

  • Relution System Portal can be called by logging in as System Administrator and Clicking "System Portal" on the help menu on the top right corner

  • Relution Portal can be found at https://[relutionURL]/

Using the Relution REST API (Application Programming Interface)

All functionality in Relution is available through an extensive REST API. You can use this API to call Relution from any other application or script.

Creating API Access Tokens

You need an API Access Token to access Relution through third party systems or scripts. You can create an access token by clicking on the user name in the top right corner of the Relution portal. Then click "Profile", "Access tokens", "Add".

For system admins, the Profile menu is not shown. Should you want to use APIs that require System Admin rights, log in as System Admin and type in this URL: https://<server>/#/profile to set the API key.

Sample Scripts

Here are some sample scripts that show how to use the API:

Uploading users via CSV import

User CSV file format

In the first line of the .csv file, insert a header line with a list of the desired property names. The order of the column names does not matter. Also you can you can omit properties that should not be included. The supported property names are:

userid,email,first name,last name,password,phone number,position,country,managed apple id

In addition, you can define up to 15 user-defined properties. The corresponding header columns should be named as follows: custom1-custom15.

You can copy the following example and replace the attributes with your values:

userid,email,first name,last name,password,phone number,position,country,managed apple id,custom1,custom2
user1,user1@company.com,Heinz,Ketchup,p4ssw0rd,+49234346345,user1 position,user1 country,user1.id@company.com,43,Operations
user2,user2@company.com,Heinz,Ketchup,p4ssw0rd,+49234346345,user2 position,user2 country,user2.id@company.com,24,Marketing
user3,user3@company.com,Heinz,Ketchup,p4ssw0rd,+49234346345,user3 position,user3 country,user3.id@company.com,30,HR
user4,user4@company.com,Heinz,Ketchup,p4ssw0rd,+49234346345,user4 position,user4 country,user4.id@company.com,32,Sales
user5,user5@company.com,Heinz,Ketchup,p4ssw0rd,+49234346345,user5 position,user5 country,user5.id@company.com,45,Finance
user6,user6@company.com,Heinz,Ketchup,p4ssw0rd,+49234346345,user6 position,user6 country,user6.id@company.com,30,Purchase
Uploading users over the Relution portal

Users can be imported based on a .csv file in the Relution UI under Settings > Users by clicking CSV import

  1. In first step of the wizard select one or more groups the imported users should be member of.

  2. Select your csv file. The format of the file does follow the same format as described above.

  3. The users are being imported automatically and will be shown in the users list.

Uploading users over the Relution API

To create users in Relution based on a .csv file you need to create 2 files. The first one is the users.csv file which needs to have one line for each user in the format described above.

The second file you need is a bash script file (.sh). Copy the following example and replace following attributes with your values:

  • <valid_Relution_API_Key>

  • <relution_URL>

Save both files. Additionally the script has to be made executable:

chmod +x ./relutionCSVupload.sh

Execute it in your terminal as follows:

./relutionCSVupload.sh -f users.csv
#!/bin/bash
#--------------------------------------------------------------------------------

# Headers

ACCESS_TOKEN="<valid_Relution_API_Key>"

while getopts "a:h:f:r:" opt; do
  case $opt in
    a) # apikey
    APIKEY="$OPTARG"
    ;;

    h) # host
    HOST="$OPTARG"
    ;;

    f) # File
    FILE="$OPTARG"
    ;;

    r) # Role
    ROLE="$OPTARG"
    ;;

    \?)
    echo "Unknown option -$OPTARG" >&2
    ;;
  esac
done

APIKEY=$ACCESS_TOKEN
HOST='https://<relution_URL>'
# Remember to avoid the last backslash
echo $HOST

if [[ -z $APIKEY ]]; then
  echo "Please specify an API Key (-a)"
  exit 1
fi

if [[ -z $HOST ]]; then
  echo "Please specify a Host URL (-h)"
  exit 1
fi

if [[ ! -f $FILE ]]; then
  echo "Please specify an existing csv file (-f)"
  exit 1
fi

if [[ -z $ROLE ]]; then
  ROLE=Organame%20Device%20User
fi

ERRORS=0

echo -n "Importing users from $FILE to Relution server ${HOST} as '${ROLE//%20/ }'... "
echo
echo
# On missing errors information, you can try to run the following curl expression directly to see the full output
# curl -X POST -H "Accept: application/json" -H "X-User-Access-Token: $APIKEY" -F "file=@$FILE" "$HOST/api/v1/security/users/imports?overwrite&role=$ROLE"
HTTP_ERROR=$(curl -X POST -H "Accept: application/json" -H "X-User-Access-Token: $APIKEY" -F "file=@$FILE" -sw "%{http_code}" "$HOST/api/v1/security/users/imports?overwrite&role=$ROLE")
echo $HTTP_ERROR
HTTP_ERROR=${HTTP_ERROR: -6}
HTTP_ERROR=${HTTP_ERROR: 3}

if [[ $HTTP_ERROR -ne 200 ]]; then
  ERRORS=$((ERRORS + 1))
  echo "$HTTP_ERROR"
  else
    echo "Done. No Errors."
fi

if [[ $ERRORS -gt 0 ]]; then
  echo "Error(s) during upload: ($ERRORS)"
  exit $ERRORS
fi

echo "All done."
echo

Creating a new Relution organization

#!/bin/bash
#--------------------------------------------------------------------------------

# Web service URL, change the server name as needed
SVR_URL="https://<myserver>/api/v1/security/organizations/creationWizardRequests"

# Access token of System Admin, create it by opening https://<server>/#/profile
# Open this URL in your browser while logged in as System Administrator.
# NOTE: This is not an URL you can reach through clicking through the portal!
ACCESS_TOKEN="<sysadmin_api_token>"

# HTTP Headers
ACCEPT="application/json"
ACCEPT_CHARSET="UTF-8"

# Input JSON, change values as needed
read -r -d '' JSON_BODY << 'EOF'
{
  "name": "My Orga",
  "uniqueName": "myorga",
  "orgaMailReplyTo": [],
  "passwordPolicy": {
    "allowSimplePassword": false,
    "maximumPasswordAge": 0,
    "minimumNumbersOfDigits": 0,
    "minimumNumbersOfLowerCaseLetters": 0,
    "minimumNumbersOfUpperCaseLetters": 0,
    "minimumPasswordLength": 8,
    "requiredNumbersOfSymbols": 0
  },
  "orgaName": "myorga",
  "orgaFullName": "My Orga",
  "orgaContactName": "MyOrga Admin",
  "orgaContactEMail": "myorgaadmin@mail.de",
  "orgaAdminUser": "myorgaadmin",
  "orgaAdminGivenName": "MyOrga",
  "orgaAdminSurName": "Admin",
  "orgaAdminPwd": "myorgaadminpw",
  "orgaAdminEmail": "myorgaadmin@mail.de"
}
EOF

echo "Creating new Relution Organization at $SVR_URL..."
echo

# No changes should be required beyond this line...

RESPONSE=$(curl -X POST \
  ${SVR_URL} \
  -H "X-User-Access-Token: $ACCESS_TOKEN" \
  -H "Accept: $ACCEPT" \
  -H "Accept-Charset: $ACCEPT_CHARSET" \
  -H "Content-Type: $ACCEPT" \
  --write-out " HTTP_STATUS=%{http_code}" \
  --silent \
  -d "$JSON_BODY")
if [[ $RESPONSE =~ HTTP_STATUS=([0-9]+) ]]; then
  HTTP_STATUS=${BASH_REMATCH[1]}
fi

if [[ $HTTP_STATUS -lt 200 || $HTTP_STATUS -gt 299 ]]; then
  echo " HTTP status: $HTTP_STATUS"
else
    echo "Done. No Errors."
fi
echo

Querying the devices enrolled in a specific organization

#!/bin/bash
#--------------------------------------------------------------------------------

# Web service URL, change the server name as needed
SVR_URL="https://<myserver>/api/v1/devices/baseInfo"

# Query filter, set to COMPLIANT (also possible: INACTIVE, NONCOMPUIANT, ...)
FILTER="?filter=%7B%22type%22:%22logOp%22,%22operation%22:%22AND%22,%22filters%22:%5B%7B%22type%22:%22stringEnum%22,%22fieldName%22:%22status%22,%22values%22:%5B%22COMPLIANT%22%5D%7D,%7B%22type%22:%22logOp%22,%22operation%22:%22NAND%22,%22filters%22:%5B%7B%22type%22:%22stringEnum%22,%22fieldName%22:%22status%22,%22values%22:%5B%22DELETED%22%5D%7D%5D%7D%5D%7DgetItems=true&getNonpagedCount=false"

# Access token of an Orga Admin, create it by clicking on the user name in the top right corner of the portal.
# Then click "Profile", "Access tokens", "Add".
ACCESS_TOKEN="<orga_admin_access_token>"

# HTTP Headers
ACCEPT="application/json"
ACCEPT_CHARSET="UTF-8"

function parse_json()
{
    echo $1 | \
    sed -e 's/[{}]/''/g' | \
    sed -e 's/", "/'\",\"'/g' | \
    sed -e 's/" ,"/'\",\"'/g' | \
    sed -e 's/" , "/'\",\"'/g' | \
    sed -e 's/","/'\"---SEPERATOR---\"'/g' | \
    awk -F=':' -v RS='---SEPERATOR---' "\$1~/\"$2\"/ {print}" | \
    sed -e "s/\"$2\"://" | \
    tr -d "\n\t" | \
    sed -e 's/\\"/"/g' | \
    sed -e 's/\\\\/\\/g' | \
    sed -e 's/^[ \t]*//g' | \
    sed -e 's/^"//'  -e 's/"$//'
}

# Output JSON - not used in the script, just for reference
read -r -d '' JSON_BODY << 'EOF'
{
  "errors": {
    "additionalProp1": {},
    "additionalProp2": {},
    "additionalProp3": {}
  },
  "extras": {
    "additionalProp1": {},
    "additionalProp2": {},
    "additionalProp3": {}
  },
  "message": "string",
  "results": [
    {
      "complianceNoticeCount": 0,
      "complianceViolatedCount": 0,
      "deviceId": "string",
      "enrollmentDate": 0,
      "enrollmentType": "UNKNOWN",
      "executedPolicy": {
        "name": "string",
        "policyUuid": "string",
        "policyVersionUuid": "string",
        "state": "ACTIVE",
        "version": 0
      },
      "iosAvailableUpdates": [
        {
          "downloadPercentComplete": 0,
          "downloaded": true,
          "errorChain": [
            {
              "errorCode": 0,
              "errorDomain": "string",
              "localizedDescription": "string",
              "usEnglishDescription": "string"
            }
          ],
          "installAction": "DEFAULT",
          "isDownloaded": true,
          "lastUpdateStatusTime": 0,
          "productKey": "string",
          "productVersion": {
            "majorVersion": 0,
            "minorVersion": 0,
            "patchVersion": 0
          },
          "updateStatus": "IDLE"
        }
      ],
      "iosCurrentOSUpdate": {
        "downloadPercentComplete": 0,
        "downloaded": true,
        "errorChain": [
          {
            "errorCode": 0,
            "errorDomain": "string",
            "localizedDescription": "string",
            "usEnglishDescription": "string"
          }
        ],
        "installAction": "DEFAULT",
        "isDownloaded": true,
        "lastUpdateStatusTime": 0,
        "productKey": "string",
        "productVersion": {
          "majorVersion": 0,
          "minorVersion": 0,
          "patchVersion": 0
        },
        "updateStatus": "IDLE"
      },
      "isDep": true,
      "isSupervised": true,
      "lastConnectionDate": 0,
      "manufacturer": "string",
      "model": "string",
      "msisdn": "string",
      "name": "string",
      "openActions": 0,
      "osVersion": "string",
      "ownership": "COD",
      "platform": "UNKNOWN",
      "policy": {
        "name": "string",
        "policyUuid": "string",
        "policyVersionUuid": "string",
        "state": "ACTIVE",
        "version": 0
      },
      "ruleset": {
        "name": "string",
        "rulesetUuid": "string",
        "rulesetVersionUuid": "string",
        "version": 0
      },
      "serialNumber": "string",
      "status": "COMPLIANT",
      "supervised": true,
      "userName": "string",
      "uuid": "string",
      "wifiMac": "string"
    }
  ],
  "status": "string",
  "total": 0
}
EOF

echo "Querying devices at $SVR_URL..."
echo

# No changes should be required beyond this line...

RESPONSE=$(curl -X GET \
  ${SVR_URL}${FILTER} \
  -H "X-User-Access-Token: $ACCESS_TOKEN" \
  -H "Accept: $ACCEPT" \
  -H "Accept-Charset: $ACCEPT_CHARSET" \
  -H "Content-Type: $ACCEPT" \
  --write-out " HTTP_STATUS=%{http_code}" \
  --silent \
  )
if [[ $RESPONSE =~ HTTP_STATUS=([0-9]+) ]]; then
  HTTP_STATUS=${BASH_REMATCH[1]}
fi

if [[ $HTTP_STATUS -lt 200 || $HTTP_STATUS -gt 299 ]]; then
  echo " HTTP status: $HTTP_STATUS"
else
    echo "Done. Parsing ouput..."
    echo ${RESPONSE%HTTP_STATUS*} | jq '.results[].name'
fi
echo