|
1 | 1 | """Product registration API views."""
|
2 | 2 |
|
| 3 | +from typing import cast |
3 | 4 | import logging
|
4 | 5 |
|
5 | 6 | from fastapi import APIRouter, Depends, HTTPException, Request
|
|
11 | 12 | from OpenSSL.crypto import load_certificate_request, FILETYPE_PEM # FIXME: use cryptography instead of pyOpenSSL
|
12 | 13 |
|
13 | 14 |
|
14 |
| -from .schema import CertificatesResponse, CertificatesRequest, RevokeRequest, KCClientToken |
| 15 | +from .schema import CertificatesResponse, CertificatesRequest, RevokeRequest, KCClientToken, ProductAddRequest |
15 | 16 | from ....db.nonces import SeenToken
|
16 | 17 | from ....db.errors import NotFound
|
17 | 18 | from ....cfssl.public import get_ca, get_bundle
|
18 | 19 | from ....cfssl.private import sign_csr, revoke_pem
|
19 | 20 | from ....cfssl.base import CFSSLError
|
20 | 21 | from ....rmsettings import RMSettings
|
21 | 22 | from ....kchelpers import KCClient
|
| 23 | +from ....productapihelpers import post_to_product |
22 | 24 |
|
23 | 25 |
|
24 | 26 | router = APIRouter()
|
@@ -138,3 +140,29 @@ async def get_kc_token(
|
138 | 140 | raise HTTPException(403, detail="KC is not enabled")
|
139 | 141 | data = await KCClient.singleton().client_access_token()
|
140 | 142 | return KCClientToken.parse_obj(data)
|
| 143 | + |
| 144 | + |
| 145 | +@router.post("/interop/{tgtproduct}", dependencies=[Depends(MTLSHeader(auto_error=True))]) |
| 146 | +async def add_interop( |
| 147 | + srcproduct: ProductAddRequest, |
| 148 | + tgtproduct: str, |
| 149 | + request: Request, |
| 150 | +) -> OperationResultResponse: |
| 151 | + """Product needs interop privileges with another""" |
| 152 | + payload = request.state.mtlsdn |
| 153 | + if payload.get("CN") not in RMSettings.singleton().valid_product_cns: |
| 154 | + raise HTTPException(status_code=403) |
| 155 | + |
| 156 | + # TODO: Verify that srcproduct certcn and actual cert contents match |
| 157 | + |
| 158 | + manifest = RMSettings.singleton().kraftwerk_manifest_dict |
| 159 | + if "products" not in manifest: |
| 160 | + LOGGER.error("Manifest does not have products key") |
| 161 | + raise HTTPException(status_code=500, detail="Manifest does not have products key") |
| 162 | + if not tgtproduct in manifest["products"]: |
| 163 | + raise HTTPException(status_code=404, detail=f"Unknown product {tgtproduct}") |
| 164 | + resp = await post_to_product(tgtproduct, "/api/v1/interop/add", srcproduct.dict(), OperationResultResponse) |
| 165 | + if resp is None: |
| 166 | + return OperationResultResponse(success=False, error="post_to_product returned None") |
| 167 | + resp = cast(OperationResultResponse, resp) |
| 168 | + return resp |
0 commit comments