Skip to content

Commit

Permalink
[dss][openapi-to-go-server] Move scopes to go constants in generated …
Browse files Browse the repository at this point in the history
…files (#1023)

* [openapi-to-go-server] Move scopes to go constants

* Update examples

* Update DSS interfaces
  • Loading branch information
barroco authored May 2, 2024
1 parent 8a1a5e9 commit 89eefa0
Show file tree
Hide file tree
Showing 10 changed files with 171 additions and 116 deletions.
16 changes: 15 additions & 1 deletion interfaces/openapi-to-go-server/apis.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import dataclasses
from typing import Dict, List, Set
from itertools import chain
from typing import Dict, List, Set, Tuple

import data_types
import operations
Expand Down Expand Up @@ -58,6 +59,19 @@ def filter_operations(self, tags: Set[str]):
self.data_types = [dt for dt in self.data_types
if dt.name in required_data_types]

def security_scopes(self) -> Set[Tuple[str, operations.Scope]]:
"""Returns a set of unique security scopes used by this API.
:return: set of unique tuples containing the authorization scheme and scope
"""
security_options = [op.security.options for op in self.operations]
scopes_set = set()
for so in chain.from_iterable(security_options):
for scheme, scopes in so.option.items():
for scope in scopes:
scopes_set.add((scheme, scope))
return scopes_set


def make_api(package: str, api_path: str, spec: Dict) -> API:
"""Create an API from the given OpenAPI specification
Expand Down
24 changes: 13 additions & 11 deletions interfaces/openapi-to-go-server/example/api/rid/interface.gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,57 +7,59 @@ import (
)

var (
DssReadIdentificationServiceAreasScope = api.RequiredScope("dss.read.identification_service_areas")
DssWriteIdentificationServiceAreasScope = api.RequiredScope("dss.write.identification_service_areas")
SearchIdentificationServiceAreasSecurity = []api.AuthorizationOption{
{
"AuthFromAuthorizationAuthority": {"dss.read.identification_service_areas"},
"AuthFromAuthorizationAuthority": {DssReadIdentificationServiceAreasScope},
},
}
GetIdentificationServiceAreaSecurity = []api.AuthorizationOption{
{
"AuthFromAuthorizationAuthority": {"dss.read.identification_service_areas"},
"AuthFromAuthorizationAuthority": {DssReadIdentificationServiceAreasScope},
},
}
CreateIdentificationServiceAreaSecurity = []api.AuthorizationOption{
{
"AuthFromAuthorizationAuthority": {"dss.write.identification_service_areas"},
"AuthFromAuthorizationAuthority": {DssWriteIdentificationServiceAreasScope},
},
}
UpdateIdentificationServiceAreaSecurity = []api.AuthorizationOption{
{
"AuthFromAuthorizationAuthority": {"dss.write.identification_service_areas"},
"AuthFromAuthorizationAuthority": {DssWriteIdentificationServiceAreasScope},
},
}
DeleteIdentificationServiceAreaSecurity = []api.AuthorizationOption{
{
"AuthFromAuthorizationAuthority": {"dss.write.identification_service_areas"},
"AuthFromAuthorizationAuthority": {DssWriteIdentificationServiceAreasScope},
},
}
SearchSubscriptionsSecurity = []api.AuthorizationOption{
{
"AuthFromAuthorizationAuthority": {"dss.read.identification_service_areas"},
"AuthFromAuthorizationAuthority": {DssReadIdentificationServiceAreasScope},
},
}
GetSubscriptionSecurity = []api.AuthorizationOption{
{
"AuthFromAuthorizationAuthority": {"dss.read.identification_service_areas"},
"AuthFromAuthorizationAuthority": {DssReadIdentificationServiceAreasScope},
},
{
"AuthFromAuthorizationAuthority": {"dss.write.identification_service_areas"},
"AuthFromAuthorizationAuthority": {DssWriteIdentificationServiceAreasScope},
},
}
CreateSubscriptionSecurity = []api.AuthorizationOption{
{
"AuthFromAuthorizationAuthority": {"dss.read.identification_service_areas"},
"AuthFromAuthorizationAuthority": {DssReadIdentificationServiceAreasScope},
},
}
UpdateSubscriptionSecurity = []api.AuthorizationOption{
{
"AuthFromAuthorizationAuthority": {"dss.read.identification_service_areas"},
"AuthFromAuthorizationAuthority": {DssReadIdentificationServiceAreasScope},
},
}
DeleteSubscriptionSecurity = []api.AuthorizationOption{
{
"AuthFromAuthorizationAuthority": {"dss.read.identification_service_areas"},
"AuthFromAuthorizationAuthority": {DssReadIdentificationServiceAreasScope},
},
}
)
Expand Down
81 changes: 43 additions & 38 deletions interfaces/openapi-to-go-server/example/api/scd/interface.gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,154 +7,159 @@ import (
)

var (
UtmAvailabilityArbitrationScope = api.RequiredScope("utm.availability_arbitration")
UtmConformanceMonitoringSaScope = api.RequiredScope("utm.conformance_monitoring_sa")
UtmConstraintManagementScope = api.RequiredScope("utm.constraint_management")
UtmStrategicCoordinationScope = api.RequiredScope("utm.strategic_coordination")
UtmConstraintProcessingScope = api.RequiredScope("utm.constraint_processing")
QueryOperationalIntentReferencesSecurity = []api.AuthorizationOption{
{
"Authority": {"utm.strategic_coordination"},
"Authority": {UtmStrategicCoordinationScope},
},
{
"Authority": {"utm.conformance_monitoring_sa"},
"Authority": {UtmConformanceMonitoringSaScope},
},
}
GetOperationalIntentReferenceSecurity = []api.AuthorizationOption{
{
"Authority": {"utm.strategic_coordination"},
"Authority": {UtmStrategicCoordinationScope},
},
{
"Authority": {"utm.conformance_monitoring_sa"},
"Authority": {UtmConformanceMonitoringSaScope},
},
}
CreateOperationalIntentReferenceSecurity = []api.AuthorizationOption{
{
"Authority": {"utm.strategic_coordination"},
"Authority": {UtmStrategicCoordinationScope},
},
{
"Authority": {"utm.strategic_coordination", "utm.constraint_processing"},
"Authority": {UtmStrategicCoordinationScope, UtmConstraintProcessingScope},
},
{
"Authority": {"utm.conformance_monitoring_sa"},
"Authority": {UtmConformanceMonitoringSaScope},
},
}
UpdateOperationalIntentReferenceSecurity = []api.AuthorizationOption{
{
"Authority": {"utm.strategic_coordination"},
"Authority": {UtmStrategicCoordinationScope},
},
{
"Authority": {"utm.strategic_coordination", "utm.constraint_processing"},
"Authority": {UtmStrategicCoordinationScope, UtmConstraintProcessingScope},
},
{
"Authority": {"utm.conformance_monitoring_sa"},
"Authority": {UtmConformanceMonitoringSaScope},
},
}
DeleteOperationalIntentReferenceSecurity = []api.AuthorizationOption{
{
"Authority": {"utm.strategic_coordination"},
"Authority": {UtmStrategicCoordinationScope},
},
{
"Authority": {"utm.conformance_monitoring_sa"},
"Authority": {UtmConformanceMonitoringSaScope},
},
}
QueryConstraintReferencesSecurity = []api.AuthorizationOption{
{
"Authority": {"utm.constraint_management"},
"Authority": {UtmConstraintManagementScope},
},
{
"Authority": {"utm.constraint_processing"},
"Authority": {UtmConstraintProcessingScope},
},
}
GetConstraintReferenceSecurity = []api.AuthorizationOption{
{
"Authority": {"utm.constraint_management"},
"Authority": {UtmConstraintManagementScope},
},
{
"Authority": {"utm.constraint_processing"},
"Authority": {UtmConstraintProcessingScope},
},
}
CreateConstraintReferenceSecurity = []api.AuthorizationOption{
{
"Authority": {"utm.constraint_management"},
"Authority": {UtmConstraintManagementScope},
},
}
UpdateConstraintReferenceSecurity = []api.AuthorizationOption{
{
"Authority": {"utm.constraint_management"},
"Authority": {UtmConstraintManagementScope},
},
}
DeleteConstraintReferenceSecurity = []api.AuthorizationOption{
{
"Authority": {"utm.constraint_management"},
"Authority": {UtmConstraintManagementScope},
},
}
QuerySubscriptionsSecurity = []api.AuthorizationOption{
{
"Authority": {"utm.constraint_processing"},
"Authority": {UtmConstraintProcessingScope},
},
{
"Authority": {"utm.strategic_coordination"},
"Authority": {UtmStrategicCoordinationScope},
},
}
GetSubscriptionSecurity = []api.AuthorizationOption{
{
"Authority": {"utm.constraint_processing"},
"Authority": {UtmConstraintProcessingScope},
},
{
"Authority": {"utm.strategic_coordination"},
"Authority": {UtmStrategicCoordinationScope},
},
}
CreateSubscriptionSecurity = []api.AuthorizationOption{
{
"Authority": {"utm.constraint_processing"},
"Authority": {UtmConstraintProcessingScope},
},
{
"Authority": {"utm.strategic_coordination"},
"Authority": {UtmStrategicCoordinationScope},
},
}
UpdateSubscriptionSecurity = []api.AuthorizationOption{
{
"Authority": {"utm.constraint_processing"},
"Authority": {UtmConstraintProcessingScope},
},
{
"Authority": {"utm.strategic_coordination"},
"Authority": {UtmStrategicCoordinationScope},
},
}
DeleteSubscriptionSecurity = []api.AuthorizationOption{
{
"Authority": {"utm.constraint_processing"},
"Authority": {UtmConstraintProcessingScope},
},
{
"Authority": {"utm.strategic_coordination"},
"Authority": {UtmStrategicCoordinationScope},
},
}
MakeDssReportSecurity = []api.AuthorizationOption{
{
"Authority": {"utm.constraint_management"},
"Authority": {UtmConstraintManagementScope},
},
{
"Authority": {"utm.constraint_processing"},
"Authority": {UtmConstraintProcessingScope},
},
{
"Authority": {"utm.strategic_coordination"},
"Authority": {UtmStrategicCoordinationScope},
},
{
"Authority": {"utm.conformance_monitoring_sa"},
"Authority": {UtmConformanceMonitoringSaScope},
},
{
"Authority": {"utm.availability_arbitration"},
"Authority": {UtmAvailabilityArbitrationScope},
},
}
GetUssAvailabilitySecurity = []api.AuthorizationOption{
{
"Authority": {"utm.availability_arbitration"},
"Authority": {UtmAvailabilityArbitrationScope},
},
{
"Authority": {"utm.strategic_coordination"},
"Authority": {UtmStrategicCoordinationScope},
},
{
"Authority": {"utm.conformance_monitoring_sa"},
"Authority": {UtmConformanceMonitoringSaScope},
},
}
SetUssAvailabilitySecurity = []api.AuthorizationOption{
{
"Authority": {"utm.availability_arbitration"},
"Authority": {UtmAvailabilityArbitrationScope},
},
}
)
Expand Down
6 changes: 5 additions & 1 deletion interfaces/openapi-to-go-server/formatting.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from typing import Dict

import re

def capitalize_first_letter(s: str) -> str:
return s[0].upper() + s[1:] if s else s
Expand All @@ -9,6 +9,10 @@ def snake_case_to_pascal_case(s: str) -> str:
return s.replace('_', ' ').title().replace(' ', '')


def string_to_pascal_case(s: str) -> str:
return re.sub(r'[^a-zA-Z0-9]', ' ', s).title().replace(' ', '')


def replace(s: str, template_vars: Dict[str, str]) -> str:
for k, v in template_vars.items():
s = s.replace(k, v)
Expand Down
20 changes: 18 additions & 2 deletions interfaces/openapi-to-go-server/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,27 @@ def go_field_name(self) -> str:
return formatting.snake_case_to_pascal_case(self.name)


@dataclasses.dataclass
class Scope:
"""Representation of a scope used to authorize a particular Operation"""

name: str
"""Name of the scope"""

@property
def go_constant_name(self) -> str:
"""Go-style field name for this parameter in the Operation's `request_type_name`"""
return "{}Scope".format(formatting.string_to_pascal_case(self.name))

def __hash__(self):
return self.name.__hash__()


@dataclasses.dataclass
class AuthorizationOption:
"""One acceptable option for authorization to invoke a particular Operation"""

option: Dict[str, List[str]]
option: Dict[str, List[Scope]]
"""Mapping between authorization scheme name and a list of scope combination options that may be used to access the Operation under that authorization scheme"""


Expand Down Expand Up @@ -201,7 +217,7 @@ def make_operations(path: str, schema: Dict) -> Tuple[List[Operation], List[data
for security_option in action.get('security', []):
auth_option = AuthorizationOption(option={})
for scheme, scopes in security_option.items():
auth_option.option[scheme] = scopes
auth_option.option[scheme] = [Scope(s) for s in scopes]
security.options.append(auth_option)

responses: List[Response] = []
Expand Down
7 changes: 6 additions & 1 deletion interfaces/openapi-to-go-server/rendering.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ def implementation_interface(api: apis.API, api_package: str, ensure_500: bool)
# Provide security constants
lines.append('var (')

for _, scope in api.security_scopes():
lines.append(
'%s = api.RequiredScope("%s")' % (scope.go_constant_name, scope.name)
)

var_body: List[str] = []
for operation in api.operations:
var_body.append(
Expand All @@ -118,7 +123,7 @@ def implementation_interface(api: apis.API, api_package: str, ensure_500: bool)
init_body.extend(indent([
'"%s": {%s},' % (
scheme,
', '.join('"{}"'.format(scope) for scope in scopes)
', '.join(scope.go_constant_name for scope in scopes)
)
], 1))
init_body.append('},')
Expand Down
2 changes: 1 addition & 1 deletion interfaces/openapi-to-go-server/requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
PyYAML==6.0
PyYAML==6.0.1
Loading

0 comments on commit 89eefa0

Please sign in to comment.