certidude/certidude/api/token.py

58 lines
2.3 KiB
Python
Raw Normal View History

import click
import codecs
import falcon
2017-04-21 21:22:08 +00:00
import logging
import os
import string
from asn1crypto import pem
from asn1crypto.csr import CertificationRequest
from datetime import datetime, timedelta
2017-04-21 21:22:08 +00:00
from time import time
from certidude import mailer, const
from certidude.tokens import TokenManager
from certidude.relational import RelationalMixin
from certidude.decorators import serialize
2017-04-21 21:22:08 +00:00
from certidude.user import User
from certidude import config
from .utils import AuthorityHandler
from .utils.firewall import login_required, authorize_admin
2017-04-21 21:22:08 +00:00
logger = logging.getLogger(__name__)
class TokenResource(AuthorityHandler):
def __init__(self, authority, manager):
AuthorityHandler.__init__(self, authority)
self.manager = manager
2017-04-21 21:22:08 +00:00
def on_put(self, req, resp):
try:
username, mail, created, expires, profile = self.manager.consume(req.get_param("token", required=True))
except RelationalMixin.DoesNotExist:
raise falcon.HTTPForbidden("Forbidden", "No such token or token expired")
body = req.stream.read(req.content_length)
header, _, der_bytes = pem.unarmor(body)
csr = CertificationRequest.load(der_bytes)
common_name = csr["certification_request_info"]["subject"].native["common_name"]
if not common_name.startswith(username + "@"):
raise falcon.HTTPBadRequest("Bad requst", "Invalid common name %s" % common_name)
try:
_, resp.body = self.authority._sign(csr, body, profile=config.PROFILES.get(profile),
overwrite=config.TOKEN_OVERWRITE_PERMITTED)
resp.set_header("Content-Type", "application/x-pem-file")
logger.info("Autosigned %s as proven by token ownership", common_name)
except FileExistsError:
logger.info("Won't autosign duplicate %s", common_name)
raise falcon.HTTPConflict(
"Certificate with such common name (CN) already exists",
"Will not overwrite existing certificate signing request, explicitly delete existing one and try again")
2017-04-21 21:22:08 +00:00
@serialize
2017-04-21 21:22:08 +00:00
@login_required
@authorize_admin
def on_post(self, req, resp):
self.manager.issue(
issuer = req.context.get("user"),
subject = User.objects.get(req.get_param("username", required=True)),
subject_mail = req.get_param("mail"))