def render_POST(self, request):
        request.responseHeaders.addRawHeader(b"content-type",
                                             b"application/json")
        response = {}
        try:
            token = request.args.get('token', None)[0]
            auth = request.args.get('auth', None)[0]
            setting = request.args.get('setting', None)[0]

            canarydrop = Canarydrop(**get_canarydrop(canarytoken=token))
            if not canarydrop['auth'] or canarydrop['auth'] != auth:
                raise NoCanarytokenPresent()

            if setting not in [
                    'clonedsite', 'email_enable', 'webhook_enable',
                    'sms_enable', 'browser_scanner_enable', 'web_image_enable'
            ]:
                raise NoCanarytokenPresent()

        except (IndexError, TypeError, NoCanarytokenPresent):
            return NoResource().render(request)

        if setting == 'clonedsite':
            try:
                clonedsite = request.args['clonedsite'][0]
                if not clonedsite:
                    raise KeyError

                cloned_token = {'clonedsite': clonedsite, 'canarytoken': token}
                canarydrop.clonedsite_token = save_clonedsite_token(
                    cloned_token)
                save_canarydrop(canarydrop)
                response[
                    'clonedsite_js'] = canarydrop.get_cloned_site_javascript()
                response['clonedsite'] = clonedsite
            except (IndexError, KeyError):
                return NoResource().render(request)
        elif setting == "email_enable":
            canarydrop['alert_email_enabled'] = request.args['value'][
                0] == "on"
        elif setting == "webhook_enable":
            canarydrop['alert_webhook_enabled'] = request.args['value'][
                0] == "on"
        elif setting == "sms_enable":
            canarydrop['alert_sms_enabled'] = request.args['value'][0] == "on"
        elif setting == "browser_scanner_enable":
            canarydrop['browser_scanner_enabled'] = request.args['value'][
                0] == "on"
        elif setting == "web_image_enable":
            canarydrop['web_image_enabled'] = request.args['value'][0] == "on"

        save_canarydrop(canarydrop=canarydrop)
        response['result'] = 'success'

        return simplejson.dumps(response)
    def render_POST(self, request):
        request.responseHeaders.addRawHeader(b"content-type",
                                             b"application/json")
        response = {
            'Error': None,
            'Url': "",
            'Url_components': None,
            'Token': "",
            'Email': "",
            'Hostname': "",
            'Auth': ''
        }

        try:
            try:
                token_type = request.args.get('type', None)[0]
                if token_type not in [
                        'web', 'dns', 'web_image', 'ms_word', 'adobe_pdf',
                        'windows_dir', 'clonedsite', 'qr_code', 'svn', 'smtp',
                        'sql_server', 'aws_keys', 'signed_exe',
                        'fast_redirect', 'slow_redirect'
                ]:
                    raise Exception()
            except:
                raise Exception('Unknown type')

            try:
                email = request.args.get('email', None)[0]
                webhook = request.args.get('webhook', None)[0]
                if not email and not webhook:
                    response['Error'] = 1
                    raise Exception('No email/webhook supplied')
            except IndexError:
                response['Error'] = 1
                raise Exception('No email supplied')
            try:
                memo = ''.join(request.args.get('memo', None))
                if not memo:
                    response['Error'] = 2
                    raise Exception('No memo supplied')
            except TypeError:
                response['Error'] = 2
                raise Exception('No memo supplied')

            if webhook and not is_webhook_valid(webhook):
                response['Error'] = 3
                raise Exception(
                    'Invalid webhook supplied. Confirm you can POST to this URL.'
                )

            alert_email_enabled = False if not email else True
            alert_webhook_enabled = False if not webhook else True
            canarytoken = Canarytoken()

            if token_type == "web":
                #always enable the browser scanner by default
                browser_scanner = True
            else:
                browser_scanner = False

            canarydrop = Canarydrop(
                type=token_type,
                generate=True,
                alert_email_enabled=alert_email_enabled,
                alert_email_recipient=email,
                alert_webhook_enabled=alert_webhook_enabled,
                alert_webhook_url=webhook,
                canarytoken=canarytoken.value(),
                memo=memo,
                browser_scanner_enabled=browser_scanner)

            if settings.TWILIO_ENABLED:
                try:
                    if not request.args['mobile'][0]:
                        raise KeyError

                    canarydrop['alert_sms_recipient'] = request.args['mobile'][
                        0]
                    canarydrop['alert_sms_enabled'] = True
                except KeyError:
                    canarydrop['alert_sms_recipient'] = ''
                    canarydrop['alert_sms_enabled'] = False

            save_canarydrop(canarydrop)

            response['Token'] = canarytoken.value()
            response['Url'] = canarydrop.get_url()
            response['Hostname'] = canarydrop.get_hostname()
            response['Auth'] = canarydrop['auth']
            response['Email'] = email
            response['Url_components'] = list(canarydrop.get_url_components())
            save_canarydrop(canarydrop)

            try:
                clonedsite = request.args['clonedsite'][0]
                if not clonedsite:
                    raise KeyError

                cloned_token = {
                    'clonedsite': clonedsite,
                    'canarytoken': canarytoken.value()
                }
                canarydrop.clonedsite_token = save_clonedsite_token(
                    cloned_token)
                canarydrop['clonedsite'] = clonedsite
                save_canarydrop(canarydrop)
                response[
                    'clonedsite_js'] = canarydrop.get_cloned_site_javascript()
                response['clonedsite'] = clonedsite
            except (IndexError, KeyError):
                pass

            try:
                if not request.args.get('type', None)[0] == 'qr_code':
                    raise Exception()
                response['qrcode_png'] = canarydrop.get_qrcode_data_uri_png()
            except:
                pass

            try:
                if not request.args.get('type', None)[0] == 'aws_keys':
                    raise Exception()
                keys = get_aws_keys(token=canarytoken.value(),
                                    server=get_all_canary_domains()[0])
                if not keys:
                    raise Exception()
                response['aws_access_key_id'] = keys[0]
                response['aws_secret_access_key'] = keys[1]
                canarydrop['aws_access_key_id'] = keys[0]
                canarydrop['aws_secret_access_key'] = keys[1]
                save_canarydrop(canarydrop)
            except:
                pass

            try:
                if not request.args.get('type', None)[0] == 'web_image':
                    raise Exception()

                if not settings.WEB_IMAGE_UPLOAD_PATH:
                    raise Exception(
                        "Image upload not supported, set CANARY_WEB_IMAGE_UPLOAD_PATH in frontend.env."
                    )

                fields = cgi.FieldStorage(
                    fp=request.content,
                    headers=request.getAllHeaders(),
                    environ={
                        'REQUEST_METHOD': 'POST',
                        'CONTENT_TYPE':
                        request.getAllHeaders()['content-type'],
                    })

                filename = fields['web_image'].filename
                filebody = fields['web_image'].value

                if len(filebody) > settings.MAX_UPLOAD_SIZE:
                    raise Exception('File too large')

                if not filename.lower().endswith(('.png', '.gif', '.jpg')):
                    raise Exception('Uploaded image must be a PNG, GIF or JPG')
                ext = filename.lower()[-4:]

                #create a random local filename
                r = hashlib.md5(os.urandom(32)).hexdigest()
                filepath = os.path.join(settings.WEB_IMAGE_UPLOAD_PATH, r[:2],
                                        r[2:]) + ext
                if not os.path.exists(os.path.dirname(filepath)):
                    try:
                        os.makedirs(os.path.dirname(filepath))
                    except OSError as exc:  # Guard against race condition
                        if exc.errno != errno.EEXIST:
                            raise

                with open(filepath, "w") as f:
                    f.write(filebody)

                canarydrop['web_image_enabled'] = True
                canarydrop['web_image_path'] = filepath
                save_canarydrop(canarydrop)
            except:
                pass

            try:
                if request.args.get('type', None)[0] != 'signed_exe':
                    raise Exception()

                fields = cgi.FieldStorage(
                    fp=request.content,
                    headers=request.getAllHeaders(),
                    environ={
                        'REQUEST_METHOD': 'POST',
                        'CONTENT_TYPE':
                        request.getAllHeaders()['content-type'],
                    })  #hacky way to parse out file contents and filenames

                filename = fields['signed_exe'].filename
                filebody = fields['signed_exe'].value
                if len(filebody) > settings.MAX_UPLOAD_SIZE:
                    raise Exception('File too large')

                if not filename.lower().endswith(('exe', 'dll')):
                    raise Exception(
                        'Uploaded authenticode file must be an exe or dll')

                signed_contents = make_canary_authenticode_binary(
                    hostname=canarydrop.get_hostname(with_random=False,
                                                     as_url=True),
                    filebody=filebody)
                response['file_name'] = filename
                response[
                    'file_contents'] = "data:octet/stream;base64," + base64.b64encode(
                        signed_contents)
            except:
                pass

            try:
                if request.args.get('type', None)[0] != 'fast_redirect':
                    raise Exception()

                if not request.args['redirect_url'][0]:
                    raise Exception()

                canarydrop['redirect_url'] = request.args['redirect_url'][0]
                save_canarydrop(canarydrop)
            except:
                pass

            try:
                if request.args.get('type', None)[0] != 'slow_redirect':
                    raise Exception()

                if not request.args['redirect_url'][0]:
                    raise Exception()

                canarydrop['redirect_url'] = request.args['redirect_url'][0]
                save_canarydrop(canarydrop)
            except:
                pass

        except Exception as e:
            if response['Error'] is None:
                response['Error'] = 255
                log.err('Unexpected error: {err}'.format(err=e))

        return simplejson.dumps(response)