diff --git a/README.md b/README.md index 1753d44042eae64d7cce7cfe47b902243e2110c1..17db2d3b1c460a1b60f6f145f9001a5ee54ae3b1 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ flowchart LR The policy service exposes HTTP endpoints to evaluate/execute policies. The endpoint interface is conformant to the TSA requirements document. -To evaluate a policy a POST request is sent to the evaluation URL. +To evaluate a policy a GET or POST request is sent to the evaluation URL. The example URL below is given for the local docker-compose environment. The `host` and `port` parts will be different for the different environments. @@ -48,10 +48,11 @@ are also important during policy development (see below) as `group` and `policy` **must** be used as package name inside the policy source code file. -The body of the POST request **must** be JSON and it is passed directly -to the policy execution runtime. Inside the policy it is accessed with -the global variable name `input`. For example, if you pass to the evaluation -endpoint the following JSON, it will be accessible by `input.message`: +The body of the POST request can be empty, but if it's not empty, it +**must** be JSON. It is passed directly to the policy execution runtime. +Inside the policy it is accessed with the global variable name `input`. +For example, if you pass to the evaluation endpoint the following JSON, +it will be accessible by `input.message`: ```json { "message": "hello world" diff --git a/cmd/policy/main.go b/cmd/policy/main.go index 9bdce8186e666bdd27195b64773fc6cb8fce4d7d..1e6e9c9f888b81424a5e2c47c5b4f69ffe2ce5f8 100644 --- a/cmd/policy/main.go +++ b/cmd/policy/main.go @@ -90,7 +90,8 @@ func main() { regofunc.Register("taskListCreate", rego.Function2(taskFuncs.CreateTaskListFunc())) regofunc.Register("getKey", rego.Function1(keysFuncs.GetKeyFunc())) regofunc.Register("getAllKeys", rego.FunctionDyn(keysFuncs.GetAllKeysFunc())) - regofunc.Register("strictBuiltinErrors", rego.StrictBuiltinErrors(true)) + regofunc.Register("getAllKeys", rego.FunctionDyn(keysFuncs.GetAllKeysFunc())) + regofunc.Register("issuer", rego.FunctionDyn(keysFuncs.IssuerDID())) } // subscribe the cache for policy data changes diff --git a/internal/regofunc/pubkeys.go b/internal/regofunc/pubkeys.go index 51d41c3c353ddd558905ee5f71d5a06bbae14f32..c9873c6b9c246df6205b2d0d781a60a8de5e1617 100644 --- a/internal/regofunc/pubkeys.go +++ b/internal/regofunc/pubkeys.go @@ -103,3 +103,39 @@ func (pf *PubkeyFuncs) GetAllKeysFunc() (*rego.Function, rego.BuiltinDyn) { return ast.NewTerm(v), nil } } + +func (pf *PubkeyFuncs) IssuerDID() (*rego.Function, rego.BuiltinDyn) { + return ®o.Function{ + Name: "issuer", + Decl: types.NewFunction(nil, types.A), + Memoize: true, + }, + func(bctx rego.BuiltinContext, terms []*ast.Term) (*ast.Term, error) { + uri, err := url.ParseRequestURI(pf.signerAddr + "/v1/issuerDID") + if err != nil { + return nil, err + } + + req, err := http.NewRequest("GET", uri.String(), nil) + if err != nil { + return nil, err + } + + resp, err := pf.httpClient.Do(req.WithContext(bctx.Context)) + if err != nil { + return nil, err + } + defer resp.Body.Close() // nolint:errcheck + + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("unexpected response from signer: %s", resp.Status) + } + + v, err := ast.ValueFromReader(resp.Body) + if err != nil { + return nil, err + } + + return ast.NewTerm(v), nil + } +}