using Invercargill; using Invercargill.DataStructures; using Inversion; using Astralis; namespace Spry { public class ComponentEndpoint : Object, Endpoint { private PathProvider component_uri_provider = inject(); private CryptographyProvider cryptograpy_provider = inject(); private Scope scope = inject(); public async Astralis.HttpResult handle_request (HttpContext http_context, RouteContext route_context) throws Error { var component_id = route_context.mapped_parameters.get_or_default ("component-id"); var action_name = route_context.mapped_parameters.get_or_default ("action"); var context_blob = route_context.mapped_parameters.get_or_default ("context"); if(component_id == null) { return new HttpStringResult ("Missing component ID", StatusCode.BAD_REQUEST); } if(component_id == null) { return new HttpStringResult ("Missing action", StatusCode.BAD_REQUEST); } var component = component_uri_provider.get_component_instance(component_id, scope); if(component == null) { return new HttpStringResult ("Invalid component ID", StatusCode.NOT_FOUND); } if(context_blob != null) { ComponentContext context; try { context = cryptograpy_provider.read_component_context_blob (context_blob); } catch(Error e) { warning(@"Invalid component context: $(e.message)"); return new HttpStringResult ("Invalid component context", StatusCode.BAD_REQUEST); } if(context.type_name != component.get_type().name()) { return new HttpStringResult ("Context mismatch", StatusCode.BAD_REQUEST); } component.context_key = context.context_key; foreach(var prop in context.data) { unowned var component_class = component.get_class (); var prop_spec = component_class.find_property (prop.key); if(prop_spec == null) { return new HttpStringResult (@"Invalid context property '$(prop.key)'", StatusCode.BAD_REQUEST); } component.set_property (prop.key, prop.value.to_value (prop_spec.value_type)); } } yield component.handle_action(action_name); return yield component.to_result(); } } }