lemur/lemur/authorities/service.py

235 lines
6.3 KiB
Python
Raw Normal View History

2015-06-22 22:47:27 +02:00
"""
.. module: lemur.authorities.service
:platform: Unix
:synopsis: This module contains all of the services level functions used to
administer authorities in Lemur
:copyright: (c) 2018 by Netflix Inc., see AUTHORS for more
2015-06-22 22:47:27 +02:00
:license: Apache, see LICENSE for more details.
.. moduleauthor:: Kevin Glisson <kglisson@netflix.com>
"""
import json
2015-06-22 22:47:27 +02:00
from lemur import database
from lemur.common.utils import truthiness
from lemur.extensions import metrics
2015-06-22 22:47:27 +02:00
from lemur.authorities.models import Authority
from lemur.certificates.models import Certificate
2015-06-22 22:47:27 +02:00
from lemur.roles import service as role_service
from lemur.certificates.service import upload
2015-06-22 22:47:27 +02:00
2015-07-21 22:06:13 +02:00
def update(authority_id, description, owner, active, roles):
2015-06-22 22:47:27 +02:00
"""
Update an authority with new values.
2015-06-22 22:47:27 +02:00
:param authority_id:
:param roles: roles that are allowed to use this authority
:return:
"""
authority = get(authority_id)
authority.roles = roles
authority.active = active
authority.description = description
authority.owner = owner
2015-06-22 22:47:27 +02:00
return database.update(authority)
def update_options(authority_id, options):
"""
Update an authority with new options.
:param authority_id:
:param options: the new options to be saved into the authority
:return:
"""
authority = get(authority_id)
authority.options = options
return database.update(authority)
2020-09-23 16:57:48 +02:00
def mint(**kwargs):
2015-06-22 22:47:27 +02:00
"""
Creates the authority based on the plugin provided.
2015-06-22 22:47:27 +02:00
"""
2019-05-16 16:57:02 +02:00
issuer = kwargs["plugin"]["plugin_object"]
values = issuer.create_authority(kwargs)
# support older plugins
if len(values) == 3:
body, chain, roles = values
private_key = None
elif len(values) == 4:
body, private_key, chain, roles = values
2019-05-16 16:57:02 +02:00
roles = create_authority_roles(
roles,
kwargs["owner"],
kwargs["plugin"]["plugin_object"].title,
kwargs["creator"],
)
return body, private_key, chain, roles
2015-06-22 22:47:27 +02:00
2015-11-23 18:53:55 +01:00
def create_authority_roles(roles, owner, plugin_title, creator):
"""
Creates all of the necessary authority roles.
:param creator:
:param roles:
:return:
"""
2015-06-22 22:47:27 +02:00
role_objs = []
for r in roles:
2019-05-16 16:57:02 +02:00
role = role_service.get_by_name(r["name"])
if not role:
role = role_service.create(
2019-05-16 16:57:02 +02:00
r["name"],
password=r["password"],
description="Auto generated role for {0}".format(plugin_title),
2019-05-16 16:57:02 +02:00
username=r["username"],
)
2015-06-22 22:47:27 +02:00
# the user creating the authority should be able to administer it
2019-05-16 16:57:02 +02:00
if role.username == "admin":
creator.roles.append(role)
2015-06-22 22:47:27 +02:00
role_objs.append(role)
# create an role for the owner and assign it
owner_role = role_service.get_by_name(owner)
if not owner_role:
owner_role = role_service.create(
2019-05-16 16:57:02 +02:00
owner, description="Auto generated role based on owner: {0}".format(owner)
)
role_objs.append(owner_role)
return role_objs
2015-06-22 22:47:27 +02:00
def create(**kwargs):
"""
Creates a new authority.
"""
2021-03-17 18:51:21 +01:00
ca_name = kwargs.get("name")
if get_by_name(ca_name):
raise Exception(f"Authority with name {ca_name} already exists")
if role_service.get_by_name(f"{ca_name}_admin") or role_service.get_by_name(f"{ca_name}_operator"):
raise Exception(f"Admin and/or operator roles for authority {ca_name} already exist")
body, private_key, chain, roles = mint(**kwargs)
2019-05-16 16:57:02 +02:00
kwargs["creator"].roles = list(set(list(kwargs["creator"].roles) + roles))
2019-05-16 16:57:02 +02:00
kwargs["body"] = body
kwargs["private_key"] = private_key
kwargs["chain"] = chain
2019-05-16 16:57:02 +02:00
if kwargs.get("roles"):
kwargs["roles"] += roles
else:
2019-05-16 16:57:02 +02:00
kwargs["roles"] = roles
cert = upload(**kwargs)
2019-05-16 16:57:02 +02:00
kwargs["authority_certificate"] = cert
if kwargs.get("plugin", {}).get("plugin_options", []):
kwargs["options"] = json.dumps(kwargs["plugin"]["plugin_options"])
authority = Authority(**kwargs)
authority = database.create(authority)
2019-05-16 16:57:02 +02:00
kwargs["creator"].authorities.append(authority)
2015-06-22 22:47:27 +02:00
2019-05-16 16:57:02 +02:00
metrics.send(
"authority_created", "counter", 1, metric_tags=dict(owner=authority.owner)
)
2015-06-22 22:47:27 +02:00
return authority
def get_all():
"""
Get all authorities that are currently in Lemur.
:rtype : List
:return:
"""
query = database.session_query(Authority)
return database.find_all(query, Authority, {}).all()
def get(authority_id):
"""
Retrieves an authority given it's ID
:param authority_id:
:return:
"""
return database.get(Authority, authority_id)
def get_by_name(authority_name):
"""
Retrieves an authority given it's name.
:param authority_name:
:return:
"""
2019-05-16 16:57:02 +02:00
return database.get(Authority, authority_name, field="name")
2015-06-22 22:47:27 +02:00
def get_authority_role(ca_name, creator=None):
2015-06-22 22:47:27 +02:00
"""
Attempts to get the authority role for a given ca uses current_user
as a basis for accomplishing that.
:param ca_name:
"""
if creator:
if creator.is_admin:
return role_service.get_by_name("{0}_admin".format(ca_name))
return role_service.get_by_name("{0}_operator".format(ca_name))
2015-06-22 22:47:27 +02:00
def render(args):
"""
Helper that helps us render the REST Api responses.
:param args:
:return:
"""
query = database.session_query(Authority)
2019-05-16 16:57:02 +02:00
filt = args.pop("filter")
2015-06-22 22:47:27 +02:00
if filt:
2019-05-16 16:57:02 +02:00
terms = filt.split(";")
if "active" in filt:
query = query.filter(Authority.active == truthiness(terms[1]))
2019-05-16 16:57:02 +02:00
elif "cn" in filt:
term = "%{0}%".format(terms[1])
sub_query = (
database.session_query(Certificate.root_authority_id)
.filter(Certificate.cn.ilike(term))
.subquery()
2019-05-16 16:57:02 +02:00
)
query = query.filter(Authority.id.in_(sub_query))
2015-06-22 22:47:27 +02:00
else:
query = database.filter(query, Authority, terms)
# we make sure that a user can only use an authority they either own are a member of - admins can see all
2019-05-16 16:57:02 +02:00
if not args["user"].is_admin:
2015-06-22 22:47:27 +02:00
authority_ids = []
2019-05-16 16:57:02 +02:00
for authority in args["user"].authorities:
authority_ids.append(authority.id)
2019-05-16 16:57:02 +02:00
for role in args["user"].roles:
for authority in role.authorities:
authority_ids.append(authority.id)
2015-06-22 22:47:27 +02:00
query = query.filter(Authority.id.in_(authority_ids))
return database.sort_and_page(query, Authority, args)