示例#1
0
def suppressed_emails(request):

    params = dict(params_from_request(request).copy())

    try:
        mac_verify(params)
    except Exception as exc:
        raise BadRequestError(str(exc))

    try:
        decrypted_str = decrypt(params['token'])
        decrypted_json = json.loads(decrypted_str)
    except Exception as exc:
        log.exception(repr(exc))
        raise BadRequestError()

    if decrypted_json.get('key') != Portal.get_singleton().external_api_key:
        raise NotFoundError()

    action = decrypted_json.get('action')
    if not action:
        raise RequiredParameterMissingError('action')

    if action == 'delete':
        Notification.objects(suppressed=True).delete()
    elif action == 'unsuppress':
        Notification.objects.update(suppressed=False)
    else:
        raise BadRequestError('Action "%s" not supported' % action)

    return Response("OK", 200)
示例#2
0
def confirm_unsubscription(request):
    """
    Tags: notifications
    ---
    Creates a new notification override.
    Accepts an override creation request and adds the corresponding override,
    creating a new override policy if it does not exist.
    ---
    """
    params = params_from_request(request)
    try:
        decrypted_str = decrypt(params["token"])
        decrypted_json = json.loads(decrypted_str)
    except Exception as exc:
        log.exception(repr(exc))
        raise BadRequestError(ERROR_MSG)

    option = params.get("option")
    if not option:
        raise RequiredParameterMissingError("option")

    try:
        mac_verify(decrypted_json)
    except Exception as exc:
        raise BadRequestError(exc)

    try:
        org_id = decrypted_json["org_id"]
    except KeyError as err:
        log.exception(repr(err))
        raise BadRequestError(ERROR_MSG)

    try:
        org = Organization.objects.get(id=org_id)
    except Organization.DoesNotExist:
        raise OrganizationNotFound()

    rid = decrypted_json.get("rid", "")
    rtype = decrypted_json.get("rtype", "")
    email = decrypted_json.get("email")
    user_id = decrypted_json.get("user_id")
    channel = decrypted_json.get("channel")
    if not (email or user_id) and channel in CHANNELS:
        log.critical("Got invalid/insufficient data: %s", decrypted_json)
        raise BadRequestError(ERROR_MSG)

    qr = me.Q(owner=org)
    qr &= me.Q(user_id=user_id) if user_id else me.Q(email=email)
    np = UserNotificationPolicy.objects(qr).first()
    if not np:
        np = UserNotificationPolicy(owner=org, user_id=user_id, email=email)
    for override in np.overrides:
        if override.blocks(channel, rtype, rid):
            return json.dumps({"response": "channel_blocked"})
    override = NotificationOverride()
    if option == 'channel':
        override.channel = channel
    elif option == 'rule':
        override.rid = rid
        override.rtype = rtype
        override.channel = channel
    elif option == 'all':
        pass
    else:
        raise BadRequestError("Invalid option '%s'" % option)

    np.overrides.append(override)
    try:
        np.save()
    except me.ValidationError as err:
        log.critical("Failed to save %s: %r", np, err)
        raise BadRequestError(ERROR_MSG)
    return json.dumps({"response": "override_added"})
示例#3
0
def request_unsubscription(request):
    """
    Tags: notifications
    ---
    Returns an unsubscription request page.
    Accepts a request, validates the unsubscribe token and returns a rendered
    template, with a link and another token to confirm unsubscribing.
    ---
    """
    params = params_from_request(request)

    # Decrypt URL params.
    try:
        decrypted_str = decrypt(params["token"])
        decrypted_json = json.loads(decrypted_str)
    except Exception as exc:
        log.exception(repr(exc))
        raise BadRequestError(ERROR_MSG)

    # Verify HMAC.
    try:
        mac_verify(decrypted_json)
    except Exception as exc:
        raise BadRequestError(exc)

    try:
        org_id = decrypted_json["org_id"]
    except KeyError as err:
        log.exception(repr(err))
        raise BadRequestError(ERROR_MSG)

    # Get Organization.
    try:
        org = Organization.objects.get(id=org_id)
    except Organization.DoesNotExist:
        raise OrganizationNotFound()

    # Verify required parameters are present.
    rid = decrypted_json.get("rid", "")
    rtype = decrypted_json.get("rtype", "")
    email = decrypted_json.get("email")
    user_id = decrypted_json.get("user_id")
    channel = decrypted_json.get("channel")
    if not (email or user_id) and channel in CHANNELS:
        log.critical("Got invalid/insufficient data: %s", decrypted_json)
        raise BadRequestError(ERROR_MSG)

    inputs = {
        "uri": config.CORE_URI,
        "csrf_token": get_csrf_token(request),
        "rid": rid,
        "rype": rtype,
        "channel": channel,
        "org": org.id
    }

    unsubscribe_options = [{"id": "all", "title": "all mist.io emails"}]
    if channel == "EmailReports":
        unsubscribe_options.insert(0, {
            "id": "channel",
            "title": "mist.io weekly reports"
        })
    else:  # channel == "EmailAlert":
        unsubscribe_options.insert(0, {
            "id": "channel",
            "title": "all mist.io email alerts"
        })
        if rtype == 'rule':
            unsubscribe_options.insert(0, {
                "id": "rule",
                "title": "alerts about this rule"
            })

    inputs.update({'options': unsubscribe_options})
    # Get the user's notification policy.
    qr = me.Q(owner=org)
    qr &= me.Q(user_id=user_id) if user_id else me.Q(email=email)
    np = UserNotificationPolicy.objects(qr).first()

    # Check if an override already exists.
    if np:
        for override in np.overrides:
            if override.blocks(channel, rtype, rid):
                return render_to_response('templates/is_unsubscribed.pt',
                                          inputs)

    # Render template to unsubscribe.
    try:
        hmac_params = decrypted_json.copy()
        mac_sign(hmac_params)
        encrypted = encrypt(json.dumps(hmac_params))
        inputs.update({
            "token": encrypted,
            # TODO Make the template customizable/dynamic based on the action.
            "action": decrypted_json["action"],
            "csrf_token": get_csrf_token(request),
        })
    except Exception as exc:
        log.exception(repr(exc))
        raise BadRequestError(ERROR_MSG)

    return render_to_response('templates/unsubscribe.pt', inputs)