Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
107 changes: 107 additions & 0 deletions test/e2e_test/smoke/proxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/stretchr/testify/suite"

"github.com/goto/shield/config"
"github.com/goto/shield/internal/store/postgres"
"github.com/goto/shield/pkg/db"
shieldv1beta1 "github.com/goto/shield/proto/v1beta1"
"github.com/goto/shield/test/e2e_test/testbench"
Expand Down Expand Up @@ -101,6 +102,36 @@ func (s *EndToEndProxySmokeTestSuite) TestProxyToEchoServer() {
defer res.Body.Close()
s.Assert().Equal(200, res.StatusCode)
})

s.Run("user not part of group will not be authenticated by middleware auth", func() {
groupDetail, err := s.client.GetGroup(context.Background(), &shieldv1beta1.GetGroupRequest{Id: s.groupID})
s.Require().NoError(err)

url := fmt.Sprintf("http://localhost:%d/api/resource_slug", s.appConfig.Proxy.Services[0].Port)
reqBodyMap := map[string]string{
"project": s.projID,
"name": "test-resource-group-slug",
"group_slug": groupDetail.GetGroup().GetSlug(),
}
reqBodyBytes, err := json.Marshal(reqBodyMap)
s.Require().NoError(err)

req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(reqBodyBytes))
s.Require().NoError(err)

req.Header.Set(testbench.IdentityHeader, "[email protected]")
req.Header.Set("X-Shield-Org", s.orgID)

res, err := http.DefaultClient.Do(req)
s.Require().NoError(err)

defer res.Body.Close()

s.Assert().Equal(401, res.StatusCode)
})
}

func (s *EndToEndProxySmokeTestSuite) TestResourceRelation() {
s.Run("resource created on echo server should persist in shieldDB", func() {
url := fmt.Sprintf("http://localhost:%d/api/resource", s.appConfig.Proxy.Services[0].Port)
reqBodyMap := map[string]string{
Expand Down Expand Up @@ -369,6 +400,7 @@ func (s *EndToEndProxySmokeTestSuite) TestProxyToEchoServer() {
}
s.Assert().Equal(s.userID, subjectID)
})

s.Run("resource created on echo server should persist in shieldDB when using user e-mail", func() {
userDetail, err := s.client.GetUser(context.Background(), &shieldv1beta1.GetUserRequest{Id: s.userID})
s.Require().NoError(err)
Expand Down Expand Up @@ -423,6 +455,81 @@ func (s *EndToEndProxySmokeTestSuite) TestProxyToEchoServer() {
})
}

func (s *EndToEndProxySmokeTestSuite) TestEdgeCases() {
s.Run("Two relations created in POST hook won't be overwritten when 1 relation in PUT hook is created", func() {
var (
resourceName = "test-resource-overwrite"
staticGroupUUID = "6b591fe0-fc94-4fd2-82bc-45f8a5d12a88"
)

userDetail, err := s.client.GetUser(context.Background(), &shieldv1beta1.GetUserRequest{Id: s.userID})
s.Require().NoError(err)
sqlRes, err := s.dbClient.DB.Exec(fmt.Sprintf("UPDATE groups SET id = '%s' WHERE slug = 'org1-group3'", staticGroupUUID))
s.Require().NoError(err)
rowsAffected, err := sqlRes.RowsAffected()
s.Require().NoError(err)
s.Require().Equal(int64(1), rowsAffected)

// POST
url := fmt.Sprintf("http://localhost:%d/api/resource", s.appConfig.Proxy.Services[0].Port)
reqBodyMap := map[string]string{
"project": s.projID,
"group": s.groupID,
"name": resourceName,
"user_email": userDetail.GetUser().GetEmail(),
}
reqBodyBytes, err := json.Marshal(reqBodyMap)
s.Require().NoError(err)

req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(reqBodyBytes))
s.Require().NoError(err)

req.Header.Set(testbench.IdentityHeader, "[email protected]")
req.Header.Set("X-Shield-Org", s.orgID)

res, err := http.DefaultClient.Do(req)
s.Require().NoError(err)
defer res.Body.Close()

s.Require().Equal(200, res.StatusCode)

// Validate resource & relation
var resourceShield = struct {
ID string `db:"id"`
Name string `db:"name"`
}{}

s.Require().NoError(s.dbClient.DB.Get(&resourceShield, fmt.Sprintf("SELECT id, name FROM resources WHERE name = '%s'", resourceName)))
s.Assert().Equal(resourceShield.Name, resourceName)

var relationsShield []postgres.Relation
s.Require().NoError(s.dbClient.DB.Select(&relationsShield, "SELECT * FROM relations WHERE role_id = 'entropy/firehose:owner'"))
s.Assert().Len(relationsShield, 2)

// PUT
req, err = http.NewRequest(http.MethodPut, url, bytes.NewBuffer(reqBodyBytes))
s.Require().NoError(err)

req.Header.Set(testbench.IdentityHeader, "[email protected]")
req.Header.Set("X-Shield-Org", s.orgID)

res, err = http.DefaultClient.Do(req)
s.Require().NoError(err)
defer res.Body.Close()

s.Require().Equal(200, res.StatusCode)

// Validate resource & relation
s.Require().NoError(s.dbClient.DB.Get(&resourceShield, fmt.Sprintf("SELECT id, name FROM resources WHERE name = '%s'", resourceName)))
s.Assert().Equal(resourceShield.Name, resourceName)

var updatedRelations []postgres.Relation
s.Require().NoError(s.dbClient.DB.Select(&updatedRelations, "SELECT * FROM relations WHERE role_id = 'entropy/firehose:owner'"))
fmt.Println(updatedRelations)
s.Assert().Len(updatedRelations, 2)
})
}

func TestEndToEndProxySmokeTestSuite(t *testing.T) {
suite.Run(t, new(EndToEndProxySmokeTestSuite))
}
34 changes: 34 additions & 0 deletions test/e2e_test/testbench/mockserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,38 @@ func startMockServer(ctx context.Context, logger *log.Zap, port int) {

reqBody["org"] = orgName
reqBody["urn"] = reqBody["name"]
reqBody["api"] = "POST"

respBytes, err := json.Marshal(reqBody)
if err != nil {
internalServerErrorWriter(w)
return
}

w.Write(respBytes)
}
updateResourceFn = func(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
b, err := io.ReadAll(r.Body)
defer r.Body.Close()
if err != nil {
internalServerErrorWriter(w)
return
}

var reqBody map[string]string
if err := json.Unmarshal(b, &reqBody); err != nil {
internalServerErrorWriter(w)
return
}

var orgName = ""
if hOrg, ok := r.Header["X-Shield-Org"]; ok {
orgName = hOrg[0]
}

reqBody["org"] = orgName
reqBody["urn"] = reqBody["name"]
reqBody["api"] = "PUT"

respBytes, err := json.Marshal(reqBody)
if err != nil {
Expand All @@ -54,6 +86,8 @@ func startMockServer(ctx context.Context, logger *log.Zap, port int) {
w.Write([]byte("pong"))
})
router.POST("/api/resource", createResourceFn)
router.PUT("/api/resource", updateResourceFn)

router.POST("/api/resource_slug", createResourceFn)
router.POST("/api/resource_user_id", createResourceFn)
router.POST("/api/resource_user_email", createResourceFn)
Expand Down
6 changes: 3 additions & 3 deletions test/e2e_test/testbench/testbench.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ func initTestBench(ctx context.Context, appConfig *config.Shield, mockServerPort
URL: connMainPGExternal,
MaxIdleConns: 10,
MaxOpenConns: 10,
ConnMaxLifeTime: time.Millisecond * 100,
MaxQueryTimeoutInMS: time.Millisecond * 100,
ConnMaxLifeTime: time.Millisecond * 1000,
MaxQueryTimeoutInMS: time.Millisecond * 1000,
}

te.SpiceDBConfig = spicedb.Config{
Expand Down Expand Up @@ -256,7 +256,7 @@ func SetupTests(t *testing.T) (shieldv1beta1.ShieldServiceClient, *config.Shield
if err := BootstrapGroup(ctx, client, OrgAdminEmail, testDataPath); err != nil {
t.Fatal(err)
}
time.Sleep(10 * time.Second)
time.Sleep(5 * time.Second)
if err := AssignGroupManager(ctx, client, OrgAdminEmail); err != nil {
t.Fatal(err)
}
Expand Down
37 changes: 37 additions & 0 deletions test/e2e_test/testbench/testdata/configs/rules/rule.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,43 @@ rules:
- name: create_resource
path: "/api/resource"
method: "POST"
hooks:
- name: authz
config:
action: authz_action
attributes:
resource:
key: urn
type: json_payload
source: response
project:
key: project
type: json_payload
source: request
group:
key: group
type: json_payload
source: request
organization:
key: X-Shield-Org
type: header
source: request
resource_type:
value: "firehose"
type: constant
additional_group:
value: 6b591fe0-fc94-4fd2-82bc-45f8a5d12a88
type: constant
relations:
- role: owner
subject_principal: shield/group
subject_id_attribute: group
- role: owner
subject_principal: shield/group
subject_id_attribute: additional_group
- name: update_resource
path: "/api/resource"
method: "PUT"
hooks:
- name: authz
config:
Expand Down
37 changes: 37 additions & 0 deletions test/e2e_test/testbench/testdata/configs/rules/rule.yamltpl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,43 @@ rules:
- name: create_resource
path: "/api/resource"
method: "POST"
hooks:
- name: authz
config:
action: authz_action
attributes:
resource:
key: urn
type: json_payload
source: response
project:
key: project
type: json_payload
source: request
group:
key: group
type: json_payload
source: request
organization:
key: X-Shield-Org
type: header
source: request
resource_type:
value: "firehose"
type: constant
additional_group:
value: 6b591fe0-fc94-4fd2-82bc-45f8a5d12a88
type: constant
relations:
- role: owner
subject_principal: shield/group
subject_id_attribute: group
- role: owner
subject_principal: shield/group
subject_id_attribute: additional_group
- name: update_resource
path: "/api/resource"
method: "PUT"
hooks:
- name: authz
config:
Expand Down