...

Source file src/edge-infra.dev/pkg/sds/remoteaccess/authserver/vnc_test.go

Documentation: edge-infra.dev/pkg/sds/remoteaccess/authserver

     1  package authserver
     2  
     3  import (
     4  	"context"
     5  	"net/http"
     6  	"net/http/httptest"
     7  	"testing"
     8  
     9  	"github.com/gin-gonic/gin"
    10  	"github.com/stretchr/testify/assert"
    11  
    12  	"edge-infra.dev/pkg/edge/auth-proxy/session"
    13  	"edge-infra.dev/pkg/lib/fog"
    14  	vncconst "edge-infra.dev/pkg/sds/vnc/constants"
    15  )
    16  
    17  func TestGetVNCAuthConfig(t *testing.T) {
    18  	t.Parallel()
    19  
    20  	tests := map[string]struct {
    21  		clusterConfig vncClusterConfig
    22  
    23  		expErr assert.ErrorAssertionFunc
    24  		expOut assert.BoolAssertionFunc
    25  	}{
    26  		"All Missing": {
    27  			// Currently default to unattended mode - this will change after
    28  			// API's are created
    29  			clusterConfig: vncClusterConfig{
    30  				BannerVNCAuthRequired:   "",
    31  				VNCAuthRequiredOverride: "",
    32  				ClusterVNCAuthRequired:  "",
    33  			},
    34  			expErr: assert.NoError,
    35  			expOut: assert.False,
    36  		},
    37  		"ClusterVNCAuthRequiredFalse": {
    38  			clusterConfig: vncClusterConfig{
    39  				BannerVNCAuthRequired:   "",
    40  				VNCAuthRequiredOverride: "",
    41  				ClusterVNCAuthRequired:  "false",
    42  			},
    43  			expErr: assert.NoError,
    44  			expOut: assert.False,
    45  		},
    46  		"ClusterVNCAuthRequiredTrue": {
    47  			clusterConfig: vncClusterConfig{
    48  				BannerVNCAuthRequired:   "",
    49  				VNCAuthRequiredOverride: "",
    50  				ClusterVNCAuthRequired:  "true",
    51  			},
    52  			expErr: assert.NoError,
    53  			expOut: assert.False,
    54  		},
    55  		"ClusterOverrideFalse": {
    56  			clusterConfig: vncClusterConfig{
    57  				BannerVNCAuthRequired:   "",
    58  				VNCAuthRequiredOverride: "False",
    59  				ClusterVNCAuthRequired:  "",
    60  			},
    61  			expErr: assert.NoError,
    62  			expOut: assert.False,
    63  		},
    64  		"ClusterOverrideFalseClusterVNCAuthRequiredFalse": {
    65  			clusterConfig: vncClusterConfig{
    66  				BannerVNCAuthRequired:   "",
    67  				VNCAuthRequiredOverride: "False",
    68  				ClusterVNCAuthRequired:  "False",
    69  			},
    70  			expErr: assert.NoError,
    71  			expOut: assert.False,
    72  		},
    73  		"ClusterOverrideFalseClusterVNCAuthRequiredTrue": {
    74  			clusterConfig: vncClusterConfig{
    75  				BannerVNCAuthRequired:   "",
    76  				VNCAuthRequiredOverride: "False",
    77  				ClusterVNCAuthRequired:  "True",
    78  			},
    79  			expErr: assert.NoError,
    80  			expOut: assert.False,
    81  		},
    82  		"ClusterOverrideTrue": {
    83  			clusterConfig: vncClusterConfig{
    84  				BannerVNCAuthRequired:   "",
    85  				VNCAuthRequiredOverride: "True",
    86  				ClusterVNCAuthRequired:  "",
    87  			},
    88  			expErr: assert.NoError,
    89  			expOut: assert.False,
    90  		},
    91  		"ClusterOverrideTrueClusterVNCAuthRequiredFalse": {
    92  			clusterConfig: vncClusterConfig{
    93  				BannerVNCAuthRequired:   "",
    94  				VNCAuthRequiredOverride: "True",
    95  				ClusterVNCAuthRequired:  "False",
    96  			},
    97  			expErr: assert.NoError,
    98  			expOut: assert.False,
    99  		},
   100  		"ClusterOverrideTrueClusterVNCAuthRequiredTrue": {
   101  			clusterConfig: vncClusterConfig{
   102  				BannerVNCAuthRequired:   "",
   103  				VNCAuthRequiredOverride: "True",
   104  				ClusterVNCAuthRequired:  "True",
   105  			},
   106  			expErr: assert.NoError,
   107  			expOut: assert.True,
   108  		},
   109  
   110  		"BannerVNCAuthRequiredFalse": {
   111  			clusterConfig: vncClusterConfig{
   112  				BannerVNCAuthRequired:   "False",
   113  				VNCAuthRequiredOverride: "",
   114  				ClusterVNCAuthRequired:  "",
   115  			},
   116  			expErr: assert.NoError,
   117  			expOut: assert.False,
   118  		},
   119  		"BannerVNCAuthRequiredFalseClusterVNCAuthRequiredFalse": {
   120  			clusterConfig: vncClusterConfig{
   121  				BannerVNCAuthRequired:   "False",
   122  				VNCAuthRequiredOverride: "",
   123  				ClusterVNCAuthRequired:  "False",
   124  			},
   125  			expErr: assert.NoError,
   126  			expOut: assert.False,
   127  		},
   128  		"BannerVNCAuthRequiredFalseClusterVNCAuthRequiredTrue": {
   129  			clusterConfig: vncClusterConfig{
   130  				BannerVNCAuthRequired:   "False",
   131  				VNCAuthRequiredOverride: "",
   132  				ClusterVNCAuthRequired:  "True",
   133  			},
   134  			expErr: assert.NoError,
   135  			expOut: assert.False,
   136  		},
   137  		"BannerVNCAuthRequiredFalseClusterOverrideFalse": {
   138  			clusterConfig: vncClusterConfig{
   139  				BannerVNCAuthRequired:   "False",
   140  				VNCAuthRequiredOverride: "False",
   141  				ClusterVNCAuthRequired:  "",
   142  			},
   143  			expErr: assert.NoError,
   144  			expOut: assert.False,
   145  		},
   146  		"BannerVNCAuthRequiredFalseClusterOverrideFalseClusterVNCAuthRequiredFalse": {
   147  			clusterConfig: vncClusterConfig{
   148  				BannerVNCAuthRequired:   "False",
   149  				VNCAuthRequiredOverride: "False",
   150  				ClusterVNCAuthRequired:  "False",
   151  			},
   152  			expErr: assert.NoError,
   153  			expOut: assert.False,
   154  		},
   155  		"BannerVNCAuthRequiredFalseClusterOverrideFalseClusterVNCAuthRequiredTrue": {
   156  			clusterConfig: vncClusterConfig{
   157  				BannerVNCAuthRequired:   "False",
   158  				VNCAuthRequiredOverride: "False",
   159  				ClusterVNCAuthRequired:  "True",
   160  			},
   161  			expErr: assert.NoError,
   162  			expOut: assert.False,
   163  		},
   164  		"BannerVNCAuthRequiredFalseClusterOverrideTrue": {
   165  			// If the cluster has not been specifically set, we should use the
   166  			// banner config
   167  			clusterConfig: vncClusterConfig{
   168  				BannerVNCAuthRequired:   "False",
   169  				VNCAuthRequiredOverride: "True",
   170  				ClusterVNCAuthRequired:  "",
   171  			},
   172  			expErr: assert.NoError,
   173  			expOut: assert.False,
   174  		},
   175  		"BannerVNCAuthRequiredFalseClusterOverrideTrueClusterVNCAuthRequiredFalse": {
   176  			clusterConfig: vncClusterConfig{
   177  				BannerVNCAuthRequired:   "False",
   178  				VNCAuthRequiredOverride: "True",
   179  				ClusterVNCAuthRequired:  "False",
   180  			},
   181  			expErr: assert.NoError,
   182  			expOut: assert.False,
   183  		},
   184  		"BannerVNCAuthRequiredFalseClusterOverrideTrueClusterVNCAuthRequiredTrue": {
   185  			clusterConfig: vncClusterConfig{
   186  				BannerVNCAuthRequired:   "False",
   187  				VNCAuthRequiredOverride: "True",
   188  				ClusterVNCAuthRequired:  "True",
   189  			},
   190  			expErr: assert.NoError,
   191  			expOut: assert.True,
   192  		},
   193  
   194  		"BannerVNCAuthRequiredTrue": {
   195  			clusterConfig: vncClusterConfig{
   196  				BannerVNCAuthRequired:   "true",
   197  				VNCAuthRequiredOverride: "",
   198  				ClusterVNCAuthRequired:  "",
   199  			},
   200  			expErr: assert.NoError,
   201  			expOut: assert.True,
   202  		},
   203  		"BannerVNCAuthRequiredTrueClusterVNCAuthRequiredFalse": {
   204  			clusterConfig: vncClusterConfig{
   205  				BannerVNCAuthRequired:   "true",
   206  				VNCAuthRequiredOverride: "",
   207  				ClusterVNCAuthRequired:  "False",
   208  			},
   209  			expErr: assert.NoError,
   210  			expOut: assert.True,
   211  		},
   212  		"BannerVNCAuthRequiredTrueClusterVNCAuthRequiredTrue": {
   213  			clusterConfig: vncClusterConfig{
   214  				BannerVNCAuthRequired:   "true",
   215  				VNCAuthRequiredOverride: "",
   216  				ClusterVNCAuthRequired:  "True",
   217  			},
   218  			expErr: assert.NoError,
   219  			expOut: assert.True,
   220  		},
   221  		"BannerVNCAuthRequiredTrueClusterOverrideFalse": {
   222  			clusterConfig: vncClusterConfig{
   223  				BannerVNCAuthRequired:   "true",
   224  				VNCAuthRequiredOverride: "False",
   225  				ClusterVNCAuthRequired:  "",
   226  			},
   227  			expErr: assert.NoError,
   228  			expOut: assert.True,
   229  		},
   230  		"BannerVNCAuthRequiredTrueClusterOverrideFalseClusterVNCAuthRequiredFalse": {
   231  			clusterConfig: vncClusterConfig{
   232  				BannerVNCAuthRequired:   "true",
   233  				VNCAuthRequiredOverride: "False",
   234  				ClusterVNCAuthRequired:  "False",
   235  			},
   236  			expErr: assert.NoError,
   237  			expOut: assert.True,
   238  		},
   239  		"BannerVNCAuthRequiredTrueClusterOverrideFalseClusterVNCAuthRequiredTrue": {
   240  			clusterConfig: vncClusterConfig{
   241  				BannerVNCAuthRequired:   "true",
   242  				VNCAuthRequiredOverride: "False",
   243  				ClusterVNCAuthRequired:  "true",
   244  			},
   245  			expErr: assert.NoError,
   246  			expOut: assert.True,
   247  		},
   248  		"BannerVNCAuthRequiredTrueClusterOverrideTrue": {
   249  			// Use banner config if the cluster has not been set
   250  			clusterConfig: vncClusterConfig{
   251  				BannerVNCAuthRequired:   "true",
   252  				VNCAuthRequiredOverride: "True",
   253  				ClusterVNCAuthRequired:  "",
   254  			},
   255  			expErr: assert.NoError,
   256  			expOut: assert.True,
   257  		},
   258  		"BannerVNCAuthRequiredTrueClusterOverrideTrueClusterVNCAuthRequiredFalse": {
   259  			clusterConfig: vncClusterConfig{
   260  				BannerVNCAuthRequired:   "true",
   261  				VNCAuthRequiredOverride: "True",
   262  				ClusterVNCAuthRequired:  "False",
   263  			},
   264  			expErr: assert.NoError,
   265  			expOut: assert.False,
   266  		},
   267  		"BannerVNCAuthRequiredTrueClusterOverrideTrueClusterVNCAuthRequiredTrue": {
   268  			clusterConfig: vncClusterConfig{
   269  				BannerVNCAuthRequired:   "true",
   270  				VNCAuthRequiredOverride: "True",
   271  				ClusterVNCAuthRequired:  "true",
   272  			},
   273  			expErr: assert.NoError,
   274  			expOut: assert.True,
   275  		},
   276  
   277  		"Not a truthy value": {
   278  			clusterConfig: vncClusterConfig{
   279  				BannerVNCAuthRequired:   "11",
   280  				VNCAuthRequiredOverride: "",
   281  				ClusterVNCAuthRequired:  "",
   282  			},
   283  			expErr: assert.Error,
   284  			expOut: assert.False,
   285  		},
   286  	}
   287  
   288  	for name, tc := range tests {
   289  		tc := tc
   290  		t.Run(name, func(t *testing.T) {
   291  			t.Parallel()
   292  
   293  			out, err := getVNCAuthConfig(tc.clusterConfig)
   294  			tc.expErr(t, err)
   295  			tc.expOut(t, out)
   296  		})
   297  	}
   298  }
   299  
   300  func TestGetVNCClusterConfig(t *testing.T) {
   301  	t.Parallel()
   302  
   303  	tests := map[string]struct {
   304  		bannerEdgeID     string
   305  		clusterEdgeID    string
   306  		connectMode      vncConnectMode
   307  		expClusterConfig vncClusterConfig
   308  	}{
   309  		"Test one write connect mode": {
   310  			// Use existing banners and clusters from the seed data
   311  			bannerEdgeID:  "3396a52c-6a22-4049-9593-5a63b596a100",
   312  			clusterEdgeID: "3396a52c-6a22-4049-9593-5a63b596a200",
   313  			connectMode:   vncWriteConnectMode,
   314  			expClusterConfig: vncClusterConfig{
   315  				BannerVNCAuthRequired:   "true",
   316  				VNCAuthRequiredOverride: "false",
   317  				ClusterVNCAuthRequired:  "",
   318  			},
   319  		},
   320  		"Test two write connect mode": {
   321  			bannerEdgeID:  "3396a52c-6a22-4049-9593-5a63b596a101",
   322  			clusterEdgeID: "3396a52c-6a22-4049-9593-5a63b596a101",
   323  			connectMode:   vncWriteConnectMode,
   324  			expClusterConfig: vncClusterConfig{
   325  				BannerVNCAuthRequired:   "",
   326  				VNCAuthRequiredOverride: "true",
   327  				ClusterVNCAuthRequired:  "false",
   328  			},
   329  		},
   330  		"Test vnc read only mode": {
   331  			bannerEdgeID:  "3396a52c-6a22-4049-9593-5a63b596a100",
   332  			clusterEdgeID: "3396a52c-6a22-4049-9593-5a63b596a200",
   333  			connectMode:   vncReadConnectMode,
   334  			expClusterConfig: vncClusterConfig{
   335  				BannerVNCAuthRequired:   "true",
   336  				VNCAuthRequiredOverride: "false",
   337  				ClusterVNCAuthRequired:  "",
   338  			},
   339  		},
   340  		"Invalid connect mode": {
   341  			// note if an invalid connect mode is supplied, write auth mode
   342  			// config is fetched from the db. Currently no check is done on an
   343  			// invalid connect mode as we do not expect it to be set by any
   344  			// untrusted source.
   345  			bannerEdgeID:  "4cb5d0e5-42cd-4483-8dca-547507d2adb0",
   346  			clusterEdgeID: "2d589401-8e64-4845-ad7b-0466e8e65f13",
   347  			connectMode:   vncConnectMode("invalid"),
   348  			expClusterConfig: vncClusterConfig{
   349  				BannerVNCAuthRequired:   "false",
   350  				VNCAuthRequiredOverride: "false",
   351  				ClusterVNCAuthRequired:  "",
   352  			},
   353  		},
   354  	}
   355  
   356  	for name, tc := range tests {
   357  		tc := tc
   358  		t.Run(name, func(t *testing.T) {
   359  			t.Parallel()
   360  
   361  			db, err := seededPostgres.DB()
   362  			assert.NoError(t, err)
   363  
   364  			authRequiredKey := "vnc_read_write_auth_required"
   365  			authOverrideKey := "vnc_read_write_auth_required_override"
   366  			if tc.connectMode == vncReadConnectMode {
   367  				authRequiredKey = "vnc_read_auth_required"
   368  				authOverrideKey = "vnc_read_auth_required_override"
   369  			}
   370  
   371  			_, err = db.Exec(
   372  				`INSERT INTO banner_configs(banner_edge_id, config_key, config_value)
   373  				VALUES
   374  					($1, $2, $3),
   375  					($1, $4, $5);`,
   376  				tc.bannerEdgeID,
   377  				authRequiredKey, tc.expClusterConfig.BannerVNCAuthRequired,
   378  				authOverrideKey, tc.expClusterConfig.VNCAuthRequiredOverride,
   379  			)
   380  			assert.NoError(t, err)
   381  
   382  			_, err = db.Exec(
   383  				`INSERT INTO cluster_config(cluster_edge_id, config_key, config_value)
   384  				VALUES
   385  					($1, $2, $3);`,
   386  				tc.clusterEdgeID,
   387  				authRequiredKey, tc.expClusterConfig.ClusterVNCAuthRequired,
   388  			)
   389  			assert.NoError(t, err)
   390  
   391  			as := &AuthServer{
   392  				db: db,
   393  			}
   394  
   395  			clusterConfig, err := as.getVNCClusterConfig(context.Background(), tc.bannerEdgeID, tc.clusterEdgeID, tc.connectMode)
   396  			assert.NoError(t, err)
   397  
   398  			assert.Equal(t, tc.expClusterConfig, clusterConfig)
   399  		})
   400  	}
   401  }
   402  
   403  func TestValidateVNCRoles(t *testing.T) {
   404  	t.Parallel()
   405  
   406  	tests := map[string]struct {
   407  		path       string
   408  		roles      []string
   409  		expErrCode int
   410  	}{
   411  		"BWC Write connect mode": {
   412  			path:  "/remoteaccess/3396a52c-6a22-4049-9593-5a63b596a210/novnc/authorize",
   413  			roles: []string{"EDGE_BANNER_OPERATOR"},
   414  		},
   415  		"Write connect mode": {
   416  			path:  "/remoteaccess/3396a52c-6a22-4049-9593-5a63b596a210/novnc/write/authorize",
   417  			roles: []string{"EDGE_BANNER_OPERATOR"},
   418  		},
   419  		"Read connect mode": {
   420  			path:  "/remoteaccess/3396a52c-6a22-4049-9593-5a63b596a210/novnc/read/authorize",
   421  			roles: []string{"EDGE_BANNER_VIEWER"},
   422  		},
   423  		"BWC Missing connect mode org admin": {
   424  			path:  "/remoteaccess/3396a52c-6a22-4049-9593-5a63b596a210/novnc/authorize",
   425  			roles: []string{"EDGE_ORG_ADMIN"},
   426  		},
   427  		"BWC Missing connect mode banner viewer": {
   428  			path:       "/remoteaccess/3396a52c-6a22-4049-9593-5a63b596a210/novnc/authorize",
   429  			roles:      []string{"EDGE_BANNER_VIEWER"},
   430  			expErrCode: http.StatusUnauthorized,
   431  		},
   432  		"Banner Viewer Write": {
   433  			path:       "/remoteaccess/3396a52c-6a22-4049-9593-5a63b596a210/novnc/write/authorize",
   434  			roles:      []string{"EDGE_BANNER_VIEWER"},
   435  			expErrCode: http.StatusUnauthorized,
   436  		},
   437  		"No Roles Read": {
   438  			path:       "/remoteaccess/3396a52c-6a22-4049-9593-5a63b596a210/novnc/read/authorize",
   439  			roles:      []string{},
   440  			expErrCode: http.StatusUnauthorized,
   441  		},
   442  		"Nil Roles Read": {
   443  			path:       "/remoteaccess/3396a52c-6a22-4049-9593-5a63b596a210/novnc/read/authorize",
   444  			roles:      nil,
   445  			expErrCode: http.StatusUnauthorized,
   446  		},
   447  		"No Valid Roles Read": {
   448  			path:       "/remoteaccess/3396a52c-6a22-4049-9593-5a63b596a210/novnc/read/authorize",
   449  			roles:      []string{"EDGE_OI_ADMIN"},
   450  			expErrCode: http.StatusUnauthorized,
   451  		},
   452  		"Attempt bypass on old store": {
   453  			// nginx on the old store will treat this as as a normal call to
   454  			// authorize. This path must not be accessible to banner viewers
   455  			path:       "/remoteaccess/3396a52c-6a22-4049-9593-5a63b596a210/novnc/authorize/novnc/read/authorize",
   456  			roles:      []string{"EDGE_BANNER_VIEWER"},
   457  			expErrCode: http.StatusUnauthorized,
   458  		},
   459  		"Unknown connect mode": {
   460  			// This will result in a 404 in the store, but it's ok for
   461  			// authserver to accept the connection while we maintain bwc with
   462  			// old stores. After removing bwc, this should be blocked by
   463  			// authserver
   464  			path:  "/remoteaccess/3396a52c-6a22-4049-9593-5a63b596a210/novnc/unknown/authorize?vncConnectMode=unknown",
   465  			roles: []string{"EDGE_ORG_ADMIN"},
   466  		},
   467  	}
   468  
   469  	for name, tc := range tests {
   470  		tc := tc
   471  		t.Run(name, func(t *testing.T) {
   472  			t.Parallel()
   473  
   474  			r := httptest.NewRecorder()
   475  			ctx, ginTestEngine := getTestGinContext(r)
   476  
   477  			req := httptest.NewRequest(http.MethodGet, tc.path, nil)
   478  			ctx.Request = req
   479  
   480  			mockSessions := session.NewMockSessions()
   481  			mockSessions.Set("roles", tc.roles)
   482  
   483  			as := &AuthServer{
   484  				GinMode:   gin.TestMode,
   485  				GinEngine: ginTestEngine,
   486  				Log:       fog.New(),
   487  			}
   488  
   489  			err := (*AuthServer).validateVNCRoles(as, ctx, mockSessions)
   490  
   491  			if tc.expErrCode == 0 {
   492  				assert.NoError(t, err)
   493  			} else {
   494  				assert.Error(t, err)
   495  
   496  				e, ok := err.(*httpError)
   497  				if assert.True(t, ok) {
   498  					assert.Equal(t, tc.expErrCode, e.StatusCode(), "unexpected error status code")
   499  				}
   500  			}
   501  		})
   502  	}
   503  }
   504  
   505  func TestNovncAuthModeHeader(t *testing.T) {
   506  	t.Parallel()
   507  
   508  	tests := map[string]struct {
   509  		bannerEdgeID      string
   510  		clusterEdgeID     string
   511  		path              string
   512  		incomingHeaderVal string
   513  		connectMode       vncConnectMode
   514  		dbContents        vncClusterConfig
   515  
   516  		expHeaderVal string
   517  		expErr       assert.ErrorAssertionFunc
   518  	}{
   519  		"User Override": {
   520  			bannerEdgeID:      "3396a52c-6a22-4049-9593-5a63b596a102",
   521  			clusterEdgeID:     "3396a52c-6a22-4049-9593-5a63b596a201",
   522  			path:              "/remoteaccess/3396a52c-6a22-4049-9593-5a63b596a201/novnc/write/authorize",
   523  			incomingHeaderVal: "1",
   524  			connectMode:       vncWriteConnectMode,
   525  			dbContents: vncClusterConfig{
   526  				BannerVNCAuthRequired:   "false",
   527  				VNCAuthRequiredOverride: "false",
   528  				ClusterVNCAuthRequired:  "false",
   529  			},
   530  
   531  			expHeaderVal: "1",
   532  			expErr:       assert.NoError,
   533  		},
   534  		"No header Write Connect Mode": {
   535  			bannerEdgeID:      "3396a52c-6a22-4049-9593-5a63b596a103",
   536  			clusterEdgeID:     "5af7b37a-c149-4df4-ad0d-2b0e03bd9ed1",
   537  			path:              "/remoteaccess/5af7b37a-c149-4df4-ad0d-2b0e03bd9ed1/novnc/write/authorize",
   538  			incomingHeaderVal: "",
   539  			connectMode:       vncWriteConnectMode,
   540  			dbContents: vncClusterConfig{
   541  				BannerVNCAuthRequired:   "false",
   542  				VNCAuthRequiredOverride: "false",
   543  				ClusterVNCAuthRequired:  "false",
   544  			},
   545  
   546  			expHeaderVal: "",
   547  			expErr:       assert.NoError,
   548  		},
   549  		"Header Write Connect Mode": {
   550  			bannerEdgeID:      "98ef1fcb-dc88-4c9f-9980-c09a04564a48",
   551  			clusterEdgeID:     "3396a52c-6a22-4049-9593-5a63b596a210",
   552  			path:              "/remoteaccess/3396a52c-6a22-4049-9593-5a63b596a210/novnc/write/authorize",
   553  			incomingHeaderVal: "",
   554  			connectMode:       vncWriteConnectMode,
   555  			dbContents: vncClusterConfig{
   556  				BannerVNCAuthRequired:   "true",
   557  				VNCAuthRequiredOverride: "true",
   558  				ClusterVNCAuthRequired:  "true",
   559  			},
   560  
   561  			expHeaderVal: "1",
   562  			expErr:       assert.NoError,
   563  		},
   564  		"Auth Mode Not Required Read Connect Mode": {
   565  			bannerEdgeID:      "3396a52c-6a22-4049-9593-5a63b596a104",
   566  			clusterEdgeID:     "5bc12c67-d9b0-4f13-a6d4-4852b0c11291",
   567  			path:              "/remoteaccess/5bc12c67-d9b0-4f13-a6d4-4852b0c11291/novnc/read/authorize",
   568  			incomingHeaderVal: "",
   569  			connectMode:       vncReadConnectMode,
   570  			dbContents: vncClusterConfig{
   571  				BannerVNCAuthRequired:   "false",
   572  				VNCAuthRequiredOverride: "false",
   573  				ClusterVNCAuthRequired:  "false",
   574  			},
   575  
   576  			expHeaderVal: "",
   577  			expErr:       assert.NoError,
   578  		},
   579  		"Auth Mode Required Read Connect Mode": {
   580  			bannerEdgeID:      "3396a52c-6a22-4049-9593-5a63b596a105",
   581  			clusterEdgeID:     "2a589401-8e64-4845-ad7b-0466e8e65f13",
   582  			path:              "/remoteaccess/2a589401-8e64-4845-ad7b-0466e8e65f13/novnc/read/authorize",
   583  			incomingHeaderVal: "",
   584  			connectMode:       vncReadConnectMode,
   585  			dbContents: vncClusterConfig{
   586  				BannerVNCAuthRequired:   "true",
   587  				VNCAuthRequiredOverride: "true",
   588  				ClusterVNCAuthRequired:  "true",
   589  			},
   590  
   591  			expHeaderVal: "1",
   592  			expErr:       assert.NoError,
   593  		},
   594  		"BWC no connect mode in path": {
   595  			bannerEdgeID:  "3396a52c-6a22-4049-9593-5a63b596a106",
   596  			clusterEdgeID: "2b589401-8e64-4845-ad7b-0466e8e65f13",
   597  			path:          "/remoteaccess/2b589401-8e64-4845-ad7b-0466e8e65f13/novnc/authorize",
   598  			connectMode:   vncWriteConnectMode,
   599  			dbContents: vncClusterConfig{
   600  				BannerVNCAuthRequired:   "true",
   601  				VNCAuthRequiredOverride: "true",
   602  				ClusterVNCAuthRequired:  "true",
   603  			},
   604  
   605  			expHeaderVal: "1",
   606  			expErr:       assert.NoError,
   607  		},
   608  	}
   609  
   610  	for name, tc := range tests {
   611  		tc := tc
   612  		t.Run(name, func(t *testing.T) {
   613  			t.Parallel()
   614  
   615  			// Setup
   616  			r := httptest.NewRecorder()
   617  			ctx, ginTestEngine := getTestGinContext(r)
   618  
   619  			req := httptest.NewRequest(http.MethodGet, tc.path, nil)
   620  			req.Header.Add(vncconst.HeaderKeyAuthMode, tc.incomingHeaderVal)
   621  			req.Header.Add("Banner", tc.bannerEdgeID)
   622  			ctx.Request = req
   623  
   624  			db, err := seededPostgres.DB()
   625  			assert.NoError(t, err)
   626  
   627  			authRequiredKey := "vnc_read_write_auth_required"
   628  			authOverrideKey := "vnc_read_write_auth_required_override"
   629  			if tc.connectMode == vncReadConnectMode {
   630  				authRequiredKey = "vnc_read_auth_required"
   631  				authOverrideKey = "vnc_read_auth_required_override"
   632  			}
   633  
   634  			_, err = db.Exec(
   635  				`INSERT INTO banner_configs(banner_edge_id, config_key, config_value)
   636  				VALUES
   637  					($1, $2, $3),
   638  					($1, $4, $5);`,
   639  				tc.bannerEdgeID,
   640  				authRequiredKey, tc.dbContents.BannerVNCAuthRequired,
   641  				authOverrideKey, tc.dbContents.VNCAuthRequiredOverride,
   642  			)
   643  			assert.NoError(t, err)
   644  
   645  			_, err = db.Exec(
   646  				`INSERT INTO cluster_config(cluster_edge_id, config_key, config_value)
   647  				VALUES
   648  					($1, $2, $3);`,
   649  				tc.clusterEdgeID,
   650  				authRequiredKey, tc.dbContents.ClusterVNCAuthRequired,
   651  			)
   652  			assert.NoError(t, err)
   653  
   654  			as := &AuthServer{
   655  				GinMode:   gin.TestMode,
   656  				GinEngine: ginTestEngine,
   657  				db:        db,
   658  				Log:       fog.New(),
   659  			}
   660  
   661  			// Test
   662  
   663  			err = (*AuthServer).injectVNCAuthHeaders(as, ctx, session.NewMockSessions())
   664  			tc.expErr(t, err)
   665  
   666  			assert.Equal(t, tc.expHeaderVal, r.Result().Header.Get(vncconst.HeaderKeyAuthMode))
   667  		})
   668  	}
   669  }
   670  

View as plain text