mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-03-19 07:57:13 -04:00
* add policies service add policies proxy middleware add policies event service add policies grpc service prepare ci and git environments (ci, make, readme, doc) * add webfinger to the drone conf * fix docs remove not used virus scan postprocessing step * relocate example rego file implicitly enable and disable proxy and postprocessing policy checking by setting the query. update configuration descriptions * move policies update readme * use converter func to convert pp environment to actual environment expose and test custom rego functions add engine unit tests add opa unit tests update policies readme Co-authored-by: Martin <github@diemattels.at> * relocate sample policies to the deployments folder change and document policies service port * update index.md and small fix * add health command add version command add debug server --------- Co-authored-by: Martin <github@diemattels.at>
125 lines
2.7 KiB
Go
125 lines
2.7 KiB
Go
package engine
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/cs3org/reva/v2/pkg/rhttp"
|
|
"github.com/gabriel-vasile/mimetype"
|
|
"github.com/open-policy-agent/opa/ast"
|
|
"github.com/open-policy-agent/opa/rego"
|
|
"github.com/open-policy-agent/opa/types"
|
|
"github.com/owncloud/ocis/v2/services/policies/pkg/config"
|
|
)
|
|
|
|
// OPA wraps open policy agent makes it possible to ask if an action is granted.
|
|
type OPA struct {
|
|
policies []string
|
|
timeout time.Duration
|
|
}
|
|
|
|
// NewOPA returns a ready to use opa engine.
|
|
func NewOPA(timeout time.Duration, conf config.Engine) (OPA, error) {
|
|
return OPA{
|
|
policies: conf.Policies,
|
|
timeout: timeout,
|
|
},
|
|
nil
|
|
}
|
|
|
|
// Evaluate evaluates the opa policies and returns the result.
|
|
func (o OPA) Evaluate(ctx context.Context, qs string, env Environment) (bool, error) {
|
|
ctx, cancel := context.WithTimeout(ctx, o.timeout)
|
|
defer cancel()
|
|
|
|
q, err := rego.New(
|
|
rego.Query(qs),
|
|
rego.Load(o.policies, nil),
|
|
GetMimetype,
|
|
GetResource,
|
|
).PrepareForEval(ctx)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
result, err := q.Eval(ctx, rego.EvalInput(env))
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
return result.Allowed(), nil
|
|
}
|
|
|
|
var GetResource = rego.Function1(
|
|
®o.Function{
|
|
Name: "ocis_get_resource",
|
|
Decl: types.NewFunction(types.Args(types.S), types.A),
|
|
Memoize: true,
|
|
Nondeterministic: true,
|
|
},
|
|
func(_ rego.BuiltinContext, a *ast.Term) (*ast.Term, error) {
|
|
var url string
|
|
|
|
if err := ast.As(a.Value, &url); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
req, err := http.NewRequest(http.MethodGet, url, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
client := rhttp.GetHTTPClient(rhttp.Insecure(true))
|
|
res, err := client.Do(req)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer res.Body.Close()
|
|
|
|
if res.StatusCode != http.StatusOK {
|
|
return nil, fmt.Errorf("unexpected status code from Download %v", res.StatusCode)
|
|
}
|
|
|
|
buf := new(bytes.Buffer)
|
|
if _, err := buf.ReadFrom(res.Body); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
v, err := ast.InterfaceToValue(buf.Bytes())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return ast.NewTerm(v), nil
|
|
},
|
|
)
|
|
|
|
var GetMimetype = rego.Function1(
|
|
®o.Function{
|
|
Name: "ocis_get_mimetype",
|
|
Decl: types.NewFunction(types.Args(types.A), types.S),
|
|
Memoize: true,
|
|
Nondeterministic: true,
|
|
},
|
|
func(_ rego.BuiltinContext, a *ast.Term) (*ast.Term, error) {
|
|
var body []byte
|
|
|
|
if err := ast.As(a.Value, &body); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
mimeInfo := mimetype.Detect(body).String()
|
|
detectedMimetype := strings.Split(mimeInfo, ";")[0]
|
|
v, err := ast.InterfaceToValue(detectedMimetype)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return ast.NewTerm(v), nil
|
|
},
|
|
)
|