Skip to content

add public-viewer support to SpaceLister's Get #451

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

Merged
merged 23 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
414cf41
add public-viewer support to pkg/configuration
filariow Jul 25, 2024
06efa59
add public-viewer support to pkg/context
filariow Jul 25, 2024
99e41e8
add public-viewer support to SpaceLister's Get
filariow Jul 25, 2024
8d176eb
Merge remote-tracking branch 'upstream/master' into pv-532-spaceliste…
filariow Jul 31, 2024
00be35d
Merge branch 'master' into pv-532-spacelister-get
filariow Jul 31, 2024
5412a91
simplify logs by using Errorf
filariow Aug 1, 2024
d1b21d0
improve logs
filariow Aug 1, 2024
c34dfad
fix logs
filariow Aug 1, 2024
0af2c8f
remove unused parameter from getUserSpaceBinding
filariow Aug 1, 2024
2d452c9
update comments
filariow Aug 1, 2024
9f455b3
remove context's PublicViewerEnabled set
filariow Aug 1, 2024
9ab1fc2
Merge branch 'master' into pv-532-spacelister-get
filariow Aug 5, 2024
af7bb99
remove expectedErr
filariow Aug 5, 2024
8736124
fix test case title
filariow Aug 5, 2024
a525db5
add missing tests
filariow Aug 5, 2024
7b3c4cd
Update pkg/proxy/handlers/spacelister_get_test.go
filariow Aug 5, 2024
9d94638
Update pkg/proxy/handlers/spacelister_get_test.go
filariow Aug 5, 2024
ab258fd
Update pkg/proxy/handlers/spacelister_get.go
filariow Aug 6, 2024
98bd360
improve unit tests
filariow Aug 13, 2024
6c0bbaf
cleanup unit-tests
filariow Aug 13, 2024
f0bf289
Update pkg/proxy/handlers/spacelister_get_test.go
filariow Aug 13, 2024
a5541e2
rollback unneeded changes
filariow Aug 13, 2024
ebb8e55
Merge branch 'master' into pv-532-spacelister-get
filariow Aug 19, 2024
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
84 changes: 74 additions & 10 deletions pkg/proxy/handlers/spacelister_get.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
"time"

toolchainv1alpha1 "github.com/codeready-toolchain/api/api/v1alpha1"
"github.com/codeready-toolchain/registration-service/pkg/configuration"
"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 All @@ -26,6 +28,8 @@
// get specific workspace
return func(ctx echo.Context) error {
requestReceivedTime := ctx.Get(regsercontext.RequestReceivedTime).(time.Time)
publicViewerEnabled := configuration.GetRegistrationServiceConfig().PublicViewerEnabled()
ctx.Set(context.PublicViewerEnabled, publicViewerEnabled)
workspace, err := GetUserWorkspaceWithBindings(ctx, spaceLister, ctx.Param("workspace"), GetMembersFunc)
if err != nil {
spaceLister.ProxyMetrics.RegServWorkspaceHistogramVec.WithLabelValues(fmt.Sprintf("%d", http.StatusInternalServerError), metrics.MetricsLabelVerbGet).Observe(time.Since(requestReceivedTime).Seconds()) // using list as the default value for verb to minimize label combinations for prometheus to process
Expand All @@ -42,7 +46,7 @@
}
}

// 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 @@ -53,10 +57,58 @@
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.CompliantUsername)
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) {
pvSb, err := getUserSpaceBinding(ctx, spaceLister, space, toolchainv1alpha1.KubesawAuthenticatedUsername)
if err != nil {
ctx.Logger().Error(fmt.Sprintf("error checking if SpaceBinding is present for user %s and the workspace %s", toolchainv1alpha1.KubesawAuthenticatedUsername, workspaceName))
return nil, err

Check warning on line 90 in pkg/proxy/handlers/spacelister_get.go

View check run for this annotation

Codecov / codecov/patch

pkg/proxy/handlers/spacelister_get.go#L89-L90

Added lines #L89 - L90 were not covered by tests
}
if pvSb == nil {
ctx.Logger().Error(fmt.Sprintf("unauthorized access - there is no SpaceBinding present for the user %s and the workspace %s", toolchainv1alpha1.KubesawAuthenticatedUsername, 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.
// If no space binding found for this user and space then returns nil, nil
// If multiple found then returns the first one.
func getUserSpaceBinding(ctx echo.Context, spaceLister *SpaceLister, space *toolchainv1alpha1.Space, compliantUsername string) (*toolchainv1alpha1.SpaceBinding, error) {
// recursively get all the spacebindings for the current workspace
listSpaceBindingsFunc := func(spaceName string) ([]toolchainv1alpha1.SpaceBinding, error) {
spaceSelector, _ := labels.SelectorFromSet(labels.Set{toolchainv1alpha1.SpaceBindingSpaceLabelKey: spaceName}).Requirements()
murSelector, _ := labels.SelectorFromSet(labels.Set{toolchainv1alpha1.SpaceBindingMasterUserRecordLabelKey: userSignup.CompliantUsername}).Requirements()
murSelector, _ := labels.SelectorFromSet(labels.Set{toolchainv1alpha1.SpaceBindingMasterUserRecordLabelKey: compliantUsername}).Requirements()
return spaceLister.GetInformerServiceFunc().ListSpaceBindings(spaceSelector[0], murSelector[0])
}
spaceBindingLister := spacebinding.NewLister(listSpaceBindingsFunc, spaceLister.GetInformerServiceFunc().GetSpace)
Expand All @@ -66,21 +118,20 @@
return nil, err
}
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))
// consider this as not found
return nil, nil
}

if len(userSpaceBindings) > 1 {
userBindingsErr := fmt.Errorf("invalid number of SpaceBindings found for MUR:%s and Space:%s. Expected 1 got %d", userSignup.CompliantUsername, space.Name, len(userSpaceBindings))
userBindingsErr := fmt.Errorf("invalid number of SpaceBindings found for MUR:%s and Space:%s. Expected 1 got %d", compliantUsername, space.Name, len(userSpaceBindings))
ctx.Logger().Error(userBindingsErr)
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 All @@ -106,9 +157,16 @@
// 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 @@ -145,6 +203,12 @@
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
Loading