Skip to content
This repository has been archived by the owner on Jul 3, 2023. It is now read-only.

Commit

Permalink
同步服务的 spec 配置(权限、角色)到 authz 服务
Browse files Browse the repository at this point in the history
  • Loading branch information
gwind committed Nov 5, 2018
1 parent c23363a commit a897714
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 11 deletions.
78 changes: 67 additions & 11 deletions src/codebase/controllers/service.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
# pylint: disable=W0223,W0221,broad-except
# pylint: disable=W0223,W0221,broad-except,C0103,R0201

import datetime
import json
import logging

from sqlalchemy import and_
from tornado.web import HTTPError
from tornado.httpclient import AsyncHTTPClient
from yaml import safe_load
from swagger_spec_validator.util import get_validator
from bravado_core.spec import Spec
Expand Down Expand Up @@ -48,6 +51,38 @@ def save_openapi(name, data):
}


def get_perm_roles(service_name, data):
spec_json = safe_load(data)
spec = Spec.from_dict(spec_json)

perm_roles = []

for key in spec.resources:
rs = spec.resources[key]
for attr in dir(rs):
if attr.startswith("__"):
continue

op = getattr(rs, attr)

# get roles
roles = op.op_spec.get("x-roles", [])
if "Authorization" in op.params:
if "authenticated" not in roles:
roles.append("authenticated")
else:
if "anonymous" not in roles:
roles.append("anonymous")

# get permission name
perm = ":".join([service_name, op.http_method, op.path_name])

# save
perm_roles.append((perm, roles))

return perm_roles


class ServiceHandler(APIRequestHandler):

def get(self):
Expand All @@ -56,33 +91,54 @@ def get(self):
services = self.db.query(Service).all()
self.success(data=[srv.isimple for srv in services])

def post(self):
async def post(self):
"""创建服务
"""

name = self.get_argument("name")
srv = self.db.query(Service).filter_by(name=name).first()
if srv:
self.fail("name-exist")
return
if not srv:
srv = Service(name=name)
self.db.add(srv)

spec_info = {}
errors = []

# 处理 openapi
file_metas = self.request.files["openapi"]
for meta in file_metas:
data = meta["body"]
spec_info = save_openapi(name, data)

srv = Service(
name=name,
version=spec_info.get("version"),
summary=spec_info.get("summary"),
description=spec_info.get("description"))
self.db.add(srv)
# update to service
http_client = AsyncHTTPClient()
for perm, roles in get_perm_roles(name, data):
for role in roles:
url = self.get_full_url(f"/authz/role/permission/append")
body = json.dumps({"role": role, "permissions": [perm]})
resp = await http_client.fetch(
url, method="POST", body=body, raise_error=False)
respBody = json.loads(resp.body)
status = respBody["status"]
if status != "success":
logging.error(
"update role permissions failed. resp.body = %s",
resp.body)
errors.append({"name": perm, "error": status})

if errors:
self.fail(errors=errors)
return

srv.version = spec_info.get("version")
srv.summary = spec_info.get("summary")
srv.description = spec_info.get("description")
self.db.commit()
self.success(id=str(srv.uuid))

def get_full_url(self, url):
return settings.INTERNAL_APIGATEWAY + url


class _BaseSingleServiceHandler(APIRequestHandler):

Expand Down
3 changes: 3 additions & 0 deletions src/codebase/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@
DB_URI = "sqlite://"

ETCD_ENDPOINTS = "127.0.0.1:2379"

# the apigate to access authz service
INTERNAL_APIGATEWAY = "http://127.0.0.1:10080"

0 comments on commit a897714

Please sign in to comment.