Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Models Fixes #60

Merged
merged 5 commits into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api/collections_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
func TestCollections(t *testing.T) {
app, core := InitTestingVault(t)

customerCollection := _vault.Collection{
customerCollection := &_vault.Collection{
Name: "customers",
Fields: map[string]_vault.Field{
"name": {Type: "name", IsIndexed: true},
Expand Down
6 changes: 4 additions & 2 deletions api/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,9 @@ func (core *Core) Init() error {
panic(err)
}
}
rootPolicyId := _vault.GenerateId("pol")
err := core.vault.Db.CreatePolicy(ctx, &_vault.Policy{
Id: rootPolicyId,
Name: "root",
Effect: _vault.EffectAllow,
Actions: []_vault.PolicyAction{_vault.PolicyActionWrite, _vault.PolicyActionRead},
Expand All @@ -171,8 +173,8 @@ func (core *Core) Init() error {
Username: core.conf.ADMIN_USERNAME,
Password: core.conf.ADMIN_PASSWORD,
Description: "admin",
Policies: []string{"root"}}
err = core.vault.CreatePrincipal(ctx, adminPrincipal, &_vault.Principal{Username: adminPrincipal.Username, Password: adminPrincipal.Password, Description: adminPrincipal.Description, Policies: adminPrincipal.Policies})
Policies: []string{rootPolicyId}}
err = core.vault.CreatePrincipal(ctx, adminPrincipal, &adminPrincipal) // The admin bootstraps himself

var co *_vault.ConflictError
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion api/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ go 1.21

require (
github.com/go-playground/assert/v2 v2.2.0
github.com/go-playground/validator/v10 v10.16.0
github.com/gofiber/fiber/v2 v2.51.0
github.com/joho/godotenv v1.3.0
github.com/knadh/koanf v1.5.0
Expand All @@ -29,6 +28,7 @@ require (
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.16.0 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
Expand Down
16 changes: 9 additions & 7 deletions api/policies_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ import (
func TestPolicies(t *testing.T) {
app, core := InitTestingVault(t)

testPolicyId := "test-policy"
testPolicyId := ""
testResource := "/resources/stuff"

t.Run("can create policy", func(t *testing.T) {
testPolicy := _vault.Policy{
Name: testPolicyId,
Name: "test-policy",
Effect: _vault.EffectAllow,
Actions: []_vault.PolicyAction{_vault.PolicyActionRead},
Resources: []string{fmt.Sprintf("/policies/%s", testPolicyId)},
Resources: []string{testResource},
}

request := newRequest(t, http.MethodPost, "/policies", map[string]string{
Expand All @@ -29,11 +30,12 @@ func TestPolicies(t *testing.T) {
response := performRequest(t, app, request)
var createdPolicy _vault.Policy
checkResponse(t, response, http.StatusCreated, &createdPolicy)
testPolicyId = createdPolicy.Id

// Assertions
assert.Equal(t, _vault.EffectAllow, createdPolicy.Effect)
assert.Equal(t, []_vault.PolicyAction{_vault.PolicyActionRead}, createdPolicy.Actions)
assert.Equal(t, []string{fmt.Sprintf("/policies/%s", testPolicyId)}, createdPolicy.Resources)
assert.Equal(t, []string{testResource}, createdPolicy.Resources)
})

t.Run("can get policy", func(t *testing.T) {
Expand All @@ -48,7 +50,7 @@ func TestPolicies(t *testing.T) {
// Assertions
assert.Equal(t, _vault.EffectAllow, returnedPolicy.Effect)
assert.Equal(t, []_vault.PolicyAction{_vault.PolicyActionRead}, returnedPolicy.Actions)
assert.Equal(t, []string{fmt.Sprintf("/policies/%s", testPolicyId)}, returnedPolicy.Resources)
assert.Equal(t, []string{testResource}, returnedPolicy.Resources)
})

t.Run("can delete policy", func(t *testing.T) {
Expand All @@ -69,15 +71,15 @@ func TestPolicies(t *testing.T) {
checkResponse(t, response, http.StatusCreated, &returnedPolicy)

// Delete it
request = newRequest(t, http.MethodDelete, fmt.Sprintf("/policies/%s", dummyPolicy.Id), map[string]string{
request = newRequest(t, http.MethodDelete, fmt.Sprintf("/policies/%s", returnedPolicy.Id), map[string]string{
"Authorization": createBasicAuthHeader(core.conf.ADMIN_USERNAME, core.conf.ADMIN_PASSWORD),
}, nil)

response = performRequest(t, app, request)
checkResponse(t, response, http.StatusNoContent, nil)

// Check it's gone
request = newRequest(t, http.MethodGet, fmt.Sprintf("/policies/%s", dummyPolicy.Id), map[string]string{
request = newRequest(t, http.MethodGet, fmt.Sprintf("/policies/%s", returnedPolicy.Id), map[string]string{
"Authorization": createBasicAuthHeader(core.conf.ADMIN_USERNAME, core.conf.ADMIN_PASSWORD),
}, nil)

Expand Down
17 changes: 13 additions & 4 deletions api/testing_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ import (
_vault "github.com/subrose/vault"
)

var adminPrincipal = _vault.Principal{Username: "admin", Password: "admin", Policies: []string{"root"}}
var rootPolicyId = _vault.GenerateId("pol")
var adminPrincipal = _vault.Principal{Username: "admin", Password: "admin", Policies: []string{rootPolicyId}}

func InitTestingVault(t *testing.T) (*fiber.App, *Core) {
// Read environment variables if a test.env file exists, error is ignored on purpose
_ = godotenv.Load("test.env")
_ = godotenv.Load("../test.env")

coreConfig, err := ReadConfigs()
if err != nil {
Expand Down Expand Up @@ -50,13 +51,15 @@ func InitTestingVault(t *testing.T) (*fiber.App, *Core) {
if err != nil {
t.Fatal("Failed to create logger", err)
}
vault := _vault.Vault{Db: db, Priv: priv, Logger: vaultLogger, Signer: signer}
vault := _vault.Vault{Db: db, Priv: priv, Logger: vaultLogger, Signer: signer, Validator: _vault.NewValidator()}
bootstrapContext := context.Background()
err = vault.Db.Flush(bootstrapContext)
if err != nil {
t.Fatal("Failed to flush db", err)
}

err = db.CreatePolicy(bootstrapContext, &_vault.Policy{
Id: rootPolicyId,
Name: "root",
Effect: _vault.EffectAllow,
Actions: []_vault.PolicyAction{_vault.PolicyActionRead, _vault.PolicyActionWrite},
Expand All @@ -67,7 +70,13 @@ func InitTestingVault(t *testing.T) (*fiber.App, *Core) {
t.Fatal("Failed to create root policy", err)
}

err = vault.CreatePrincipal(bootstrapContext, adminPrincipal, &_vault.Principal{Username: coreConfig.ADMIN_USERNAME, Password: coreConfig.ADMIN_PASSWORD, Description: "admin principal", Policies: []string{"root"}})
err = vault.CreatePrincipal(bootstrapContext, adminPrincipal, &_vault.Principal{
Id: _vault.GenerateId("prin"),
Username: coreConfig.ADMIN_USERNAME,
Password: coreConfig.ADMIN_PASSWORD,
Description: "admin principal",
Policies: []string{rootPolicyId},
})
if err != nil {
t.Fatal("Failed to create admin principal", err)
}
Expand Down
5 changes: 3 additions & 2 deletions simulator/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@


class Policy(BaseModel):
policy_id: str
name: Optional[str] = None
effect: str
actions: List[str]
resources: List[str]
Expand Down Expand Up @@ -134,13 +134,14 @@ def get_record(

def create_policy(
self, policy: Policy, expected_statuses: Optional[list[int]] = None
) -> None:
) -> dict[str, str]:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very nitpicky, but fyi .json() returns Any, not dict (same for json.loads)

response = requests.post(
f"{self.vault_url}/policies",
auth=(self.username, self.password),
json=policy.model_dump(),
)
check_expected_status(response, expected_statuses)
return response.json()

def get_policy(
self, policy_id: str, expected_statuses: Optional[list[int]] = None
Expand Down
15 changes: 6 additions & 9 deletions simulator/ecommerce.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,8 @@

# Create policies
# Backend can write customer details
admin.create_policy(
backend_policy = admin.create_policy(
policy=Policy(
policy_id="backend",
effect="allow",
actions=["write"],
resources=["/collections/customers/*"],
Expand All @@ -47,9 +46,8 @@
)

# Marketing can read masked records
admin.create_policy(
marketing_policy = admin.create_policy(
policy=Policy(
policy_id="marketing",
effect="allow",
actions=["read"],
resources=[
Expand All @@ -60,9 +58,8 @@
)

# Customer service team can read all customer details in plain
admin.create_policy(
cs_policy = admin.create_policy(
policy=Policy(
policy_id="customer-service",
effect="allow",
actions=["read"],
resources=[
Expand All @@ -83,23 +80,23 @@
username=backend.username,
password=backend.password,
description="backend",
policies=["backend"],
policies=[backend_policy["id"]],
expected_statuses=[201, 409],
)

admin.create_principal(
username=marketing.username,
password=marketing.password,
description="marketing",
policies=["marketing"],
policies=[marketing_policy["id"]],
expected_statuses=[201, 409],
)

admin.create_principal(
username=customer_service.username,
password=customer_service.password,
description="customer-service",
policies=["customer-service"],
policies=[cs_policy["id"]],
expected_statuses=[201, 409],
)

Expand Down
9 changes: 4 additions & 5 deletions simulator/ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,8 @@


# Create a temporary policy for somebody
admin.create_policy(
temp_policy = admin.create_policy(
policy=Policy(
policy_id="secret-access",
effect="allow",
actions=["read", "write"],
resources=["/collections/secrets/*"],
Expand All @@ -52,7 +51,7 @@
username=SOMEBODY_USERNAME,
password=SOMEBODY_PASSWORD,
description="somebody",
policies=["secret-access"],
policies=[temp_policy["id"]],
expected_statuses=[201, 409],
)

Expand All @@ -68,13 +67,13 @@

# Policy is removed
admin.delete_policy(
policy_id="secret-access",
policy_id=temp_policy["id"],
expected_statuses=[204],
)

# Policy is removed twice for good measure
admin.delete_policy(
policy_id="secret-access",
policy_id=temp_policy["id"],
expected_statuses=[404],
)

Expand Down
10 changes: 4 additions & 6 deletions simulator/password_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,8 @@

# Step 3: Create policies using admin role

admin.create_policy(
alice_policy = admin.create_policy(
policy=Policy(
policy_id="alice-access-own_passwords",
effect="allow",
actions=["read", "write"],
resources=["/collections/alice_passwords/*"],
Expand All @@ -51,9 +50,8 @@
)


admin.create_policy(
bob_policy = admin.create_policy(
policy=Policy(
policy_id="bob-access-own_passwords",
effect="allow",
actions=["read", "write"],
resources=["/collections/bob_passwords/*"],
Expand All @@ -65,7 +63,7 @@
username=ALICE_USERNAME,
password=ALICE_PASSWORD,
description="alice",
policies=["alice-access-own_passwords"],
policies=[alice_policy["id"]],
expected_statuses=[201, 409],
)

Expand All @@ -76,7 +74,7 @@
username=BOB_USERNAME,
password=BOB_PASSWORD,
description="bob",
policies=["bob-access-own_passwords"],
policies=[bob_policy["id"]],
expected_statuses=[201, 409],
)

Expand Down
15 changes: 6 additions & 9 deletions simulator/pci.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,8 @@

# Create policies
# Backend can write customer details
admin.create_policy(
backend_policy = admin.create_policy(
policy=Policy(
policy_id="backend-ccs",
effect="allow",
actions=["write"],
resources=["/collections/credit_cards/*"],
Expand All @@ -37,9 +36,8 @@
)

# CS can read masked records
admin.create_policy(
cs_policy = admin.create_policy(
policy=Policy(
policy_id="cs-ccs",
effect="allow",
actions=["read"],
resources=[
Expand All @@ -50,9 +48,8 @@
)

# Proxy service can read plain for forwarding to payment gateway
admin.create_policy(
proxy_policy = admin.create_policy(
policy=Policy(
policy_id="proxy-ccs",
effect="allow",
actions=["read"],
resources=[
Expand All @@ -71,23 +68,23 @@
username=backend.username,
password=backend.password,
description="backend",
policies=["backend-ccs"],
policies=[backend_policy["id"]],
expected_statuses=[201, 409],
)

admin.create_principal(
username=cs.username,
password=cs.password,
description="cs",
policies=["cs-ccs"],
policies=[cs_policy["id"]],
expected_statuses=[201, 409],
)

admin.create_principal(
username=proxy.username,
password=proxy.password,
description="proxy",
policies=["proxy-ccs"],
policies=[proxy_policy["id"]],
expected_statuses=[201, 409],
)

Expand Down
File renamed without changes.
Loading