Esempio n. 1
0
def profile():
    """Accept a CMS Signed DER encoded XML data containing device information.

    This starts the DEP enrollment process. The absolute url to this endpoint should be present in the DEP profile's
    enrollment URL.

    The signed data contains a plist with the following keys:

    :UDID: The device’s UDID.
    :SERIAL: The device's Serial Number.
    :PRODUCT: The device’s product type: e.g., iPhone5,1.
    :VERSION: The OS version installed on the device: e.g., 7A182.
    :IMEI: The device’s IMEI (if available).
    :MEID: The device’s MEID (if available).
    :LANGUAGE: The user’s currently-selected language: e.g., en.

    See Also:
        - `Mobile Device Management Protocol: Request to a Profile URL <https://developer.apple.com/library/content/documentation/Miscellaneous/Reference/MobileDeviceManagementProtocolRef/4-Profile_Management/ProfileManagement.html#//apple_ref/doc/uid/TP40017387-CH7-SW242>`_.
    """
    g.plist_data = plistlib.loads(g.signed_data)
    profile = generate_enroll_profile()

    schema = ProfileSchema()
    result = schema.dump(profile)
    plist_data = dumps_none(result.data, skipkeys=True)

    return plist_data, 200, {'Content-Type': PROFILE_CONTENT_TYPE}
Esempio n. 2
0
def upload_profile():
    """Upload a custom profile using multipart/form-data I.E from an upload input.

    Encrypted profiles are not supported.

    The profiles contents will be stored using the following process:
    - For the top level profile (and each payload) there is a marshmallow schema which maps the payload keys into
        the SQLAlchemy model keys. It is also the responsibility of the marshmallow schema to be the validator for 
        uploaded profiles.
    - The profile itself is inserted as a Profile model.
    - Each payload is unmarshalled using marshmallow to a specific Payload model. Each specific model contains a join
        table inheritance to the base ``payloads`` table.

    The returned body contains a jsonapi object with details of the newly created profile and associated payload ID's.

    Note: Does not support ``application/x-www-form-urlencoded``

    TODO:
        - Support signed profiles

    :reqheader Accept: application/vnd.api+json
    :reqheader Content-Type: multipart/form-data
    :resheader Content-Type: application/vnd.api+json
    :statuscode 201: profile created
    :statuscode 400: If the request contained malformed or missing payload data.
    :statuscode 500: If something else went wrong with parsing or persisting the payload(s)
    """
    if 'file' not in request.files:
        abort(400, 'no file uploaded in request data')

    f = request.files['file']

    if not f.content_type == 'application/x-apple-aspen-config':
        abort(400, 'incorrect MIME type in request')

    try:
        data = f.read()
        plist = plistlib.loads(data)

        profile = ProfilePlistSchema().load(plist).data
    except plistlib.InvalidFileException as e:
        current_app.logger.error(e)
        abort(400, 'invalid plist format supplied')

    except BaseException as e:  # TODO: separate errors for exceptions caught here
        current_app.logger.error(e)
        abort(400, 'cannot parse the supplied profile')

    profile.data = data
    db.session.add(profile)
    db.session.commit()

    profile_schema = ProfileSchema()
    model_data = profile_schema.dump(profile).data
    resp = make_response(jsonify(model_data), 201,
                         {'Content-Type': 'application/vnd.api+json'})
    return resp
Esempio n. 3
0
def profile():
    """Accept a CMS Signed DER encoded XML data containing device information.

    This starts the DEP enrollment process.

    See Also:
        - **Request to a Profile URL** in the MDM Protocol Reference.
    """
    # TODO: Do something with signed request data???
    #g.plist_data = plistlib.loads(g.signed_data)
    profile = generate_enroll_profile()

    schema = ProfileSchema()
    result = schema.dump(profile)
    plist_data = dumps_none(result.data, skipkeys=True)

    return plist_data, 200, {'Content-Type': PROFILE_CONTENT_TYPE}