Skip to content

Commit 2e76aea

Browse files
committed
Change: Unify permission tests & test all endpoints
1 parent 74f886d commit 2e76aea

8 files changed

Lines changed: 336 additions & 310 deletions

File tree

pkg/web/mailcontroller/checkMailServer_test.go

Lines changed: 51 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
1+
// SPDX-FileCopyrightText: 2026 Greenbone AG <https://greenbone.net>
2+
//
3+
// SPDX-License-Identifier: AGPL-3.0-or-later
4+
15
package mailcontroller
26

37
import (
48
"net/http"
9+
"net/http/httptest"
10+
"strings"
511
"testing"
612

713
"github.com/gin-gonic/gin"
@@ -23,22 +29,11 @@ func setup(t *testing.T) (*gin.Engine, *mocks.MailChannelService) {
2329

2430
notificationChannelServicer := mocks.NewMailChannelService(t)
2531

26-
AddCheckMailServerController(engine, notificationChannelServicer, testhelper.MockAuthMiddlewareWithAdmin, registry)
27-
return engine, notificationChannelServicer
28-
}
29-
30-
func setupCheckMailServerWithAuth(t *testing.T) *gin.Engine {
31-
registry := errmap.NewRegistry()
32-
engine := testhelper.NewTestWebEngine(registry)
33-
mailChannelService := mocks.NewMailChannelService(t)
34-
3532
authMiddleware, err := auth.NewGinAuthMiddleware(integrationTests.NewTestJwtParser(t))
3633
require.NoError(t, err)
3734

38-
mailChannelService.On("CheckNotificationChannelConnectivity", mock.Anything, mock.Anything).Maybe().Return(nil)
39-
40-
AddCheckMailServerController(engine, mailChannelService, authMiddleware, registry)
41-
return engine
35+
AddCheckMailServerController(engine, notificationChannelServicer, authMiddleware, registry)
36+
return engine, notificationChannelServicer
4237
}
4338

4439
func TestCheckMailServer(t *testing.T) {
@@ -58,6 +53,7 @@ func TestCheckMailServer(t *testing.T) {
5853
"username": "testUser",
5954
"password": "123"
6055
}`).
56+
AuthJwt(integrationTests.CreateJwtTokenWithRole(iam.NotificationAdmin)).
6157
Expect().
6258
StatusCode(http.StatusNoContent).
6359
NoContent()
@@ -69,6 +65,7 @@ func TestCheckMailServer(t *testing.T) {
6965
httpassert.New(t, engine).
7066
Post("/notification-channel/mail/check").
7167
Content(`-`).
68+
AuthJwt(integrationTests.CreateJwtTokenWithRole(iam.NotificationAdmin)).
7269
Expect().
7370
StatusCode(http.StatusBadRequest).
7471
Json(`{
@@ -84,6 +81,7 @@ func TestCheckMailServer(t *testing.T) {
8481
httpassert.New(t, engine).
8582
Post("/notification-channel/mail/check").
8683
Content(`{}`).
84+
AuthJwt(integrationTests.CreateJwtTokenWithRole(iam.NotificationAdmin)).
8785
Expect().
8886
StatusCode(http.StatusBadRequest).
8987
Json(`{
@@ -109,6 +107,7 @@ func TestCheckMailServer(t *testing.T) {
109107
"username": "",
110108
"password": ""
111109
}`).
110+
AuthJwt(integrationTests.CreateJwtTokenWithRole(iam.NotificationAdmin)).
112111
Expect().
113112
StatusCode(http.StatusBadRequest).
114113
Json(`{
@@ -135,6 +134,7 @@ func TestCheckMailServer(t *testing.T) {
135134
"isAuthenticationRequired": false,
136135
"isTlsEnforced": false
137136
}`).
137+
AuthJwt(integrationTests.CreateJwtTokenWithRole(iam.NotificationAdmin)).
138138
Expect().
139139
StatusCode(http.StatusUnprocessableEntity).
140140
Json(`{
@@ -144,44 +144,52 @@ func TestCheckMailServer(t *testing.T) {
144144
})
145145
}
146146

147-
func TestCheckMailServer_ForbiddenRoles(t *testing.T) {
147+
func TestCheckMailServer_Permissions(t *testing.T) {
148148
t.Parallel()
149149

150-
forbiddenRoles := []string{iam.OsiViewer, iam.User, iam.OsiUser, iam.OsiAdmin, iam.Notification}
151-
152-
for _, role := range forbiddenRoles {
153-
t.Run("Check mail server is forbidden for role "+role, func(t *testing.T) {
154-
t.Parallel()
155-
156-
router := setupCheckMailServerWithAuth(t)
150+
var endpoints = []struct {
151+
name string
152+
method string
153+
path string
154+
}{
155+
{"Create mail channel", http.MethodPost, "/notification-channel/mail/check"},
156+
}
157157

158-
httpassert.New(t, router).
159-
Post("/notification-channel/mail/check").
160-
AuthJwt(integrationTests.CreateJwtTokenWithRole(role)).
161-
Content(`{"domain":"example.com","port":123}`).
162-
Expect().
163-
StatusCode(http.StatusForbidden)
164-
})
158+
tests := []struct {
159+
role string
160+
wantAllow bool
161+
}{
162+
// ensure this is the same as in iam/roles.go
163+
{iam.OsiViewer, false},
164+
{iam.User, false},
165+
{iam.OsiUser, false},
166+
{iam.OsiAdmin, false},
167+
{iam.Admin, true},
168+
{iam.NotificationAdmin, true},
169+
{iam.Notification, false},
165170
}
166-
}
167171

168-
func TestCheckMailServer_AllowedRoles(t *testing.T) {
169-
t.Parallel()
172+
for _, tt := range tests {
173+
for _, ep := range endpoints {
174+
t.Run(ep.name+" as "+tt.role, func(t *testing.T) {
175+
t.Parallel()
170176

171-
allowedRoles := []string{iam.Admin, iam.NotificationAdmin}
177+
router, notificationChannelServicer := setup(t)
178+
notificationChannelServicer.EXPECT().CheckNotificationChannelConnectivity(mock.Anything, mock.Anything).Maybe().Return(nil)
172179

173-
for _, role := range allowedRoles {
174-
t.Run("Check mail server is allowed for role "+role, func(t *testing.T) {
175-
t.Parallel()
180+
req, _ := http.NewRequest(ep.method, ep.path, strings.NewReader(`{"domain":"example.com","port":123}`))
181+
req.Header.Set("Authorization", "Bearer "+integrationTests.CreateJwtTokenWithRole(tt.role))
176182

177-
router := setupCheckMailServerWithAuth(t)
183+
w := httptest.NewRecorder()
184+
router.ServeHTTP(w, req)
178185

179-
httpassert.New(t, router).
180-
Post("/notification-channel/mail/check").
181-
AuthJwt(integrationTests.CreateJwtTokenWithRole(role)).
182-
Content(`{"domain":"example.com","port":123}`).
183-
Expect().
184-
StatusCode(http.StatusNoContent)
185-
})
186+
if tt.wantAllow {
187+
require.NotEqual(t, http.StatusUnauthorized, w.Code)
188+
require.NotEqual(t, http.StatusForbidden, w.Code)
189+
} else {
190+
require.Equal(t, http.StatusForbidden, w.Code)
191+
}
192+
})
193+
}
186194
}
187195
}

pkg/web/mailcontroller/mailController_test.go

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1+
// SPDX-FileCopyrightText: 2026 Greenbone AG <https://greenbone.net>
2+
//
3+
// SPDX-License-Identifier: AGPL-3.0-or-later
4+
15
package mailcontroller
26

37
import (
48
"errors"
59
"net/http"
10+
"net/http/httptest"
611
"testing"
712

813
"github.com/gin-gonic/gin"
@@ -339,18 +344,17 @@ func setupWithAuth(t *testing.T) *gin.Engine {
339344
authMiddleware, err := auth.NewGinAuthMiddleware(integrationTests.NewTestJwtParser(t))
340345
require.NoError(t, err)
341346

342-
notificationChannelService.On("ListNotificationChannelsByType", mock.Anything, mock.Anything).Maybe().Return(nil, nil)
347+
notificationChannelService.EXPECT().ListNotificationChannelsByType(mock.Anything, mock.Anything).Maybe().Return(nil, nil)
348+
notificationChannelService.EXPECT().DeleteNotificationChannel(mock.Anything, mock.Anything).Maybe().Return(nil, nil)
343349

344350
NewMailController(router, notificationChannelService, mailChannelService, authMiddleware, registry)
345351
return router
346352
}
347353

348-
func TestMailController_ForbiddenRoles(t *testing.T) {
354+
func TestMailController_Permissions(t *testing.T) {
349355
t.Parallel()
350356

351-
forbiddenRoles := []string{iam.OsiViewer, iam.User, iam.OsiUser, iam.OsiAdmin, iam.Notification}
352-
353-
endpoints := []struct {
357+
var endpoints = []struct {
354358
name string
355359
method string
356360
path string
@@ -362,39 +366,39 @@ func TestMailController_ForbiddenRoles(t *testing.T) {
362366
{"Check mail server", http.MethodPost, "/notification-channel/mail/" + uuid.NewString() + "/check"},
363367
}
364368

365-
for _, role := range forbiddenRoles {
369+
tests := []struct {
370+
role string
371+
wantAllow bool
372+
}{
373+
// ensure this is the same as in iam/roles.go
374+
{iam.OsiViewer, false},
375+
{iam.User, false},
376+
{iam.OsiUser, false},
377+
{iam.OsiAdmin, false},
378+
{iam.Admin, true},
379+
{iam.NotificationAdmin, true},
380+
{iam.Notification, false},
381+
}
382+
383+
for _, tt := range tests {
366384
for _, ep := range endpoints {
367-
t.Run(ep.name+" is forbidden for role "+role, func(t *testing.T) {
385+
t.Run(ep.name+" as "+tt.role, func(t *testing.T) {
368386
t.Parallel()
369387

370388
router := setupWithAuth(t)
371389

372-
httpassert.New(t, router).
373-
Perform(ep.method, ep.path).
374-
AuthJwt(integrationTests.CreateJwtTokenWithRole(role)).
375-
Expect().
376-
StatusCode(http.StatusForbidden)
390+
req, _ := http.NewRequest(ep.method, ep.path, nil)
391+
req.Header.Set("Authorization", "Bearer "+integrationTests.CreateJwtTokenWithRole(tt.role))
392+
w := httptest.NewRecorder()
393+
router.ServeHTTP(w, req)
394+
395+
if tt.wantAllow {
396+
require.NotEqual(t, http.StatusUnauthorized, w.Code)
397+
require.NotEqual(t, http.StatusForbidden, w.Code)
398+
} else {
399+
require.Equal(t, http.StatusForbidden, w.Code)
400+
}
377401
})
378402
}
379403
}
380404
}
381-
382-
func TestMailController_AllowedRoles(t *testing.T) {
383-
t.Parallel()
384-
385-
allowedRoles := []string{iam.Admin, iam.NotificationAdmin}
386-
387-
for _, role := range allowedRoles {
388-
t.Run("List mail channels is allowed for role "+role, func(t *testing.T) {
389-
t.Parallel()
390-
391-
router := setupWithAuth(t)
392-
393-
httpassert.New(t, router).
394-
Get("/notification-channel/mail").
395-
AuthJwt(integrationTests.CreateJwtTokenWithRole(role)).
396-
Expect().
397-
StatusCode(http.StatusOK)
398-
})
399-
}
400-
}
Lines changed: 42 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
1+
// SPDX-FileCopyrightText: 2026 Greenbone AG <https://greenbone.net>
2+
//
3+
// SPDX-License-Identifier: AGPL-3.0-or-later
4+
15
package mattermostcontroller
26

37
import (
48
"net/http"
9+
"net/http/httptest"
510
"testing"
611

712
"github.com/gin-gonic/gin"
813
"github.com/google/uuid"
914
"github.com/greenbone/keycloak-client-golang/auth"
10-
"github.com/greenbone/opensight-golang-libraries/pkg/httpassert"
1115
"github.com/greenbone/opensight-notification-service/pkg/services/notificationchannelservice/mocks"
1216
"github.com/greenbone/opensight-notification-service/pkg/web/errmap"
1317
"github.com/greenbone/opensight-notification-service/pkg/web/iam"
@@ -17,7 +21,7 @@ import (
1721
"github.com/stretchr/testify/require"
1822
)
1923

20-
func setup(t *testing.T) *gin.Engine {
24+
func setupWithAuth(t *testing.T) *gin.Engine {
2125
registry := errmap.NewRegistry()
2226
router := testhelper.NewTestWebEngine(registry)
2327
notificationChannelService := mocks.NewNotificationChannelService(t)
@@ -26,60 +30,61 @@ func setup(t *testing.T) *gin.Engine {
2630
authMiddleware, err := auth.NewGinAuthMiddleware(integrationTests.NewTestJwtParser(t))
2731
require.NoError(t, err)
2832

29-
// We only test permissions, the method itself is not part of these tests.
30-
notificationChannelService.
31-
On("ListNotificationChannelsByType", mock.Anything, mock.Anything).
32-
Maybe().
33-
Return(nil, nil)
33+
notificationChannelService.EXPECT().ListNotificationChannelsByType(mock.Anything, mock.Anything).Maybe().Return(nil, nil)
34+
notificationChannelService.EXPECT().DeleteNotificationChannel(mock.Anything, mock.Anything).Maybe().Return(nil, nil)
3435

3536
NewMattermostController(router, notificationChannelService, mattermostChannelService, authMiddleware, registry)
3637
return router
3738
}
3839

39-
func TestMattermostController_ForbiddenRoles(t *testing.T) {
40-
router := setup(t)
41-
42-
forbiddenRoles := []string{iam.OsiViewer, iam.User, iam.OsiUser, iam.OsiAdmin, iam.Notification}
40+
func TestMattermostController_Permissions(t *testing.T) {
41+
t.Parallel()
4342

44-
type endpoint struct {
43+
var endpoints = []struct {
4544
name string
4645
method string
4746
path string
48-
}
49-
50-
endpoints := []endpoint{
47+
}{
5148
{"Create mattermost channel", http.MethodPost, "/notification-channel/mattermost"},
5249
{"List mattermost channels", http.MethodGet, "/notification-channel/mattermost"},
5350
{"Update mattermost channel", http.MethodPut, "/notification-channel/mattermost/" + uuid.NewString()},
5451
{"Delete mattermost channel", http.MethodDelete, "/notification-channel/mattermost/" + uuid.NewString()},
5552
{"Check mattermost channel", http.MethodPost, "/notification-channel/mattermost/check"},
5653
}
5754

58-
for _, role := range forbiddenRoles {
59-
for _, ep := range endpoints {
60-
t.Run(ep.name+" is forbidden for role "+role, func(t *testing.T) {
61-
httpassert.New(t, router).
62-
Perform(ep.method, ep.path).
63-
AuthJwt(integrationTests.CreateJwtTokenWithRole(role)).
64-
Expect().
65-
StatusCode(http.StatusForbidden)
66-
})
67-
}
55+
tests := []struct {
56+
role string
57+
wantAllow bool
58+
}{
59+
// ensure this is the same as in iam/roles.go
60+
{iam.OsiViewer, false},
61+
{iam.User, false},
62+
{iam.OsiUser, false},
63+
{iam.OsiAdmin, false},
64+
{iam.Admin, true},
65+
{iam.NotificationAdmin, true},
66+
{iam.Notification, false},
6867
}
69-
}
7068

71-
func TestMattermostController_AllowedRoles(t *testing.T) {
72-
router := setup(t)
69+
for _, tt := range tests {
70+
for _, ep := range endpoints {
71+
t.Run(ep.name+" as "+tt.role, func(t *testing.T) {
72+
t.Parallel()
73+
74+
router := setupWithAuth(t)
7375

74-
allowedRoles := []string{iam.Admin, iam.NotificationAdmin}
76+
req, _ := http.NewRequest(ep.method, ep.path, nil)
77+
req.Header.Set("Authorization", "Bearer "+integrationTests.CreateJwtTokenWithRole(tt.role))
78+
w := httptest.NewRecorder()
79+
router.ServeHTTP(w, req)
7580

76-
for _, role := range allowedRoles {
77-
t.Run("Access is granted for role "+role, func(t *testing.T) {
78-
httpassert.New(t, router).
79-
Get(`/notification-channel/mattermost`).
80-
AuthJwt(integrationTests.CreateJwtTokenWithRole(role)).
81-
Expect().
82-
StatusCode(http.StatusOK)
83-
})
81+
if tt.wantAllow {
82+
require.NotEqual(t, http.StatusUnauthorized, w.Code)
83+
require.NotEqual(t, http.StatusForbidden, w.Code)
84+
} else {
85+
require.Equal(t, http.StatusForbidden, w.Code)
86+
}
87+
})
88+
}
8489
}
8590
}

0 commit comments

Comments
 (0)