Add backend ability to generate sec keys in config app

This commit is contained in:
Sam Chow 2018-08-14 11:42:11 -04:00
parent 0bc22d810a
commit 9faba7f5c3
3 changed files with 243 additions and 165 deletions

View file

@ -2,6 +2,7 @@ import logging
import pathvalidate
import os
import subprocess
from datetime import datetime
from flask import request, jsonify, make_response
@ -149,6 +150,64 @@ class SuperUserServiceKeyManagement(ApiResource):
'keys': [key.to_dict() for key in keys],
})
@nickname('createServiceKey')
@validate_json_request('CreateServiceKey')
def post(self):
body = request.get_json()
# Ensure we have a valid expiration date if specified.
expiration_date = body.get('expiration', None)
if expiration_date is not None:
try:
expiration_date = datetime.utcfromtimestamp(float(expiration_date))
except ValueError as ve:
raise InvalidRequest('Invalid expiration date: %s' % ve)
if expiration_date <= datetime.now():
raise InvalidRequest('Expiration date cannot be in the past')
# Create the metadata for the key.
# Since we don't have logins in the config app, we'll just get any of the superusers
user = config_provider.get_config().get('SUPER_USERS', [None])[0]
if user is None:
raise InvalidRequest('No super users exist, cannot create service key without approver')
metadata = body.get('metadata', {})
metadata.update({
'created_by': 'Quay Superuser Panel',
'creator': user,
'ip': request.remote_addr,
})
# Generate a key with a private key that we *never save*.
(private_key, key_id) = pre_oci_model.generate_service_key(body['service'], expiration_date,
metadata=metadata,
name=body.get('name', ''))
# Auto-approve the service key.
pre_oci_model.approve_service_key(key_id, ServiceKeyApprovalType.SUPERUSER,
notes=body.get('notes', ''))
# Log the creation and auto-approval of the service key.
key_log_metadata = {
'kid': key_id,
'preshared': True,
'service': body['service'],
'name': body.get('name', ''),
'expiration_date': expiration_date,
'auto_approved': True,
}
log_action('service_key_create', None, key_log_metadata)
log_action('service_key_approve', None, key_log_metadata)
return jsonify({
'kid': key_id,
'name': body.get('name', ''),
'service': body['service'],
'public_key': private_key.publickey().exportKey('PEM'),
'private_key': private_key.exportKey('PEM'),
})
@resource('/v1/superuser/approvedkeys/<kid>')
class SuperUserServiceKeyApproval(ApiResource):
""" Resource for approving service keys. """

View file

@ -43,5 +43,10 @@ class PreOCIModel(SuperuserDataInterface):
except model.ServiceKeyAlreadyApproved:
raise ServiceKeyAlreadyApproved
def generate_service_key(self, service, expiration_date, kid=None, name='', metadata=None, rotation_duration=None):
(private_key, key) = model.service_keys.generate_service_key(service, expiration_date, metadata=metadata, name=name)
return private_key, key.kid
pre_oci_model = PreOCIModel()

View file

@ -27,6 +27,19 @@ export type MarkdownSymbol = 'heading1'
export type BrowserPlatform = "firefox"
| "chrome";
/**
* Constant representing current browser platform. Used for determining available features.
* TODO Only rudimentary implementation, should prefer specific feature detection strategies instead.
*/
export const browserPlatform: BrowserPlatform = (() => {
if (navigator.userAgent.toLowerCase().indexOf('firefox') != -1) {
return 'firefox';
}
else {
return 'chrome';
}
})();
/**
* Dynamically fetch and register a new language with Highlight.js
*/
@ -90,6 +103,7 @@ highlightedLanguages.forEach((langName) => addHighlightedLanguage(langName));
declarations: [],
providers: [
{provide: 'markdownConverter', useValue: new Converter({extensions: [<any>showdownHighlight]})},
{provide: 'BrowserPlatform', useValue: browserPlatform},
],
})
export class MarkdownModule {