Skip to content

Commit

Permalink
add public-viewer support
Browse files Browse the repository at this point in the history
This commit adds the notion of Public-Viewer to the Proxy as described
in [JIRA ASC-532](https://issues.redhat.com/browse/ASC-532).

Signed-off-by: Francesco Ilario <[email protected]>
  • Loading branch information
filariow committed Jul 11, 2024
1 parent 2d147e4 commit 32e9044
Show file tree
Hide file tree
Showing 19 changed files with 1,142 additions and 141 deletions.
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ go 1.20

require (
github.com/aws/aws-sdk-go v1.44.100
github.com/codeready-toolchain/api v0.0.0-20240607180719-368c7afbaebe
github.com/codeready-toolchain/toolchain-common v0.0.0-20240613121043-7e6ef858cdff
github.com/codeready-toolchain/api v0.0.0-20240708122235-0af5a9a178bb
github.com/codeready-toolchain/toolchain-common v0.0.0-20240711082950-c7f9f4442ae0
github.com/go-logr/logr v1.4.1
github.com/gofrs/uuid v4.2.0+incompatible
github.com/pkg/errors v0.9.1
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtM
github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/codeready-toolchain/api v0.0.0-20240607180719-368c7afbaebe h1:l+KsEXkNe1mZ14Z/RaTgeUkEuX9r56mSZC6xlu5H6zY=
github.com/codeready-toolchain/api v0.0.0-20240607180719-368c7afbaebe/go.mod h1:ie9p4LenCCS0LsnbWp6/xwpFDdCWYE0KWzUO6Sk1g0E=
github.com/codeready-toolchain/toolchain-common v0.0.0-20240613121043-7e6ef858cdff h1:bVWL+2eayFKUnEzdEAwltPs+pzbGlGDSmrM3oOV2Ams=
github.com/codeready-toolchain/toolchain-common v0.0.0-20240613121043-7e6ef858cdff/go.mod h1:cyHrUfvBYEtsf+FbqQYmR9y0AQi9QAVtM3SUWLA5bd4=
github.com/codeready-toolchain/api v0.0.0-20240708122235-0af5a9a178bb h1:Wc9CMsv0ODZv9dM5qF3OI0mFDO95YNIXV/8oRvoz8aE=
github.com/codeready-toolchain/api v0.0.0-20240708122235-0af5a9a178bb/go.mod h1:ie9p4LenCCS0LsnbWp6/xwpFDdCWYE0KWzUO6Sk1g0E=
github.com/codeready-toolchain/toolchain-common v0.0.0-20240711082950-c7f9f4442ae0 h1:v7Z5i0JaF1H9SYxK/uEjWgH8Vpm4Eg3OJep/Pl/2iyM=
github.com/codeready-toolchain/toolchain-common v0.0.0-20240711082950-c7f9f4442ae0/go.mod h1:8M9k7w2VSyRKSK6P08Jo2ddW3uyGgxCcSitnYa3HK9o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
Expand Down
2 changes: 1 addition & 1 deletion pkg/application/service/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ type VerificationService interface {
}

type MemberClusterService interface {
GetClusterAccess(userID, username, workspace, proxyPluginName string) (*access.ClusterAccess, error)
GetClusterAccess(userID, username, workspace, proxyPluginName string, publicViewerEnabled bool) (*access.ClusterAccess, error)
}

type Services interface {
Expand Down
4 changes: 4 additions & 0 deletions pkg/configuration/configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ func (r RegistrationServiceConfig) Print() {
logger.Info("Registration Service Configuration", "config", r.cfg.Host.RegistrationService)
}

func (r RegistrationServiceConfig) PublicViewerEnabled() bool {
return r.cfg.Host.PublicViewerConfig != nil && r.cfg.Host.PublicViewerConfig.Enabled
}

func (r RegistrationServiceConfig) Environment() string {
return commonconfig.GetString(r.cfg.Host.RegistrationService.Environment, prodEnvironment)
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/context/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,8 @@ const (
WorkspaceKey = "workspace"
// RequestReceivedTime is the context key for the starting time of a request made
RequestReceivedTime = "requestReceivedTime"
// PublicViewerEnabled is a boolean value indicating whether PublicViewer support is enabled
PublicViewerEnabled = "publicViewerEnabled"
// ImpersonateUser is the content key for the impersonated user in proxied call
ImpersonateUser = "impersonateUser"
)
10 changes: 10 additions & 0 deletions pkg/context/public_viewer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package context

import "github.com/labstack/echo/v4"

// IsPublicViewerEnabled retrieves from the context the boolean value associated to the PublicViewerEnabled key.
// If the key is not set it returns false, otherwise it returns the boolean value stored in the context.
func IsPublicViewerEnabled(ctx echo.Context) bool {
publicViewerEnabled, _ := ctx.Get(PublicViewerEnabled).(bool)
return publicViewerEnabled
}
8 changes: 8 additions & 0 deletions pkg/log/log.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,14 @@ func (l *Logger) InfoEchof(ctx echo.Context, msg string, args ...string) {
ctxFields = append(ctxFields, "url")
ctxFields = append(ctxFields, ctx.Request().URL)

if impersonateUser, ok := ctx.Get(context.ImpersonateUser).(string); ok {
ctxFields = append(ctxFields, "impersonate-user", impersonateUser)
}

if publicViewerEnabled, ok := ctx.Get(context.PublicViewerEnabled).(bool); ok {
ctxFields = append(ctxFields, "public-viewer-enabled", publicViewerEnabled)
}

l.infof(ctxFields, msg, args...)
}

Expand Down
77 changes: 70 additions & 7 deletions pkg/proxy/handlers/spacelister_get.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"time"

toolchainv1alpha1 "github.com/codeready-toolchain/api/api/v1alpha1"
"github.com/codeready-toolchain/registration-service/pkg/context"
regsercontext "github.com/codeready-toolchain/registration-service/pkg/context"
"github.com/codeready-toolchain/registration-service/pkg/proxy/metrics"
"github.com/codeready-toolchain/registration-service/pkg/signup"
Expand Down Expand Up @@ -43,7 +44,7 @@ func HandleSpaceGetRequest(spaceLister *SpaceLister, GetMembersFunc cluster.GetM
}
}

// GetUserWorkspace returns a workspace object with the required fields used by the proxy
// GetUserWorkspace returns a workspace object with the required fields used by the proxy.
func GetUserWorkspace(ctx echo.Context, spaceLister *SpaceLister, workspaceName string) (*toolchainv1alpha1.Workspace, error) {
userSignup, space, err := getUserSignupAndSpace(ctx, spaceLister, workspaceName)
if err != nil {
Expand All @@ -54,6 +55,56 @@ func GetUserWorkspace(ctx echo.Context, spaceLister *SpaceLister, workspaceName
return nil, nil
}

// retrieve user space binding
userSpaceBinding, err := getUserOrPublicViewerSpaceBinding(ctx, spaceLister, space, userSignup, workspaceName)
if err != nil {
return nil, err
}
// consider this as not found
if userSpaceBinding == nil {
return nil, nil
}

// create and return the result workspace object
return createWorkspaceObject(userSignup.Name, space, userSpaceBinding), nil
}

// getUserOrPublicViewerSpaceBinding retrieves the user space binding for an user and a space.
// If the SpaceBinding is not found and the PublicViewer feature is enabled, it will retry
// with the PublicViewer credentials.
func getUserOrPublicViewerSpaceBinding(ctx echo.Context, spaceLister *SpaceLister, space *toolchainv1alpha1.Space, userSignup *signup.Signup, workspaceName string) (*toolchainv1alpha1.SpaceBinding, error) {
userSpaceBinding, err := getUserSpaceBinding(ctx, spaceLister, space, userSignup)
if err != nil {
return nil, err
}

// if user space binding is not found and PublicViewer is enabled,
// retry with PublicViewer's signup
if userSpaceBinding == nil {
if context.IsPublicViewerEnabled(ctx) {
publicViewerUserSignup := signup.Signup{
Name: toolchainv1alpha1.KubesawAuthenticatedUsername,
CompliantUsername: toolchainv1alpha1.KubesawAuthenticatedUsername,
}
pvSb, err := getUserSpaceBinding(ctx, spaceLister, space, &publicViewerUserSignup)
if err != nil {
ctx.Logger().Error(fmt.Sprintf("error checking if SpaceBinding is present for user %s and the workspace %s", publicViewerUserSignup.CompliantUsername, workspaceName))
return nil, err
}
if pvSb == nil {
ctx.Logger().Error(fmt.Sprintf("unauthorized access - there is no SpaceBinding present for the user %s and the workspace %s", userSignup.CompliantUsername, workspaceName))
return nil, nil
}
return pvSb, nil
}
ctx.Logger().Error(fmt.Sprintf("unauthorized access - there is no SpaceBinding present for the user %s and the workspace %s", userSignup.CompliantUsername, workspaceName))
}

return userSpaceBinding, nil
}

// getUserSpaceBinding retrieves the user space binding for an user and a space.
func getUserSpaceBinding(ctx echo.Context, spaceLister *SpaceLister, space *toolchainv1alpha1.Space, userSignup *signup.Signup) (*toolchainv1alpha1.SpaceBinding, error) {
// recursively get all the spacebindings for the current workspace
listSpaceBindingsFunc := func(spaceName string) ([]toolchainv1alpha1.SpaceBinding, error) {
spaceSelector, err := labels.NewRequirement(toolchainv1alpha1.SpaceBindingSpaceLabelKey, selection.Equals, []string{spaceName})
Expand All @@ -74,7 +125,6 @@ func GetUserWorkspace(ctx echo.Context, spaceLister *SpaceLister, workspaceName
}
if len(userSpaceBindings) == 0 {
// let's only log the issue and consider this as not found
ctx.Logger().Error(fmt.Sprintf("unauthorized access - there is no SpaceBinding present for the user %s and the workspace %s", userSignup.CompliantUsername, workspaceName))
return nil, nil
}

Expand All @@ -84,10 +134,10 @@ func GetUserWorkspace(ctx echo.Context, spaceLister *SpaceLister, workspaceName
return nil, userBindingsErr
}

return createWorkspaceObject(userSignup.Name, space, &userSpaceBindings[0]), nil
return &userSpaceBindings[0], nil
}

// GetUserWorkspaceWithBindings returns a workspace object with the required fields+bindings (the list with all the users access details)
// GetUserWorkspaceWithBindings returns a workspace object with the required fields+bindings (the list with all the users access details).
func GetUserWorkspaceWithBindings(ctx echo.Context, spaceLister *SpaceLister, workspaceName string, GetMembersFunc cluster.GetMemberClustersFunc) (*toolchainv1alpha1.Workspace, error) {
userSignup, space, err := getUserSignupAndSpace(ctx, spaceLister, workspaceName)
if err != nil {
Expand Down Expand Up @@ -116,9 +166,16 @@ func GetUserWorkspaceWithBindings(ctx echo.Context, spaceLister *SpaceLister, wo
// check if user has access to this workspace
userBinding := filterUserSpaceBinding(userSignup.CompliantUsername, allSpaceBindings)
if userBinding == nil {
// let's only log the issue and consider this as not found
ctx.Logger().Error(fmt.Sprintf("unauthorized access - there is no SpaceBinding present for the user %s and the workspace %s", userSignup.CompliantUsername, workspaceName))
return nil, nil
// if PublicViewer is enabled, check if the Space is visibile to PublicViewer
if context.IsPublicViewerEnabled(ctx) && userSignup.CompliantUsername != toolchainv1alpha1.KubesawAuthenticatedUsername {
userBinding = filterUserSpaceBinding(toolchainv1alpha1.KubesawAuthenticatedUsername, allSpaceBindings)
}

if userBinding == nil {
// let's only log the issue and consider this as not found
ctx.Logger().Error(fmt.Sprintf("unauthorized access - there is no SpaceBinding present for the user %s and the workspace %s", userSignup.CompliantUsername, workspaceName))
return nil, nil
}
}

// list all SpaceBindingRequests , just in case there might be some failing to create a SpaceBinding resource.
Expand Down Expand Up @@ -155,6 +212,12 @@ func getUserSignupAndSpace(ctx echo.Context, spaceLister *SpaceLister, workspace
if err != nil {
return nil, nil, err
}
if userSignup == nil && context.IsPublicViewerEnabled(ctx) {
userSignup = &signup.Signup{
CompliantUsername: toolchainv1alpha1.KubesawAuthenticatedUsername,
Name: toolchainv1alpha1.KubesawAuthenticatedUsername,
}
}

space, err := spaceLister.GetInformerServiceFunc().GetSpace(workspaceName)
if err != nil {
Expand Down
Loading

0 comments on commit 32e9044

Please sign in to comment.