Skip to content

Commit

Permalink
Merge pull request #24 from axone-protocol/feat/gov-exec
Browse files Browse the repository at this point in the history
Feat/gov exec
  • Loading branch information
amimart committed Sep 10, 2024
2 parents 713c68e + b328ae3 commit 95bee02
Show file tree
Hide file tree
Showing 15 changed files with 572 additions and 30 deletions.
3 changes: 3 additions & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ignore:
- "testutil/"
- "scripts/"
1 change: 1 addition & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ issues:
linters:
- dupl
- funlen
- goconst
- path: "_test\\.go"
linters:
- revive
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ mock: ## Generate all the mocks (for tests)
@mockgen -source=credential/parser.go -package testutil -destination testutil/credential_mocks.go
@mockgen -package testutil -destination testutil/dataverse_client_mocks.go -mock_names QueryClient=MockDataverseQueryClient github.com/axone-protocol/axone-contract-schema/go/dataverse-schema/v5 QueryClient
@mockgen -package testutil -destination testutil/cognitarium_client_mocks.go -mock_names QueryClient=MockCognitariumQueryClient github.com/axone-protocol/axone-contract-schema/go/cognitarium-schema/v5 QueryClient
@mockgen -package testutil -destination testutil/law_stone_client_mocks.go -mock_names QueryClient=MockLawStoneQueryClient github.com/axone-protocol/axone-contract-schema/go/law-stone-schema/v5 QueryClient
@mockgen -package testutil -destination testutil/signer_mocks.go github.com/hyperledger/aries-framework-go/pkg/doc/verifiable Signer
@mockgen -source=credential/generate.go -package testutil -destination testutil/generate_mocks.go

Expand Down
7 changes: 3 additions & 4 deletions auth/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,13 @@ func (a *authProxy) Authenticate(ctx context.Context, credential []byte) (*Ident
return nil, fmt.Errorf("credential not intended for this service: `%s` (target: `%s`)", a.serviceID, authClaim.ToService)
}

// TODO: get authorized actions from governance, ex:
res, err := a.dvClient.ExecGov(ctx, a.govAddr, fmt.Sprintf("can(Action,'%s').", authClaim.ID))
actions, err := a.dvClient.AskGovPermittedActions(ctx, a.govAddr, authClaim.ID)
if err != nil {
return nil, err
return nil, fmt.Errorf("failed to query governance for permitted actions: %w", err)
}

return &Identity{
DID: authClaim.ID,
AuthorizedActions: res.([]string),
AuthorizedActions: actions,
}, nil
}
2 changes: 1 addition & 1 deletion auth/proxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func TestAuthProxy_Authenticate(t *testing.T) {
}

mockDataverse := testutil.NewMockClient(controller)
mockDataverse.EXPECT().ExecGov(gomock.Any(), gomock.Any(), gomock.Any()).Return([]string(nil), nil).MaxTimes(1)
mockDataverse.EXPECT().AskGovPermittedActions(gomock.Any(), gomock.Any(), gomock.Any()).Return([]string(nil), nil).MaxTimes(1)

aProxy := auth.NewProxy(
"did:key:zQ3shZxyDoD3QorxHJrFS68EjzDgQZSqZcj3wQqc1ngbF1vgz",
Expand Down
23 changes: 22 additions & 1 deletion dataverse/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

cgschema "github.com/axone-protocol/axone-contract-schema/go/cognitarium-schema/v5"
dvschema "github.com/axone-protocol/axone-contract-schema/go/dataverse-schema/v5"
lsschema "github.com/axone-protocol/axone-contract-schema/go/law-stone-schema/v5"
"google.golang.org/grpc"
)

Expand All @@ -14,12 +15,29 @@ type Client interface {
// It queries the cognitarium to get the governance address (law-stone contract address)
// of a resource. The resource is identified by its DID.
GetResourceGovAddr(context.Context, string) (string, error)
ExecGov(context.Context, string, string) (interface{}, error)

// AskGovPermittedActions returns the permitted actions for a resource identified by its DID.
// It queries the law-stone contract to get the permitted actions for a resource using the following predicate:
// ```prolog
// tell_permitted_actions(DID, Actions).
// ```
AskGovPermittedActions(context.Context, string, string) ([]string, error)

// AskGovTellAction queries the law-stone contract to check if a given action is permitted for a resource.
// It uses the following predicate:
// ```prolog
// tell(DID, Action, Result, Evidence).
// ```
// The function returns true if Result is 'permitted', false otherwise.
AskGovTellAction(context.Context, string, string, string) (bool, error)
}

type LawStoneFactory func(string) (lsschema.QueryClient, error)

type client struct {
dataverseClient dvschema.QueryClient
cognitariumClient cgschema.QueryClient
lawStoneFactory LawStoneFactory
}

func NewClient(ctx context.Context,
Expand All @@ -44,6 +62,9 @@ func NewClient(ctx context.Context,
return &client{
dataverseClient,
cognitariumClient,
func(addr string) (lsschema.QueryClient, error) {
return lsschema.NewQueryClient(grpcAddr, addr, opts...)
},
}, nil
}

Expand Down
2 changes: 2 additions & 0 deletions dataverse/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ import (
func NewDataverseClient(
dataverseClient dvschema.QueryClient,
cognitariumClient cgschema.QueryClient,
lawStoneFactory LawStoneFactory,
) Client {
return &client{
dataverseClient,
cognitariumClient,
lawStoneFactory,
}
}

Expand Down
51 changes: 49 additions & 2 deletions dataverse/governance.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package dataverse
import (
"context"
"fmt"
"strings"

cgschema "github.com/axone-protocol/axone-contract-schema/go/cognitarium-schema/v5"
lsschema "github.com/axone-protocol/axone-contract-schema/go/law-stone-schema/v5"
)

func (c *client) GetResourceGovAddr(ctx context.Context, resourceDID string) (string, error) {
Expand All @@ -29,6 +31,51 @@ func (c *client) GetResourceGovAddr(ctx context.Context, resourceDID string) (st
return string(*code.Value.Full), nil
}

func (c *client) ExecGov(_ context.Context, _ string, _ string) (interface{}, error) {
panic("not implemented")
func (c *client) AskGovPermittedActions(ctx context.Context, addr, did string) ([]string, error) {
gov, err := c.lawStoneFactory(addr)
if err != nil {
return nil, fmt.Errorf("failed to create law-stone client: %w", err)
}

response, err := gov.Ask(ctx, &lsschema.QueryMsg_Ask{Query: fmt.Sprintf("tell_permitted_actions('%s',Actions).", did)})
if err != nil {
return nil, fmt.Errorf("failed to query law-stone contract: %w", err)
}

if len(response.Answer.Results) != 1 {
return nil, nil
}
if len(response.Answer.Results[0].Substitutions) != 1 {
return nil, nil
}

result := response.Answer.Results[0].Substitutions[0].Expression
result = result[1 : len(result)-1]
actions := make([]string, 0)
for _, action := range strings.Split(result, ",") {
actions = append(actions, strings.Trim(action, "'"))
}

return actions, nil
}

func (c *client) AskGovTellAction(ctx context.Context, addr, did, action string) (bool, error) {
gov, err := c.lawStoneFactory(addr)
if err != nil {
return false, fmt.Errorf("failed to create law-stone client: %w", err)
}

response, err := gov.Ask(ctx, &lsschema.QueryMsg_Ask{Query: fmt.Sprintf("tell('%s','%s',Result,_).", did, action)})
if err != nil {
return false, fmt.Errorf("failed to query law-stone contract: %w", err)
}

if len(response.Answer.Results) != 1 {
return false, nil
}
if len(response.Answer.Results[0].Substitutions) != 1 {
return false, nil
}

return response.Answer.Results[0].Substitutions[0].Expression == "permitted", nil
}
Loading

0 comments on commit 95bee02

Please sign in to comment.