Skip to content
This repository has been archived by the owner on Feb 18, 2021. It is now read-only.

Commit

Permalink
Add auth check for DeleteDestination (#220)
Browse files Browse the repository at this point in the history
* Add auth check for DeleteDestination

* Use tenancy in deployment name for auth check
  • Loading branch information
Bo Yang authored Jun 12, 2017
1 parent b7cadd7 commit 41c2717
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 36 deletions.
21 changes: 12 additions & 9 deletions common/auth_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import (

const (
resourceURNTemplateCreateDestination = "urn:cherami:dst:%v:%v"
resourceURNTemplateReadDestination = "urn:cherami:dst:%v:%v"
resourceURNTemplateOperateDestination = "urn:cherami:dst:%v:%v"
resourceURNTemplateCreateConsumerGroup = "urn:cherami:cg:%v:%v"
)

Expand All @@ -40,21 +40,19 @@ func GetResourceURNCreateDestination(scommon SCommon, dstPath *string) string {
} else {
dstPathString = getPathRootName(dstPath)
}
deploymentName := scommon.GetConfig().GetDeploymentName()
return fmt.Sprintf(resourceURNTemplateCreateDestination, strings.ToLower(deploymentName), strings.ToLower(dstPathString))
return fmt.Sprintf(resourceURNTemplateCreateDestination, getTenancyLowerCase(scommon), strings.ToLower(dstPathString))
}

// GetResourceURNReadDestination returns the resource URN to read destination, e.g. urn:cherami:dst:zone1_prod:/dst_prefix/dst1
// GetResourceURNOperateDestination returns the resource URN to operate destination (read, delete), e.g. urn:cherami:dst:zone1_prod:/dst_prefix/dst1
// We use URN (Uniform Resource Name) like this: https://www.ietf.org/rfc/rfc2141.txt
func GetResourceURNReadDestination(scommon SCommon, dstPath *string) string {
func GetResourceURNOperateDestination(scommon SCommon, dstPath *string) string {
var dstPathString string
if dstPath == nil {
dstPathString = ""
} else {
dstPathString = *dstPath
}
deploymentName := scommon.GetConfig().GetDeploymentName()
return fmt.Sprintf(resourceURNTemplateReadDestination, strings.ToLower(deploymentName), strings.ToLower(dstPathString))
return fmt.Sprintf(resourceURNTemplateOperateDestination, getTenancyLowerCase(scommon), strings.ToLower(dstPathString))
}

// GetResourceURNCreateConsumerGroup returns the resource URN to create consumer group, e.g. urn:cherami:dst:zone1_prod:/cg_prefix
Expand All @@ -66,8 +64,7 @@ func GetResourceURNCreateConsumerGroup(scommon SCommon, cgPath *string) string {
} else {
cgPathString = getPathRootName(cgPath)
}
deploymentName := scommon.GetConfig().GetDeploymentName()
return fmt.Sprintf(resourceURNTemplateCreateConsumerGroup, strings.ToLower(deploymentName), strings.ToLower(cgPathString))
return fmt.Sprintf(resourceURNTemplateCreateConsumerGroup, getTenancyLowerCase(scommon), strings.ToLower(cgPathString))
}

func getPathRootName(path *string) string {
Expand All @@ -83,3 +80,9 @@ func getPathRootName(path *string) string {

return parts[0]
}

func getTenancyLowerCase(scommon SCommon) string {
deploymentName := scommon.GetConfig().GetDeploymentName()
parts := strings.Split(deploymentName, "_")
return strings.ToLower(parts[0])
}
38 changes: 19 additions & 19 deletions common/auth_util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,35 +66,35 @@ func (s *AuthUtilSuite) TestGetResourceURNCreateDestination() {
s.Equal("urn:cherami:dst:zone1:/", GetResourceURNCreateDestination(mockService, StringPtr("//")))

config.deploymentName = "Zone2_ABC"
s.Equal("urn:cherami:dst:zone2_abc:/dst1", GetResourceURNCreateDestination(mockService, StringPtr("/Dst1")))
s.Equal("urn:cherami:dst:zone2_abc:/root2", GetResourceURNCreateDestination(mockService, StringPtr("/Root2/Dst2")))
s.Equal("urn:cherami:dst:zone2:/dst1", GetResourceURNCreateDestination(mockService, StringPtr("/Dst1")))
s.Equal("urn:cherami:dst:zone2:/root2", GetResourceURNCreateDestination(mockService, StringPtr("/Root2/Dst2")))

s.Equal("urn:cherami:dst:zone2_abc:dst2", GetResourceURNCreateDestination(mockService, StringPtr("Dst2")))
s.Equal("urn:cherami:dst:zone2_abc:root2", GetResourceURNCreateDestination(mockService, StringPtr("Root2/Dst2")))
s.Equal("urn:cherami:dst:zone2:dst2", GetResourceURNCreateDestination(mockService, StringPtr("Dst2")))
s.Equal("urn:cherami:dst:zone2:root2", GetResourceURNCreateDestination(mockService, StringPtr("Root2/Dst2")))
}

func (s *AuthUtilSuite) TestGetResourceURNReadDestination() {
func (s *AuthUtilSuite) TestGetResourceURNOperateDestination() {
mockService := new(MockService)

config := &serviceConfig{}

mockService.On("GetConfig").Return(config)

s.Equal("urn:cherami:dst::", GetResourceURNReadDestination(mockService, nil))
s.Equal("urn:cherami:dst::", GetResourceURNReadDestination(mockService, StringPtr("")))
s.Equal("urn:cherami:dst::", GetResourceURNOperateDestination(mockService, nil))
s.Equal("urn:cherami:dst::", GetResourceURNOperateDestination(mockService, StringPtr("")))

config.deploymentName = "zone1"
s.Equal("urn:cherami:dst:zone1:", GetResourceURNReadDestination(mockService, nil))
s.Equal("urn:cherami:dst:zone1:", GetResourceURNReadDestination(mockService, StringPtr("")))
s.Equal("urn:cherami:dst:zone1:/", GetResourceURNReadDestination(mockService, StringPtr("/")))
s.Equal("urn:cherami:dst:zone1://", GetResourceURNReadDestination(mockService, StringPtr("//")))
s.Equal("urn:cherami:dst:zone1:", GetResourceURNOperateDestination(mockService, nil))
s.Equal("urn:cherami:dst:zone1:", GetResourceURNOperateDestination(mockService, StringPtr("")))
s.Equal("urn:cherami:dst:zone1:/", GetResourceURNOperateDestination(mockService, StringPtr("/")))
s.Equal("urn:cherami:dst:zone1://", GetResourceURNOperateDestination(mockService, StringPtr("//")))

config.deploymentName = "Zone2_ABC"
s.Equal("urn:cherami:dst:zone2_abc:/dst1", GetResourceURNReadDestination(mockService, StringPtr("/Dst1")))
s.Equal("urn:cherami:dst:zone2_abc:/root2/dst2", GetResourceURNReadDestination(mockService, StringPtr("/Root2/Dst2")))
s.Equal("urn:cherami:dst:zone2:/dst1", GetResourceURNOperateDestination(mockService, StringPtr("/Dst1")))
s.Equal("urn:cherami:dst:zone2:/root2/dst2", GetResourceURNOperateDestination(mockService, StringPtr("/Root2/Dst2")))

s.Equal("urn:cherami:dst:zone2_abc:dst2", GetResourceURNReadDestination(mockService, StringPtr("Dst2")))
s.Equal("urn:cherami:dst:zone2_abc:root2/dst2", GetResourceURNReadDestination(mockService, StringPtr("Root2/Dst2")))
s.Equal("urn:cherami:dst:zone2:dst2", GetResourceURNOperateDestination(mockService, StringPtr("Dst2")))
s.Equal("urn:cherami:dst:zone2:root2/dst2", GetResourceURNOperateDestination(mockService, StringPtr("Root2/Dst2")))
}

func (s *AuthUtilSuite) TestGetResourceURNCreateConsumerGroup() {
Expand All @@ -114,9 +114,9 @@ func (s *AuthUtilSuite) TestGetResourceURNCreateConsumerGroup() {
s.Equal("urn:cherami:cg:zone1:/", GetResourceURNCreateConsumerGroup(mockService, StringPtr("//")))

config.deploymentName = "Zone2_ABC"
s.Equal("urn:cherami:cg:zone2_abc:/dst1", GetResourceURNCreateConsumerGroup(mockService, StringPtr("/Dst1")))
s.Equal("urn:cherami:cg:zone2_abc:/root2", GetResourceURNCreateConsumerGroup(mockService, StringPtr("/Root2/Dst2")))
s.Equal("urn:cherami:cg:zone2:/dst1", GetResourceURNCreateConsumerGroup(mockService, StringPtr("/Dst1")))
s.Equal("urn:cherami:cg:zone2:/root2", GetResourceURNCreateConsumerGroup(mockService, StringPtr("/Root2/Dst2")))

s.Equal("urn:cherami:cg:zone2_abc:dst2", GetResourceURNCreateConsumerGroup(mockService, StringPtr("Dst2")))
s.Equal("urn:cherami:cg:zone2_abc:root2", GetResourceURNCreateConsumerGroup(mockService, StringPtr("Root2/Dst2")))
s.Equal("urn:cherami:cg:zone2:dst2", GetResourceURNCreateConsumerGroup(mockService, StringPtr("Dst2")))
s.Equal("urn:cherami:cg:zone2:root2", GetResourceURNCreateConsumerGroup(mockService, StringPtr("Root2/Dst2")))
}
17 changes: 9 additions & 8 deletions services/frontendhost/frontend.go
Original file line number Diff line number Diff line change
Expand Up @@ -669,16 +669,17 @@ func (h *Frontend) DeleteDestination(ctx thrift.Context, deleteRequest *c.Delete
return
}

// Disallow delete destination for non-test destinations without a password
// TODO: remove when appropriate authentication is in place
lclLg := h.logger.WithField(common.TagDstPth, common.FmtDstPth(deleteRequest.GetPath()))

// To keep backward compatiblity, only check auth when no password is provided for DeleteDestination
if !allowMutate {
err = &c.BadRequestError{Message: fmt.Sprintf("Contact Cherami team to delete this path: %v", deleteRequest.GetPath())}
h.logger.WithField(common.TagErr, err).Error("DeleteDestination failed")
return
authResource := common.GetResourceURNOperateDestination(h.SCommon, deleteRequest.Path)
err = h.checkAuth(ctx, authResource, common.OperationDelete, lclLg)
if err != nil {
return err
}
}

lclLg := h.logger.WithField(common.TagDstPth, common.FmtDstPth(deleteRequest.GetPath()))

// Request to controller
cClient, err := h.getControllerClient()
if err != nil {
Expand Down Expand Up @@ -1117,7 +1118,7 @@ func (h *Frontend) CreateConsumerGroup(ctx thrift.Context, createRequest *c.Crea
})

// Check auth for read destination
authResource := common.GetResourceURNReadDestination(h.SCommon, createRequest.DestinationPath)
authResource := common.GetResourceURNOperateDestination(h.SCommon, createRequest.DestinationPath)
err = h.checkAuth(ctx, authResource, common.OperationRead, lclLg)
if err != nil {
return nil, err
Expand Down

0 comments on commit 41c2717

Please sign in to comment.