KSC Open API
Kaspersky Security Center API description
Sample. Add internal user and create an Android installation package

The Python code is presented below:

# #!/usr/bin/python -tt
# -*- coding: utf-8 -*-
"""This module presents samples of usage KlAkOAPI package to add internal user and create an Android installation package for them, which is then sent to their email address"""

import socket
import uuid
import datetime
import asyncio
from sys import platform
from KlAkOAPI.Params import KlAkArray, paramBinary, strToBin, dateTimeToStr
from KlAkOAPI.AdmServer import KlAkAdmServer
from KlAkOAPI.SecurityPolicy import KlAkSecurityPolicy
from KlAkOAPI.DataProtectionApi import KlAkDataProtectionApi
from KlAkOAPI.UserDevicesApi import KlAkUserDevicesApi
from KlAkOAPI.UserDevicesApi import KlAkUserDevicesApi
from KlAkOAPI.Error import KlAkError

class User:
    def __init__(self, name, id, email):
        self.name = name
        self.id = id
        self.email = email
        
def GetServer():
    """Connects to KSC server"""
    # server details - connect to server installed on current machine, use default port
    server_address = socket.getfqdn()
    server_port = 13299
    server_url = 'https://' + server_address + ':' + str(server_port)

    if platform == "win32":
        username = None # for Windows use NTLM by default
        password = None
    else:
        username = 'klakoapi_test' # for other platform use basic auth, user should be created on KSC server in advance
        password = 'test1234!'  # not_a_secret 
    
    SSLVerifyCert = 'C:\\ProgramData\\KasperskyLab\\adminkit\\1093\\cert\\klserver.cer'

    # create server object
    server = KlAkAdmServer.Create(server_url, username, password, verify = SSLVerifyCert)
    
    return server


async def enrollUsers(users, oUserDevicesApi):
    protSpecInfo = []
    valueParams = {
        # Protocol type for device registration (1 - MDM_IOS_PROTOCOL, 2 - KES_MOBILE_PROTOCOL)
        "KLMDM_PROTINF_PROT_ID": 2,  # KES_MOBILE_PROTOCOL
        # Operating system type of the device (1 - Android, 2 - iOS, 3 - Aurora)
        "KLMDM_PROTINF_OS_TYPE": 1,  # Android
        # Content type for device registration (1 - GENERATE_FILE_CONTENT_TYPE, 2 - GENERATE_APPLICATION_STORE_CONTENT_TYPE)
        "KLMDM_PROTINF_CONTENT_TYPE": 2,  # GENERATE_APPLICATION_STORE_CONTENT_TYPE
        # URL format for device registration (e.g. "market://details?id=com.kaspersky.kes&referrer=%s")
        "KLMDM_PROTINF_URL_FORMAT": "market://details?id=com.kaspersky.kes&referrer=%s",
        # Protocol for package download (1 - Http, 2 - Https)
        "KLMDM_ENR_PKG_LINK_PROTOCOL": 2,  # Https
        # Package download type for the device (1 - Wifi, 2 - Cellular)
        "KLMDM_ENR_PKG_DEVICE_OWNER_DOWNLOAD_TYPE": 1,  # Wifi
        # Flag to enable system app installation on the device
        "KLMDM_ENR_PKG_DEVICE_OWNER_ENABLE_SYS_APPS": True,
        # Flag to indicate that the device is the package owner
        "KLMDM_ENR_PKG_DEVICE_OWNER": False,
    }

    protSpecInfo.append({"type": "params", "value": valueParams})
    usersRequest = []
    for user in users:
        usersRequest.append({
            "type": "params",
            "value": {
                "KLMDM_ENR_USR_ID": user.id,
                "KLMDM_ENR_RECIPIENT": {
                    "type": "params",
                    "value": {"ul_wstrMail": user.email},
                },
                "KLMDM_ENR_NOTIFICATION": {
                    "type": "params",
                    "value": {
                        "NMwstrNotificationSubject": "Device Registration",
                        "NMwstrNotification": "Device Registered",
                    },
                },
            },
        })

    try:
        createResults = oUserDevicesApi.CreateEnrollmentPackagesMulti(usersRequest, 24, protSpecInfo)
        print(createResults)
    except KlAkError as e:
        print(f"Error: {e}")

def main():
    """ This sample shows how you can add internal user and create an Android installation package"""
    print (main.__doc__)

    #connect to KSC server using basic auth by default
    server = GetServer()

    oUserDevicesApi = KlAkUserDevicesApi(server)
    oDataProtectionApi = KlAkDataProtectionApi(server)
    bPasswordProtected = oDataProtectionApi.ProtectUtf16StringGlobally("test1234!").RetVal()
    
    # add users
    oUsers = KlAkSecurityPolicy(server)
    users = []
    for i in range(5):
        strUserName = f"User_{i}_{dateTimeToStr(datetime.datetime.now()).replace('-', '_').replace(':', '_')}"
        nUserID = oUsers.AddUser({"KLSPL_USER_NAME": strUserName, "KLSPL_USER_FULL_NAME": strUserName, "KLSPL_USER_PWD_ENCRYPTED": paramBinary(  (bPasswordProtected))}).RetVal()
        print ('Added user', strUserName, ', id =', nUserID)
        user = User(strUserName, nUserID, f"{strUserName}@example.com")
        users.append(user)


    asyncio.run(enrollUsers(users, oUserDevicesApi))

if __name__ == '__main__':
    main()

def generate_html_email_notification_for_add_device(locale, username):
    title = "Adding a Device"
    hello = f"Hello, {username}"
    notification_text = "You've added a new Android device."
    disregard = "Please disregard this message if you didn't add a device."
    dont_reply = "Do not reply to this message."
    kasperky_lab_copyright = "Kaspersky Lab"
    install_security = "Install"
    for_android_device = "Android Device"
    onlineHelp = "Go to Help"
    qr_code = "%ANDROID_QR_CODE%"        
    url = "%ANDROID_URL%"
    
    
    kaspersky_logo_block = """
    <table align="center" role="presentation">
        <tbody>
            <tr>
                <td align="center" style="padding-top:24px;padding-bottom:32px">
                    <img alt="Kaspersky logo" height="24" width="126" style="display:block;" src="data:image/png;base64,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"/>
                </td>
            </tr>
        </tbody>
    </table>
    """

    black_rounded_top = """
    <table align="center" width="100%" role="presentation">
        <tbody>
            <tr style="width:100%">
                <td style="background-color:#0D0D15;height:4px;width:100%;border-top-left-radius:12px;border-top-right-radius:12px"/>
            </tr>
        </tbody>
    </table>
    """

    online_help_block = """
    <table role="presentation">
        <tbody>
            <tr>
                <td style="padding-bottom:32px;padding-left:32px;padding-right:32px">
                    <p style="font-size:14px;line-height:20px;font-weight:400;color:#0D0D15;font-family:Arial;margin-top:0;margin-bottom:0">{onlineHelp}</p>
                </td>
            </tr>
        </tbody>
    </table>
    """

    footer = """
    <table align="center" role="presentation">
        <tbody>
            <tr>
                <td>
                    <table align="center" role="presentation">
                        <tbody>
                            <tr>
                                <td align="center" style="padding-top:32px;padding-bottom:60px;padding-left:32px;padding-right:32px">
                                    <p style="font-size:12px;line-height:16px;color:#69717a;font-family:Arial;margin-top:0;margin-bottom:24px">{dont_reply}</p>
                                    <p style="font-size:12px;line-height:16px;color:#69717a;font-family:Arial;margin-top:0">{kasperky_lab_copyright}</p>
                                </td>
                            </tr>
                        </tbody>
                    </table>
                </td>
            </tr>
        </tbody>
    </table>
    """

    default_margin_block = """
    <table align="center" role="presentation">
        <tbody>
            <tr>
                <td style="padding-top:16px;padding-bottom:16px"/>
            </tr>
        </tbody>
    </table>
    """

    html = f"""
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html style="background-color:#f4f7fa" dir="ltr" lang="{locale}">
        <head>
            <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/>
        </head>
        <body>
            <table align="center" role="presentation" style="max-width:37.5em;background-color:#f4f7fa">
            <tbody>
                <tr>
                    <td>
                        {kaspersky_logo_block}
                        {black_rounded_top}
                        <table align="center" role="presentation" style="background-color:#ffffff">
                            <tbody>
                                <tr>
                                    <td>
                                        <h4 style="font-size:24px;line-height:32px;color:#0D0D15;font-family:Arial;margin-bottom:32px;margin-top:0">{title}</h4>
                                        <p style="font-size:14px;line-height:20px;margin:16px 0;color:#0D0D15;font-family:Arial">{hello}</p>
                                        <p style="font-size:14px;line-height:20px;margin:16px 0;color:#0D0D15;font-family:Arial">{notification_text}</p>
                                        <p style="font-size:14px;line-height:20px;margin:16px 0;color:#0D0D15;font-family:Arial">{disregard}</p>
                                        <table align="center" role="presentation" style="border-radius:12px;background:#f4f7fa;width:100%">
                                            <tbody>
                                                <tr>
                                                    <td>
                                                        <table align="center" role="presentation">
                                                            <tbody>
                                                                <tr>
                                                                    <td align="center" style="padding-left:12px;padding-right:12px">
                                                                        <p style="font-size:16px;line-height:24px;margin:16px 0;font-weight:600;color:#0D0D15;text-align:center;font-family:Arial;margin-top:16px;margin-bottom:0">{for_android_device}</p>
                                                                    </td>
                                                                </tr>
                                                            </tbody>
                                                        </table>
                                                        <table align="center" role="presentation">
                                                            <tbody>
                                                                <tr>
                                                                    <td align="center" style="padding-left:12px;padding-right:12px;padding-top:8px;padding-bottom:8px">{qr_code}</td>
                                                                </tr>
                                                            </tbody>
                                                        </table>
                                                        <table align="center" role="presentation">
                                                            <tbody>
                                                                <tr>
                                                                    <td align="center" style="padding-bottom:12px;padding-top:0px;width:200px;height:40px;">
                                                                        <a href="{url}" style="background-color:#426FEC;border-radius:8px;color:#F5F8FB;display:inline-block;font-family:Arial;font-size:14px;line-height:20px;font-weight:500;text-align:center;text-decoration:none;width:200px;height:40px;-webkit-text-size-adjust:none;align-content:center">{install_security}</a>
                                                                    </td>
                                                                </tr>
                                                            </tbody>
                                                        </table>
                                                    </td>
                                                </tr>
                                            </tbody>
                                        </table>
                                        {online_help_block}
                                        {footer}
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    </td>
                </tr>
            </tbody>
        </table>
    </body>
</html>
    """
    return html