graphdb-workbench-tests 3.5.0-TR2 → 3.5.0-TR4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/e2e-legacy/setup/aclmanagement/create-rule.spec.js +1 -1
- package/e2e-legacy/setup/aclmanagement/delete-rule.spec.js +1 -1
- package/e2e-legacy/setup/aclmanagement/edit-rule.spec.js +1 -1
- package/e2e-legacy/setup/aclmanagement/render-rules.spec.js +1 -1
- package/e2e-legacy/setup/aclmanagement/reorder-rules.spec.js +1 -1
- package/e2e-legacy/setup/aclmanagement/revert-rules.spec.js +1 -1
- package/e2e-legacy/setup/aclmanagement/scopes.spec.js +2 -2
- package/e2e-legacy/setup/aclmanagement/update-rules.spec.js +2 -2
- package/e2e-legacy/setup/jdbc/jdbc-create.spec.js +1 -1
- package/e2e-legacy/setup/users-and-access/user-and-access.spec.js +662 -338
- package/e2e-legacy/sparql-editor/saved-query/readonly-query.spec.js +1 -1
- package/e2e-legacy/ttyg/agent-select-menu.spec.js +7 -1
- package/e2e-legacy/ttyg/edit-agent.spec.js +2 -2
- package/e2e-legacy/ttyg/ttyg-permission.spec.js +2 -1
- package/e2e-security/setup/users-and-access/create-user-permissions.spec.js +15 -15
- package/e2e-security/setup/users-and-access/graphql-user.spec.js +3 -3
- package/e2e-security/setup/users-and-access/repo-admin-role.spec.js +2 -2
- package/eslint.config.js +1 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +2 -2
- package/steps/application-steps.js +1 -1
- package/steps/deprecation-banner/deprecation-banner-steps.js +13 -0
- package/steps/main-menu-steps.js +5 -1
- package/steps/repository-steps.js +44 -3
- package/steps/setup/user-and-access-steps.js +81 -53
- package/steps/ttyg/ttyg-view-steps.js +3 -0
- package/stubs/security-stubs.js +4 -0
|
@@ -7,6 +7,7 @@ import HomeSteps from '../../../steps/home-steps';
|
|
|
7
7
|
import {LoginSteps} from '../../../steps/login-steps';
|
|
8
8
|
import {MainMenuSteps} from '../../../steps/main-menu-steps';
|
|
9
9
|
import {SecurityStubs} from '../../../stubs/security-stubs.js';
|
|
10
|
+
import {RepositorySteps} from '../../../steps/repository-steps.js';
|
|
10
11
|
|
|
11
12
|
describe('User and Access', () => {
|
|
12
13
|
|
|
@@ -16,11 +17,25 @@ describe('User and Access', () => {
|
|
|
16
17
|
const ROLE_CUSTOM_ADMIN = '#roleAdmin';
|
|
17
18
|
const DEFAULT_ADMIN_PASSWORD = 'root';
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
context('', () => {
|
|
20
|
+
context('User and access management', () => {
|
|
21
21
|
const user = 'user';
|
|
22
|
+
let repoName;
|
|
23
|
+
|
|
24
|
+
before(() => {
|
|
25
|
+
repoName = 'user-access-repo1-' + Date.now();
|
|
26
|
+
cy.createRepository({id: repoName});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
after(() => {
|
|
30
|
+
cy.loginAsAdmin().then(() => {
|
|
31
|
+
cy.switchOffSecurity(true);
|
|
32
|
+
cy.switchOffFreeAccess(false);
|
|
33
|
+
});
|
|
34
|
+
cy.deleteRepository(repoName, true);
|
|
35
|
+
});
|
|
22
36
|
|
|
23
37
|
beforeEach(() => {
|
|
38
|
+
SecurityStubs.spyOnUserGet();
|
|
24
39
|
UserAndAccessSteps.visit();
|
|
25
40
|
// Users table should be visible
|
|
26
41
|
UserAndAccessSteps.getUsersTable().should('be.visible');
|
|
@@ -35,191 +50,375 @@ describe('User and Access', () => {
|
|
|
35
50
|
});
|
|
36
51
|
});
|
|
37
52
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
context('Initial state', () => {
|
|
54
|
+
it('Initial state', () => {
|
|
55
|
+
// Create new user button should be visible
|
|
56
|
+
UserAndAccessSteps.getCreateNewUserButton().should('be.visible');
|
|
57
|
+
// Security should be disabled
|
|
58
|
+
UserAndAccessSteps.getSecuritySwitchLabel().should('be.visible').and('contain', 'Security is OFF');
|
|
59
|
+
UserAndAccessSteps.getSecurityCheckbox().should('not.be.checked');
|
|
60
|
+
// Only admin user should be created by default
|
|
61
|
+
UserAndAccessSteps.getTableRow().should('have.length', 1);
|
|
62
|
+
UserAndAccessSteps.findUserInTable('admin');
|
|
63
|
+
UserAndAccessSteps.getUserType().should('be.visible').and('contain', 'Administrator');
|
|
64
|
+
// The admin should have unrestricted rights
|
|
65
|
+
UserAndAccessSteps.getRepositoryRights().should('be.visible').and('contain', 'Unrestricted');
|
|
66
|
+
// And can be edited
|
|
67
|
+
UserAndAccessSteps.getEditUserButton().should('be.visible').and('not.be.disabled');
|
|
68
|
+
// And cannot be deleted
|
|
69
|
+
UserAndAccessSteps.getDeleteUserButton().should('not.exist');
|
|
70
|
+
// Date created should be visible
|
|
71
|
+
UserAndAccessSteps.getDateCreated().should('be.visible');
|
|
72
|
+
});
|
|
56
73
|
});
|
|
57
74
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
75
|
+
context('User creation', () => {
|
|
76
|
+
it('Create user', () => {
|
|
77
|
+
//create a normal read/write user
|
|
78
|
+
createUser(user, PASSWORD, ROLE_USER, {readWrite: true});
|
|
79
|
+
testForUser(user, false);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('Create manage user', () => {
|
|
83
|
+
createUser(user, PASSWORD, ROLE_USER, {manage: true, repoName});
|
|
84
|
+
testForUser(user, false);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('Create repo-manager', () => {
|
|
88
|
+
//create a repo-manager
|
|
89
|
+
createUser(user, PASSWORD, ROLE_REPO_MANAGER);
|
|
90
|
+
testForUser(user, false);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('Create second admin', () => {
|
|
94
|
+
//create a custom admin
|
|
95
|
+
createUser(user, PASSWORD, ROLE_CUSTOM_ADMIN);
|
|
96
|
+
testForUser(user, true);
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('Create user with custom role', () => {
|
|
100
|
+
// When I create a read/write user
|
|
101
|
+
UserAndAccessSteps.clickCreateNewUserButton();
|
|
102
|
+
UserAndAccessSteps.typeUsername(user);
|
|
103
|
+
UserAndAccessSteps.typePassword(PASSWORD);
|
|
104
|
+
UserAndAccessSteps.typeConfirmPasswordField(PASSWORD);
|
|
105
|
+
UserAndAccessSteps.selectRoleRadioButton(ROLE_USER);
|
|
106
|
+
// And add a custom role of 1 letter
|
|
107
|
+
UserAndAccessSteps.addTextToCustomRoleField('A');
|
|
108
|
+
UserAndAccessSteps.toggleWriteAccessAny();
|
|
109
|
+
|
|
110
|
+
// Then the 'create' button should be disabled
|
|
111
|
+
UserAndAccessSteps.getConfirmUserCreateButton().should('be.disabled');
|
|
112
|
+
// And the field should show an error
|
|
113
|
+
UserAndAccessSteps.getCustomRoleFieldError().should('contain.text', 'Must be at least 2 symbols long');
|
|
114
|
+
// When I add more text to the custom role tag
|
|
115
|
+
UserAndAccessSteps.addTextToCustomRoleField('A{enter}');
|
|
116
|
+
// Then the 'create' button should be enabled
|
|
117
|
+
UserAndAccessSteps.getConfirmUserCreateButton().should('be.enabled');
|
|
118
|
+
// And the field error should not exist
|
|
119
|
+
UserAndAccessSteps.getCustomRoleFieldError().should('not.be.visible');
|
|
120
|
+
|
|
121
|
+
// When I type an invalid tag
|
|
122
|
+
UserAndAccessSteps.addTextToCustomRoleField('B{enter}');
|
|
123
|
+
// And the field shows an error
|
|
124
|
+
UserAndAccessSteps.getCustomRoleFieldError().should('contain.text', 'Must be at least 2 symbols long');
|
|
125
|
+
// When I delete the invalid text
|
|
126
|
+
UserAndAccessSteps.addTextToCustomRoleField('{backspace}');
|
|
127
|
+
// Then the error should not be visible
|
|
128
|
+
UserAndAccessSteps.getCustomRoleFieldError().should('not.be.visible');
|
|
129
|
+
|
|
130
|
+
// When I create the user with a valid custom role
|
|
131
|
+
UserAndAccessSteps.toggleWriteAccessAny();
|
|
132
|
+
SecurityStubs.spyOnUserCreate();
|
|
133
|
+
UserAndAccessSteps.confirmUserCreate();
|
|
134
|
+
// Then the user should be created with that custom role
|
|
135
|
+
cy.wait('@create-user').its('request.body').then((body) => {
|
|
136
|
+
expect(body).to.deep.eq({
|
|
137
|
+
'password': 'password',
|
|
138
|
+
'grantedAuthorities': [
|
|
139
|
+
'ROLE_USER',
|
|
140
|
+
'CUSTOM_AA',
|
|
141
|
+
'WRITE_REPO_*',
|
|
142
|
+
'READ_REPO_*',
|
|
143
|
+
],
|
|
144
|
+
'appSettings': {
|
|
145
|
+
'DEFAULT_VIS_GRAPH_SCHEMA': true,
|
|
146
|
+
'DEFAULT_INFERENCE': true,
|
|
147
|
+
'DEFAULT_SAMEAS': true,
|
|
148
|
+
'IGNORE_SHARED_QUERIES': false,
|
|
149
|
+
'EXECUTE_COUNT': true,
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
cy.url().should('include', '/users');
|
|
155
|
+
UserAndAccessSteps.findUserInTable(user).should('be.visible');
|
|
156
|
+
UserAndAccessSteps.getUserCustomRoles('@user')
|
|
157
|
+
.should('have.length', 1)
|
|
158
|
+
.eq(0).and('have.text', 'AA');
|
|
159
|
+
// And when I open the edit page for that user, the custom role should be visible in the field without the prefix
|
|
160
|
+
UserAndAccessSteps.openEditUserPage(user);
|
|
161
|
+
cy.wait('@get-user');
|
|
162
|
+
UserAndAccessSteps.getCustomRoleField().find('.tag-item span')
|
|
163
|
+
.should('have.length', 1)
|
|
164
|
+
.eq(0).and('have.text', 'AA');
|
|
165
|
+
});
|
|
63
166
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
167
|
+
it('Adding a role with a CUSTOM_ prefix shows a warning message', () => {
|
|
168
|
+
// When I create a user
|
|
169
|
+
UserAndAccessSteps.clickCreateNewUserButton();
|
|
170
|
+
// And I add a custom role tag with prefix CUSTOM_
|
|
171
|
+
UserAndAccessSteps.addTextToCustomRoleField('CUSTOM_USER{Enter}');
|
|
172
|
+
// There should be a warning text
|
|
173
|
+
UserAndAccessSteps.getPrefixWarning(0).should('contain', 'Custom roles should be entered without the "CUSTOM_" prefix in Workbench');
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it('Warn users when setting no password when creating new user admin', () => {
|
|
177
|
+
UserAndAccessSteps.getUsersTable().should('be.visible');
|
|
178
|
+
createUser(user, PASSWORD, ROLE_CUSTOM_ADMIN, {noPassword: true});
|
|
179
|
+
UserAndAccessSteps.getUsersTable().should('be.visible');
|
|
180
|
+
UserAndAccessSteps.getSplashLoader().should('not.be.visible');
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
// Skipped until image with GDB implementation is available
|
|
184
|
+
it.skip('should create user with manage repo rights for specific repo', () => {
|
|
185
|
+
SecurityStubs.spyOnUserCreate();
|
|
186
|
+
UserAndAccessSteps.getUsersCatalogContainer().should('be.visible');
|
|
187
|
+
createUser(user, PASSWORD, ROLE_USER, {manage: true, repoName: repoName});
|
|
188
|
+
// Then the user should be created with that custom role
|
|
189
|
+
cy.wait('@create-user').its('request.body').then((body) => {
|
|
190
|
+
expect(body).to.deep.eq({
|
|
191
|
+
'password': 'password',
|
|
192
|
+
'grantedAuthorities': [
|
|
193
|
+
'ROLE_USER',
|
|
194
|
+
`MANAGE_REPO_${repoName}`,
|
|
195
|
+
`WRITE_REPO_${repoName}`,
|
|
196
|
+
`READ_REPO_${repoName}`,
|
|
197
|
+
],
|
|
198
|
+
'appSettings': {
|
|
199
|
+
'DEFAULT_VIS_GRAPH_SCHEMA': true,
|
|
200
|
+
'DEFAULT_INFERENCE': true,
|
|
201
|
+
'DEFAULT_SAMEAS': true,
|
|
202
|
+
'IGNORE_SHARED_QUERIES': false,
|
|
203
|
+
'EXECUTE_COUNT': true,
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
UserAndAccessSteps.getUsersCatalogContainer().should('be.visible');
|
|
208
|
+
assertUserAuthsInCatalog(user, {repo: repoName, read: false, manage: true, graphql: false});
|
|
209
|
+
|
|
210
|
+
UserAndAccessSteps.openEditUserPage(user);
|
|
211
|
+
cy.wait('@get-user');
|
|
212
|
+
UserAndAccessSteps.getRepositoryRightsList().should('be.visible');
|
|
213
|
+
verifyCheckedUserAuth(repoName, {read: true, write: true, manage: true, graphql: false});
|
|
214
|
+
verifyDisabledUserAuth(repoName, {read: true, write: true, manage: false, graphql: true});
|
|
215
|
+
});
|
|
68
216
|
});
|
|
69
217
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
218
|
+
context('Free access', () => {
|
|
219
|
+
it('should toggle free access after Admin has logged in', () => {
|
|
220
|
+
// Given I have available repositories to allow Free Access for
|
|
221
|
+
RepositoriesStubs.stubRepositories();
|
|
222
|
+
RepositoriesStubs.stubFreeAccess();
|
|
223
|
+
// When I enable security
|
|
224
|
+
UserAndAccessSteps.toggleSecurity();
|
|
225
|
+
// When I log in as an Admin
|
|
226
|
+
LoginSteps.loginWithUser('admin', DEFAULT_ADMIN_PASSWORD);
|
|
227
|
+
// Then the page should load
|
|
228
|
+
UserAndAccessSteps.getSplashLoader().should('not.be.visible');
|
|
229
|
+
UserAndAccessSteps.getUsersTable().should('be.visible');
|
|
230
|
+
// The Free Access toggle should be OFF
|
|
231
|
+
UserAndAccessSteps.getFreeAccessSwitchInput().should('not.be.checked');
|
|
232
|
+
// When I toggle Free Access ON
|
|
233
|
+
UserAndAccessSteps.toggleFreeAccess();
|
|
234
|
+
// And I allow free access to a repository
|
|
235
|
+
ModalDialogSteps.getDialog().should('be.visible');
|
|
236
|
+
// Then I click OK in the modal
|
|
237
|
+
ModalDialogSteps.clickOKButton();
|
|
238
|
+
// Then the toggle button should be ON
|
|
239
|
+
UserAndAccessSteps.getFreeAccessSwitchInput().should('be.checked');
|
|
240
|
+
// And I should see a success message
|
|
241
|
+
ToasterSteps.verifySuccess('Free access has been enabled.');
|
|
242
|
+
ToasterSteps.getToast().should('not.exist');
|
|
243
|
+
UserAndAccessSteps.getUsersTable().should('be.visible');
|
|
244
|
+
// When I toggle Free Access OFF
|
|
245
|
+
UserAndAccessSteps.toggleFreeAccess();
|
|
246
|
+
// Then I should see a success message
|
|
247
|
+
ToasterSteps.getToast().should('exist');
|
|
248
|
+
ToasterSteps.getToasterMessage().should('contain', 'Free access has been disabled.');
|
|
249
|
+
});
|
|
74
250
|
});
|
|
75
251
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
UserAndAccessSteps.addTextToCustomRoleField('B{enter}');
|
|
100
|
-
// And the field shows an error
|
|
101
|
-
UserAndAccessSteps.getCustomRoleFieldError().should('contain.text', 'Must be at least 2 symbols long');
|
|
102
|
-
// When I delete the invalid text
|
|
103
|
-
UserAndAccessSteps.addTextToCustomRoleField('{backspace}');
|
|
104
|
-
// Then the error should not be visible
|
|
105
|
-
UserAndAccessSteps.getCustomRoleFieldError().should('not.be.visible');
|
|
106
|
-
|
|
107
|
-
// When I create the user with a valid custom role
|
|
108
|
-
UserAndAccessSteps.clickWriteAccessAny();
|
|
109
|
-
SecurityStubs.spyOnUserCreate()
|
|
110
|
-
UserAndAccessSteps.confirmUserCreate();
|
|
111
|
-
// Then the user should be created with that custom role
|
|
112
|
-
cy.wait('@create-user').its('request.body').then((body) => {
|
|
113
|
-
expect(body).to.deep.eq({
|
|
114
|
-
"password": "password",
|
|
115
|
-
"grantedAuthorities": [
|
|
116
|
-
"ROLE_USER",
|
|
117
|
-
"CUSTOM_AA",
|
|
118
|
-
"WRITE_REPO_*",
|
|
119
|
-
"READ_REPO_*"
|
|
120
|
-
],
|
|
121
|
-
"appSettings": {
|
|
122
|
-
"DEFAULT_VIS_GRAPH_SCHEMA": true,
|
|
123
|
-
"DEFAULT_INFERENCE": true,
|
|
124
|
-
"DEFAULT_SAMEAS": true,
|
|
125
|
-
"IGNORE_SHARED_QUERIES": false,
|
|
126
|
-
"EXECUTE_COUNT": true
|
|
127
|
-
}
|
|
128
|
-
})
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
cy.url().should('include', '/users');
|
|
132
|
-
UserAndAccessSteps.findUserInTable(user).should('be.visible');
|
|
133
|
-
UserAndAccessSteps.getUserCustomRoles('@user')
|
|
134
|
-
.should('have.length', 1)
|
|
135
|
-
.eq(0).and('have.text', 'AA');
|
|
136
|
-
// And when I open the edit page for that user, the custom role should be visible in the field without the prefix
|
|
137
|
-
UserAndAccessSteps.openEditUserPage(user);
|
|
138
|
-
UserAndAccessSteps.getCustomRoleField().find('.tag-item span')
|
|
139
|
-
.should('have.length', 1)
|
|
140
|
-
.eq(0).and('have.text', 'AA');
|
|
252
|
+
context('Login / return URL redirects', () => {
|
|
253
|
+
it('should redirect to previous page after logout and then login', () => {
|
|
254
|
+
UserAndAccessSteps.toggleSecurity();
|
|
255
|
+
LoginSteps.loginWithUser('admin', DEFAULT_ADMIN_PASSWORD);
|
|
256
|
+
MainMenuSteps.clickOnSparqlMenu();
|
|
257
|
+
cy.url().should('include', '/sparql');
|
|
258
|
+
|
|
259
|
+
LoginSteps.logout();
|
|
260
|
+
cy.url().should('include', '/login');
|
|
261
|
+
LoginSteps.loginWithUser('admin', DEFAULT_ADMIN_PASSWORD);
|
|
262
|
+
cy.url().should('include', '/sparql');
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
it('should redirect to correct return url when user is authenticated and on login page', () => {
|
|
266
|
+
UserAndAccessSteps.visit();
|
|
267
|
+
UserAndAccessSteps.toggleSecurity();
|
|
268
|
+
LoginSteps.loginWithUser('admin', DEFAULT_ADMIN_PASSWORD);
|
|
269
|
+
UserAndAccessSteps.getUsersTable().should('be.visible');
|
|
270
|
+
|
|
271
|
+
cy.visit('/login?r=%252Fsparql');
|
|
272
|
+
cy.reload();
|
|
273
|
+
UserAndAccessSteps.getUrl().should('include', '/sparql');
|
|
274
|
+
});
|
|
141
275
|
});
|
|
276
|
+
});
|
|
142
277
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
278
|
+
context('Verify access states', () => {
|
|
279
|
+
let repoName;
|
|
280
|
+
|
|
281
|
+
before(() => {
|
|
282
|
+
repoName = 'user-access-repo1-' + Date.now();
|
|
283
|
+
cy.createRepository({id: repoName});
|
|
284
|
+
cy.switchOffSecurity(true);
|
|
285
|
+
SecurityStubs.spyOnUserGet();
|
|
150
286
|
});
|
|
151
287
|
|
|
152
|
-
|
|
153
|
-
UserAndAccessSteps.
|
|
154
|
-
|
|
288
|
+
beforeEach(() => {
|
|
289
|
+
UserAndAccessSteps.visit();
|
|
290
|
+
// Users table should be visible
|
|
155
291
|
UserAndAccessSteps.getUsersTable().should('be.visible');
|
|
156
|
-
UserAndAccessSteps.getSplashLoader().should('not.be.visible');
|
|
157
292
|
});
|
|
158
293
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
// When I log in as an Admin
|
|
166
|
-
LoginSteps.loginWithUser('admin', DEFAULT_ADMIN_PASSWORD);
|
|
167
|
-
// Then the page should load
|
|
168
|
-
UserAndAccessSteps.getSplashLoader().should('not.be.visible');
|
|
169
|
-
UserAndAccessSteps.getUsersTable().should('be.visible');
|
|
170
|
-
// The Free Access toggle should be OFF
|
|
171
|
-
UserAndAccessSteps.getFreeAccessSwitchInput().should('not.be.checked');
|
|
172
|
-
// When I toggle Free Access ON
|
|
173
|
-
UserAndAccessSteps.toggleFreeAccess();
|
|
174
|
-
// And I allow free access to a repository
|
|
175
|
-
ModalDialogSteps.getDialog().should('be.visible');
|
|
176
|
-
// Then I click OK in the modal
|
|
177
|
-
ModalDialogSteps.clickOKButton();
|
|
178
|
-
// Then the toggle button should be ON
|
|
179
|
-
UserAndAccessSteps.getFreeAccessSwitchInput().should('be.checked');
|
|
180
|
-
// And I should see a success message
|
|
181
|
-
ToasterSteps.verifySuccess('Free access has been enabled.');
|
|
182
|
-
ToasterSteps.getToast().should('not.exist');
|
|
183
|
-
UserAndAccessSteps.getUsersTable().should('be.visible');
|
|
184
|
-
// When I toggle Free Access OFF
|
|
185
|
-
UserAndAccessSteps.toggleFreeAccess();
|
|
186
|
-
// Then I should see a success message
|
|
187
|
-
ToasterSteps.getToast().should('exist');
|
|
188
|
-
ToasterSteps.getToasterMessage().should('contain', 'Free access has been disabled.');
|
|
294
|
+
after(() => {
|
|
295
|
+
cy.loginAsAdmin().then(() => {
|
|
296
|
+
cy.deleteRepository(repoName, true);
|
|
297
|
+
cy.switchOffFreeAccess(true);
|
|
298
|
+
cy.switchOffSecurity(true);
|
|
299
|
+
});
|
|
189
300
|
});
|
|
190
301
|
|
|
191
|
-
it('
|
|
192
|
-
UserAndAccessSteps.
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
LoginSteps.logout();
|
|
198
|
-
cy.url().should('include', '/login');
|
|
199
|
-
LoginSteps.loginWithUser('admin', DEFAULT_ADMIN_PASSWORD);
|
|
200
|
-
cy.url().should('include', '/sparql');
|
|
302
|
+
it('initial state', () => {
|
|
303
|
+
UserAndAccessSteps.clickCreateNewUserButton();
|
|
304
|
+
verifyCheckedUserAuth('*', {read: false, write: false, manage: false, graphql: false});
|
|
305
|
+
verifyDisabledUserAuth('*', {read: false, write: false, manage: true, graphql: true});
|
|
306
|
+
verifyCheckedUserAuth(repoName, {read: false, write: false, manage: false, graphql: false});
|
|
307
|
+
verifyDisabledUserAuth(repoName, {read: false, write: false, manage: false, graphql: true});
|
|
201
308
|
});
|
|
202
309
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
310
|
+
context('for non user roles', () => {
|
|
311
|
+
it('admin', () => {
|
|
312
|
+
UserAndAccessSteps.clickCreateNewUserButton();
|
|
313
|
+
UserAndAccessSteps.selectRoleRadioButton(ROLE_CUSTOM_ADMIN);
|
|
314
|
+
verifyCheckedUserAuth('*', {read: true, write: true, manage: true, graphql: false});
|
|
315
|
+
verifyDisabledUserAuth('*', {read: true, write: true, manage: true, graphql: true});
|
|
316
|
+
|
|
317
|
+
verifyCheckedUserAuth(repoName, {read: true, write: true, manage: true, graphql: false});
|
|
318
|
+
verifyDisabledUserAuth(repoName, {read: true, write: true, manage: true, graphql: true});
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
it('repository manager', () => {
|
|
322
|
+
UserAndAccessSteps.clickCreateNewUserButton();
|
|
323
|
+
UserAndAccessSteps.selectRoleRadioButton(ROLE_REPO_MANAGER);
|
|
208
324
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
325
|
+
verifyCheckedUserAuth('*', {read: true, write: true, manage: true, graphql: false});
|
|
326
|
+
verifyDisabledUserAuth('*', {read: true, write: true, manage: true, graphql: true});
|
|
327
|
+
|
|
328
|
+
verifyCheckedUserAuth(repoName, {read: true, write: true, manage: true, graphql: false});
|
|
329
|
+
verifyDisabledUserAuth(repoName, {read: true, write: true, manage: true, graphql: true});
|
|
330
|
+
});
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
context('for specific repo', () => {
|
|
334
|
+
it('read', () => {
|
|
335
|
+
UserAndAccessSteps.clickCreateNewUserButton();
|
|
336
|
+
setRoles({read: true, repoName});
|
|
337
|
+
verifyCheckedUserAuth(repoName, {read: true, write: false, manage: false, graphql: false});
|
|
338
|
+
verifyDisabledUserAuth(repoName, {read: false, write: false, manage: false, graphql: false});
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
it('write', () => {
|
|
342
|
+
UserAndAccessSteps.clickCreateNewUserButton();
|
|
343
|
+
setRoles({readWrite: true, repoName});
|
|
344
|
+
verifyCheckedUserAuth(repoName, {read: true, write: true, manage: false, graphql: false});
|
|
345
|
+
verifyDisabledUserAuth(repoName, {read: true, write: false, manage: false, graphql: false});
|
|
346
|
+
});
|
|
347
|
+
|
|
348
|
+
it('manage', () => {
|
|
349
|
+
UserAndAccessSteps.clickCreateNewUserButton();
|
|
350
|
+
setRoles({manage: true, repoName});
|
|
351
|
+
verifyCheckedUserAuth(repoName, {read: true, write: true, manage: true, graphql: false});
|
|
352
|
+
verifyDisabledUserAuth(repoName, {read: true, write: true, manage: false, graphql: true});
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
it('graphql with read', () => {
|
|
356
|
+
UserAndAccessSteps.clickCreateNewUserButton();
|
|
357
|
+
setRoles({read: true, graphql: true, repoName});
|
|
358
|
+
verifyCheckedUserAuth(repoName, {read: true, write: false, manage: false, graphql: true});
|
|
359
|
+
verifyDisabledUserAuth(repoName, {read: false, write: false, manage: false, graphql: false});
|
|
360
|
+
});
|
|
361
|
+
|
|
362
|
+
it('graphql with write', () => {
|
|
363
|
+
UserAndAccessSteps.clickCreateNewUserButton();
|
|
364
|
+
setRoles({readWrite: true, graphql: true, repoName});
|
|
365
|
+
verifyCheckedUserAuth(repoName, {read: true, write: true, manage: false, graphql: true});
|
|
366
|
+
verifyDisabledUserAuth(repoName, {read: true, write: false, manage: false, graphql: false});
|
|
367
|
+
});
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
context('for any repo', () => {
|
|
371
|
+
let anyRepo = '*';
|
|
372
|
+
|
|
373
|
+
it('read', () => {
|
|
374
|
+
UserAndAccessSteps.clickCreateNewUserButton();
|
|
375
|
+
setRoles({read: true, anyRepo});
|
|
376
|
+
verifyCheckedUserAuth(anyRepo, {read: true, write: false, manage: false, graphql: false});
|
|
377
|
+
verifyDisabledUserAuth(anyRepo, {read: false, write: false, manage: true, graphql: false});
|
|
378
|
+
|
|
379
|
+
verifyCheckedUserAuth(repoName, {read: true, write: false, manage: false, graphql: false});
|
|
380
|
+
verifyDisabledUserAuth(repoName, {read: true, write: false, manage: false, graphql: false});
|
|
381
|
+
});
|
|
382
|
+
|
|
383
|
+
it('write', () => {
|
|
384
|
+
UserAndAccessSteps.clickCreateNewUserButton();
|
|
385
|
+
setRoles({readWrite: true, anyRepo});
|
|
386
|
+
verifyCheckedUserAuth(anyRepo, {read: true, write: true, manage: false, graphql: false});
|
|
387
|
+
verifyDisabledUserAuth(anyRepo, {read: true, write: false, manage: true, graphql: false});
|
|
388
|
+
|
|
389
|
+
verifyCheckedUserAuth(repoName, {read: true, write: true, manage: false, graphql: false});
|
|
390
|
+
verifyDisabledUserAuth(repoName, {read: true, write: true, manage: false, graphql: false});
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
it('graphql with read', () => {
|
|
394
|
+
UserAndAccessSteps.clickCreateNewUserButton();
|
|
395
|
+
setRoles({read: true, graphql: true, anyRepo});
|
|
396
|
+
verifyCheckedUserAuth(anyRepo, {read: true, write: false, manage: false, graphql: true});
|
|
397
|
+
verifyDisabledUserAuth(anyRepo, {read: false, write: false, manage: true, graphql: false});
|
|
398
|
+
|
|
399
|
+
verifyCheckedUserAuth(repoName, {read: true, write: false, manage: false, graphql: true});
|
|
400
|
+
verifyDisabledUserAuth(repoName, {read: true, write: false, manage: false, graphql: true});
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
it('graphql with write', () => {
|
|
404
|
+
UserAndAccessSteps.clickCreateNewUserButton();
|
|
405
|
+
setRoles({readWrite: true, graphql: true, anyRepo});
|
|
406
|
+
verifyCheckedUserAuth(anyRepo, {read: true, write: true, manage: false, graphql: true});
|
|
407
|
+
verifyDisabledUserAuth(anyRepo, {read: true, write: false, manage: true, graphql: false});
|
|
408
|
+
|
|
409
|
+
verifyCheckedUserAuth(repoName, {read: true, write: true, manage: false, graphql: true});
|
|
410
|
+
verifyDisabledUserAuth(repoName, {read: true, write: true, manage: false, graphql: true});
|
|
411
|
+
});
|
|
212
412
|
});
|
|
213
413
|
});
|
|
214
|
-
|
|
215
|
-
context('GraphQL
|
|
414
|
+
|
|
415
|
+
context('GraphQL access', () => {
|
|
216
416
|
let repositoryId1;
|
|
217
417
|
let repositoryId2;
|
|
218
418
|
let repositoryId3;
|
|
219
419
|
const graphqlUser = 'graphqlUser';
|
|
220
420
|
|
|
221
421
|
beforeEach(() => {
|
|
222
|
-
cy.viewport(1280, 1000);
|
|
223
422
|
RepositoriesStubs.spyGetRepositories();
|
|
224
423
|
repositoryId1 = 'user-access-repo1-' + Date.now();
|
|
225
424
|
repositoryId2 = 'user-access-repo2-' + Date.now();
|
|
@@ -231,6 +430,7 @@ describe('User and Access', () => {
|
|
|
231
430
|
UserAndAccessSteps.visit();
|
|
232
431
|
// Users table should be visible
|
|
233
432
|
UserAndAccessSteps.getUsersTable().should('be.visible');
|
|
433
|
+
SecurityStubs.spyOnUserGet();
|
|
234
434
|
});
|
|
235
435
|
|
|
236
436
|
afterEach(() => {
|
|
@@ -245,174 +445,286 @@ describe('User and Access', () => {
|
|
|
245
445
|
|
|
246
446
|
});
|
|
247
447
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
448
|
+
context('GraphQL checkbox behavior', () => {
|
|
449
|
+
it('Create user with GraphQL-only access', () => {
|
|
450
|
+
cy.wait('@getRepositories');
|
|
451
|
+
createUser(graphqlUser, PASSWORD, ROLE_USER, {read: true, graphql: true, repoName: repositoryId2});
|
|
452
|
+
});
|
|
252
453
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
454
|
+
// Fails for unknown reason only in CI
|
|
455
|
+
it('Can create user with different auth combinations', () => {
|
|
456
|
+
cy.wait('@getRepositories');
|
|
457
|
+
cy.wait('@getRepositories');
|
|
458
|
+
UserAndAccessSteps.getUsersCatalogContainer().should('be.visible');
|
|
459
|
+
// WHEN I create a user with read + GraphQL for repository #2
|
|
460
|
+
createUser(graphqlUser, PASSWORD, ROLE_USER, {read: true, graphql: true, repoName: repositoryId2});
|
|
461
|
+
// THEN the user should have read + GraphQL on that repo
|
|
462
|
+
assertUserAuthsInCatalog(graphqlUser, {repo: repositoryId2, read: true, graphql: true});
|
|
463
|
+
// WHEN I open the edit page for that user
|
|
464
|
+
UserAndAccessSteps.openEditUserPage(graphqlUser);
|
|
465
|
+
cy.wait('@get-user');
|
|
466
|
+
// THEN for repository #1, the GraphQL checkbox should be disabled initially
|
|
467
|
+
UserAndAccessSteps.validateGraphqlAccessForRepo(repositoryId1, {disabled: true});
|
|
468
|
+
// WHEN I enable "read" for repository #1
|
|
469
|
+
setUserAuths({repo: repositoryId1, read: true});
|
|
470
|
+
// THEN GraphQL for repository #1 should become enabled
|
|
471
|
+
UserAndAccessSteps.validateGraphqlAccessForRepo(repositoryId1, {disabled: false});
|
|
472
|
+
// WHEN I enable GraphQL with read
|
|
473
|
+
setUserAuths({repo: repositoryId1, graphql: true});
|
|
474
|
+
// THEN GraphQL should be checked and enabled
|
|
475
|
+
UserAndAccessSteps.validateGraphqlAccessForRepo(repositoryId1, {checked: true, disabled: false});
|
|
476
|
+
// THEN for repository #3, GraphQL should be disabled initially
|
|
477
|
+
UserAndAccessSteps.validateGraphqlAccessForRepo(repositoryId3, {disabled: true});
|
|
478
|
+
// WHEN I enable "write" for repository #3
|
|
479
|
+
setUserAuths({repo: repositoryId3, write: true});
|
|
480
|
+
// THEN GraphQL for repository #3 should become enabled
|
|
481
|
+
UserAndAccessSteps.validateGraphqlAccessForRepo(repositoryId3, {disabled: false});
|
|
482
|
+
// And I expect "read" to be checked and disabled
|
|
483
|
+
UserAndAccessSteps.validateReadAccessForRepo(repositoryId3, {checked: true, disabled: true});
|
|
484
|
+
// I enable GraphQL for repository #3
|
|
485
|
+
setUserAuths({repo: repositoryId3, graphql: true});
|
|
486
|
+
// THEN GraphQL should be checked and enabled
|
|
487
|
+
UserAndAccessSteps.validateGraphqlAccessForRepo(repositoryId1, {checked: true, disabled: false});
|
|
488
|
+
// When I remove "read" for repository #2
|
|
489
|
+
UserAndAccessSteps.toggleReadAccessForRepo(repositoryId2);
|
|
490
|
+
// THEN I expect "graphql" to be unchecked and disabled for repository #2
|
|
491
|
+
UserAndAccessSteps.validateGraphqlAccessForRepo(repositoryId2, {checked: false, disabled: true});
|
|
492
|
+
|
|
493
|
+
// WHEN I confirm the user edit
|
|
494
|
+
UserAndAccessSteps.confirmUserEdit();
|
|
495
|
+
// THEN verify the final rights:
|
|
496
|
+
// - repo #1 has no read/write/graphql
|
|
497
|
+
// - repo #2 has read + graphql
|
|
498
|
+
// - repo #3 has write + graphql (and read was auto-checked but disabled)
|
|
499
|
+
assertUserAuthsInCatalog(graphqlUser, {repo: repositoryId1, read: true, write: false, graphql: true});
|
|
500
|
+
assertUserAuthsInCatalog(graphqlUser, {repo: repositoryId2, read: false, write: false, graphql: false});
|
|
501
|
+
assertUserAuthsInCatalog(graphqlUser, {repo: repositoryId3, read: false, write: true, graphql: true});
|
|
502
|
+
});
|
|
293
503
|
});
|
|
294
504
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
505
|
+
context('Menu navigation based on permissions', () => {
|
|
506
|
+
it('Should have access to 5 pages when have graphql only rights', () => {
|
|
507
|
+
cy.wait('@getRepositories');
|
|
508
|
+
cy.wait('@getRepositories');
|
|
509
|
+
// WHEN I create a user with read + GraphQL for repository #2
|
|
510
|
+
createUser(graphqlUser, PASSWORD, ROLE_USER, {readWrite: true, graphql: true, repoName: repositoryId1});
|
|
511
|
+
//enable security
|
|
512
|
+
UserAndAccessSteps.toggleSecurity();
|
|
513
|
+
//login new user
|
|
514
|
+
LoginSteps.loginWithUser(graphqlUser, PASSWORD);
|
|
515
|
+
cy.wait('@getRepositories');
|
|
516
|
+
cy.wait('@getRepositories');
|
|
517
|
+
|
|
518
|
+
MENU_ITEMS_WITHOUT_GRAPHQL.forEach(({path, expectedUrl, checks, expectedTitle}) => {
|
|
519
|
+
navigateMenuPath(path, expectedUrl, expectedTitle);
|
|
520
|
+
|
|
521
|
+
if (checks) {
|
|
522
|
+
runChecks(checks);
|
|
523
|
+
}
|
|
524
|
+
navigateMenuPath(['Import'], '/import', 'Import');
|
|
525
|
+
});
|
|
311
526
|
});
|
|
312
|
-
});
|
|
313
527
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
528
|
+
it('Should not have access endpoints management when have read graphql only rights', () => {
|
|
529
|
+
cy.wait('@getRepositories');
|
|
530
|
+
cy.wait('@getRepositories');
|
|
531
|
+
// WHEN I create a user with read + GraphQL for repository #2
|
|
532
|
+
createUser(graphqlUser, PASSWORD, ROLE_USER, {read: true, graphql: true, repoName: repositoryId1});
|
|
533
|
+
//enable security
|
|
534
|
+
UserAndAccessSteps.toggleSecurity();
|
|
535
|
+
//login new user
|
|
536
|
+
LoginSteps.loginWithUser(graphqlUser, PASSWORD);
|
|
537
|
+
cy.wait('@getRepositories');
|
|
538
|
+
cy.wait('@getRepositories');
|
|
539
|
+
// RepositorySelectorSteps.selectRepository(repositoryId1);
|
|
540
|
+
|
|
541
|
+
GRAPHQL_READ_MENU_ITEMS.forEach(({path, expectedUrl, checks, expectedTitle}) => {
|
|
542
|
+
navigateMenuPath(path, expectedUrl, expectedTitle);
|
|
543
|
+
if (checks) {
|
|
544
|
+
runChecks(checks);
|
|
545
|
+
}
|
|
546
|
+
navigateMenuPath(['Import'], '/import', 'Import');
|
|
547
|
+
});
|
|
329
548
|
});
|
|
330
|
-
});
|
|
331
549
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
550
|
+
it('Should have all access to endpoints management when have REPO_MANAGER role', () => {
|
|
551
|
+
cy.wait('@getRepositories');
|
|
552
|
+
cy.wait('@getRepositories');
|
|
553
|
+
createUser(graphqlUser, PASSWORD, ROLE_REPO_MANAGER);
|
|
554
|
+
//enable security
|
|
555
|
+
UserAndAccessSteps.toggleSecurity();
|
|
556
|
+
HomeSteps.visitAndWaitLoader();
|
|
557
|
+
//login new user
|
|
558
|
+
LoginSteps.loginWithUser(graphqlUser, PASSWORD);
|
|
559
|
+
cy.wait('@getRepositories');
|
|
560
|
+
cy.wait('@getRepositories');
|
|
561
|
+
GRAPHQL_REPO_MANAGER_MENU_ITEMS.forEach(({path, expectedUrl, checks, expectedTitle}) => {
|
|
562
|
+
navigateMenuPath(path, expectedUrl, expectedTitle);
|
|
563
|
+
if (checks) {
|
|
564
|
+
runChecks(checks);
|
|
565
|
+
}
|
|
566
|
+
navigateMenuPath(['Import'], '/import', 'Import');
|
|
567
|
+
});
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
it('Can have Free Access and GraphQL working together', () => {
|
|
571
|
+
cy.wait('@getRepositories');
|
|
572
|
+
cy.wait('@getRepositories');
|
|
573
|
+
//enable security
|
|
574
|
+
UserAndAccessSteps.toggleSecurity();
|
|
575
|
+
//login with the admin
|
|
576
|
+
LoginSteps.loginWithUser('admin', DEFAULT_ADMIN_PASSWORD);
|
|
577
|
+
cy.wait('@getRepositories');
|
|
578
|
+
cy.wait('@getRepositories');
|
|
579
|
+
// The Free Access toggle should be OFF
|
|
580
|
+
UserAndAccessSteps.getFreeAccessSwitchInput().should('not.be.checked');
|
|
581
|
+
// When I toggle Free Access ON
|
|
582
|
+
UserAndAccessSteps.toggleFreeAccess();
|
|
583
|
+
// Then I set repo auths
|
|
584
|
+
UserAndAccessSteps.clickFreeReadAccessRepo(repositoryId1);
|
|
585
|
+
UserAndAccessSteps.clickFreeWriteAccessRepo(repositoryId2);
|
|
586
|
+
UserAndAccessSteps.clickFreeWriteAccessRepo(repositoryId3);
|
|
587
|
+
UserAndAccessSteps.clickFreeGraphqlAccessRepo(repositoryId3);
|
|
588
|
+
// Then I click OK in the modal
|
|
589
|
+
ModalDialogSteps.clickOKButton();
|
|
590
|
+
// Then the toggle button should be ON
|
|
591
|
+
UserAndAccessSteps.getFreeAccessSwitchInput().should('be.checked');
|
|
592
|
+
// And I should see a success message
|
|
593
|
+
ToasterSteps.verifySuccess('Free access has been enabled.');
|
|
594
|
+
UserAndAccessSteps.getUsersTable().should('be.visible');
|
|
595
|
+
|
|
596
|
+
// Then I logout
|
|
597
|
+
LoginSteps.logout();
|
|
598
|
+
HomeSteps.visit();
|
|
599
|
+
// I change the repository to this with GraphQL only rights
|
|
600
|
+
RepositorySelectorSteps.selectRepository(repositoryId3);
|
|
601
|
+
// Then I should have GraphQL only rights
|
|
602
|
+
FREE_ACCESS_MENU_ITEMS_WITHOUT_GRAPHQL.forEach(({path, expectedUrl, checks, expectedTitle}) => {
|
|
603
|
+
navigateMenuPath(path, expectedUrl, expectedTitle);
|
|
604
|
+
if (checks) {
|
|
605
|
+
runChecks(checks);
|
|
606
|
+
}
|
|
607
|
+
navigateMenuPath(['Import'], '/import', 'Import');
|
|
608
|
+
});
|
|
345
609
|
});
|
|
346
610
|
});
|
|
611
|
+
});
|
|
347
612
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
613
|
+
context('User with manage permission', () => {
|
|
614
|
+
let withoutPermissionRepositoryId;
|
|
615
|
+
let readRepositoryId;
|
|
616
|
+
let writeRepositoryId;
|
|
617
|
+
let graphQLOnlyRepositoryId;
|
|
618
|
+
let manageRepositoryId;
|
|
619
|
+
const manageUser = 'manageUser';
|
|
620
|
+
|
|
621
|
+
beforeEach(() => {
|
|
622
|
+
RepositoriesStubs.spyGetRepositories();
|
|
623
|
+
readRepositoryId = 'readRepositoryId-' + Date.now();
|
|
624
|
+
writeRepositoryId = 'writeRepositoryId-' + Date.now();
|
|
625
|
+
graphQLOnlyRepositoryId = 'graphQLOnlyRepositoryId-' + Date.now();
|
|
626
|
+
manageRepositoryId = 'manageRepositoryId-' + Date.now();
|
|
627
|
+
withoutPermissionRepositoryId = 'withoutPermissionRepositoryId-' + Date.now();
|
|
628
|
+
cy.createRepository({id: readRepositoryId});
|
|
629
|
+
cy.createRepository({id: writeRepositoryId});
|
|
630
|
+
cy.createRepository({id: graphQLOnlyRepositoryId});
|
|
631
|
+
cy.createRepository({id: manageRepositoryId});
|
|
632
|
+
cy.createRepository({id: withoutPermissionRepositoryId});
|
|
633
|
+
UserAndAccessSteps.visit();
|
|
634
|
+
// Users table should be visible
|
|
369
635
|
UserAndAccessSteps.getUsersTable().should('be.visible');
|
|
636
|
+
SecurityStubs.spyOnUserGet();
|
|
637
|
+
});
|
|
370
638
|
|
|
371
|
-
|
|
372
|
-
LoginSteps.logout();
|
|
373
|
-
HomeSteps.visit();
|
|
374
|
-
// I change the repository to this with GraphQL only rights
|
|
375
|
-
RepositorySelectorSteps.selectRepository(repositoryId3);
|
|
376
|
-
// Then I should have GraphQL only rights
|
|
377
|
-
FREE_ACCESS_MENU_ITEMS_WITHOUT_GRAPHQL.forEach(({path, expectedUrl, checks, expectedTitle}) => {
|
|
378
|
-
navigateMenuPath(path, expectedUrl, expectedTitle);
|
|
379
|
-
if (checks) {
|
|
380
|
-
runChecks(checks);
|
|
381
|
-
}
|
|
382
|
-
});
|
|
383
|
-
// Turn free access off
|
|
639
|
+
afterEach(() => {
|
|
384
640
|
cy.loginAsAdmin().then(() => {
|
|
641
|
+
cy.deleteRepository(readRepositoryId, true);
|
|
642
|
+
cy.deleteRepository(writeRepositoryId, true);
|
|
643
|
+
cy.deleteRepository(graphQLOnlyRepositoryId, true);
|
|
644
|
+
cy.deleteRepository(manageRepositoryId, true);
|
|
645
|
+
cy.deleteRepository(withoutPermissionRepositoryId, true);
|
|
646
|
+
cy.deleteUser(manageUser, true);
|
|
385
647
|
cy.switchOffFreeAccess(true);
|
|
648
|
+
cy.switchOffSecurity(true);
|
|
386
649
|
});
|
|
387
650
|
});
|
|
388
|
-
});
|
|
389
|
-
|
|
390
|
-
function clickGraphqlAccessForRepo(repoName) {
|
|
391
|
-
if (repoName === '*') {
|
|
392
|
-
UserAndAccessSteps.clickGraphqlAccessAny();
|
|
393
|
-
} else {
|
|
394
|
-
UserAndAccessSteps.clickGraphqlAccessRepo(repoName);
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
651
|
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
652
|
+
it('should list all repositories for which a user with manage permission has at least read permission', () => {
|
|
653
|
+
// Given there are five repositories.
|
|
654
|
+
// And there is a user with permissions for four of them:
|
|
655
|
+
// 1. Manage permission for one repository.
|
|
656
|
+
createUser(manageUser, PASSWORD, ROLE_USER, {manage: true, repoName: manageRepositoryId});
|
|
657
|
+
// 2. Read permission for one repository.
|
|
658
|
+
UserAndAccessSteps.openEditUserPage(manageUser);
|
|
659
|
+
cy.wait('@get-user');
|
|
660
|
+
setUserAuths({repo: readRepositoryId, read: true});
|
|
661
|
+
// 3. Write permission for one repository.
|
|
662
|
+
setUserAuths({repo: writeRepositoryId, write: true});
|
|
663
|
+
// 4. GraphQL-only permission for one repository.
|
|
664
|
+
setUserAuths({repo: graphQLOnlyRepositoryId, write: true, graphql: true});
|
|
665
|
+
UserAndAccessSteps.confirmUserEdit();
|
|
405
666
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
667
|
+
// When I log in as a user with repository management permission.
|
|
668
|
+
UserAndAccessSteps.toggleSecurity();
|
|
669
|
+
LoginSteps.loginWithUser(manageUser, PASSWORD);
|
|
670
|
+
// And navigate to the repository list view.
|
|
671
|
+
RepositorySteps.visit(false);
|
|
672
|
+
|
|
673
|
+
// Then I should see all repositories for which the user has at least read permission.
|
|
674
|
+
RepositorySteps.getRepositories().should('have.length', 4);
|
|
675
|
+
|
|
676
|
+
// And I should see the actions allowed for the repository the user can manage.
|
|
677
|
+
RepositorySteps.getCopyRepositoryButton(manageRepositoryId).should('be.visible');
|
|
678
|
+
RepositorySteps.getEditRepositoryButton(manageRepositoryId).should('be.visible');
|
|
679
|
+
RepositorySteps.getDownloadRepositoryConfigurationButton(manageRepositoryId).should('be.visible');
|
|
680
|
+
RepositorySteps.getRestartRepositoryButton(manageRepositoryId).should('be.visible');
|
|
681
|
+
|
|
682
|
+
// And the delete button should not be available because users with manage permission
|
|
683
|
+
// are not allowed to delete repositories.
|
|
684
|
+
RepositorySteps.getDeleteRepositoryButton(manageRepositoryId).should('not.exist');
|
|
685
|
+
|
|
686
|
+
// And the "Set as default repository" button should not be available because users
|
|
687
|
+
// with manage permission are not allowed to set the default repository.
|
|
688
|
+
RepositorySteps.getSetDefaultRepositoryButton(manageRepositoryId).should('not.exist');
|
|
689
|
+
|
|
690
|
+
// And no repository management actions should be available for the other repositories.
|
|
691
|
+
RepositorySteps.getCopyRepositoryButton(readRepositoryId).should('not.exist');
|
|
692
|
+
RepositorySteps.getEditRepositoryButton(readRepositoryId).should('not.exist');
|
|
693
|
+
RepositorySteps.getDownloadRepositoryConfigurationButton(readRepositoryId).should('not.exist');
|
|
694
|
+
RepositorySteps.getRestartRepositoryButton(readRepositoryId).should('not.exist');
|
|
695
|
+
RepositorySteps.getDeleteRepositoryButton(readRepositoryId).should('not.exist');
|
|
696
|
+
RepositorySteps.getSetDefaultRepositoryButton(readRepositoryId).should('not.exist');
|
|
697
|
+
|
|
698
|
+
RepositorySteps.getCopyRepositoryButton(writeRepositoryId).should('not.exist');
|
|
699
|
+
RepositorySteps.getEditRepositoryButton(writeRepositoryId).should('not.exist');
|
|
700
|
+
RepositorySteps.getDownloadRepositoryConfigurationButton(writeRepositoryId).should('not.exist');
|
|
701
|
+
RepositorySteps.getRestartRepositoryButton(writeRepositoryId).should('not.exist');
|
|
702
|
+
RepositorySteps.getDeleteRepositoryButton(writeRepositoryId).should('not.exist');
|
|
703
|
+
RepositorySteps.getSetDefaultRepositoryButton(writeRepositoryId).should('not.exist');
|
|
704
|
+
|
|
705
|
+
RepositorySteps.getCopyRepositoryButton(graphQLOnlyRepositoryId).should('not.exist');
|
|
706
|
+
RepositorySteps.getEditRepositoryButton(graphQLOnlyRepositoryId).should('not.exist');
|
|
707
|
+
RepositorySteps.getDownloadRepositoryConfigurationButton(graphQLOnlyRepositoryId).should('not.exist');
|
|
708
|
+
RepositorySteps.getRestartRepositoryButton(graphQLOnlyRepositoryId).should('not.exist');
|
|
709
|
+
RepositorySteps.getDeleteRepositoryButton(graphQLOnlyRepositoryId).should('not.exist');
|
|
710
|
+
RepositorySteps.getSetDefaultRepositoryButton(graphQLOnlyRepositoryId).should('not.exist');
|
|
711
|
+
|
|
712
|
+
// And the "Create", "Create from file", and "Attach remote repository" page buttons
|
|
713
|
+
// should not be available to a user with manage permission.
|
|
714
|
+
RepositorySteps.getPageButtons().should('not.exist');
|
|
715
|
+
|
|
716
|
+
// When I select a repository for which I have GraphQL-only permission.
|
|
717
|
+
RepositorySelectorSteps.selectRepository(graphQLOnlyRepositoryId);
|
|
718
|
+
|
|
719
|
+
// Then I should still see all repositories for which the user has at least read permission.
|
|
720
|
+
RepositorySteps.getRepositories().should('have.length', 4);
|
|
721
|
+
});
|
|
722
|
+
});
|
|
413
723
|
|
|
414
724
|
function createUser(username, password, role, opts = {}) {
|
|
415
725
|
UserAndAccessSteps.clickCreateNewUserButton();
|
|
726
|
+
cy.url().should('include', '/user/create');
|
|
727
|
+
UserAndAccessSteps.getUsernameField().should('be.visible').and('be.enabled').and('not.be.disabled');
|
|
416
728
|
UserAndAccessSteps.typeUsername(username);
|
|
417
729
|
UserAndAccessSteps.typePassword(password);
|
|
418
730
|
UserAndAccessSteps.typeConfirmPasswordField(password);
|
|
@@ -421,8 +733,9 @@ describe('User and Access', () => {
|
|
|
421
733
|
|
|
422
734
|
if (role === '#roleUser') {
|
|
423
735
|
setRoles(opts);
|
|
424
|
-
|
|
425
|
-
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
if (role === ROLE_CUSTOM_ADMIN && opts.noPassword) {
|
|
426
739
|
UserAndAccessSteps.getNoPasswordCheckbox().check()
|
|
427
740
|
.then(() => {
|
|
428
741
|
UserAndAccessSteps.getNoPasswordCheckbox()
|
|
@@ -442,16 +755,8 @@ describe('User and Access', () => {
|
|
|
442
755
|
}
|
|
443
756
|
|
|
444
757
|
function setRoles(opts = {}) {
|
|
445
|
-
const {read = false, readWrite = false, graphql = false, repoName = '*'} = opts;
|
|
446
|
-
|
|
447
|
-
clickReadAccessForRepo(repoName);
|
|
448
|
-
}
|
|
449
|
-
if (readWrite) {
|
|
450
|
-
clickWriteAccessForRepo(repoName);
|
|
451
|
-
}
|
|
452
|
-
if (graphql) {
|
|
453
|
-
clickGraphqlAccessForRepo(repoName);
|
|
454
|
-
}
|
|
758
|
+
const {read = false, readWrite = false, graphql = false, manage = false, repoName = '*'} = opts;
|
|
759
|
+
setUserAuths({repo: repoName, read, write: readWrite, graphql, manage});
|
|
455
760
|
}
|
|
456
761
|
|
|
457
762
|
function testForUser(name, isAdmin) {
|
|
@@ -470,10 +775,10 @@ describe('User and Access', () => {
|
|
|
470
775
|
}
|
|
471
776
|
}
|
|
472
777
|
|
|
473
|
-
function
|
|
778
|
+
function assertUserAuthsInCatalog(username, {repo, read = false, write = false, manage = false, graphql = false} = {}) {
|
|
474
779
|
UserAndAccessSteps.findUserRowAlias(username, 'userRow');
|
|
475
780
|
|
|
476
|
-
if (!read && !write) {
|
|
781
|
+
if (!read && !write && !manage) {
|
|
477
782
|
return UserAndAccessSteps.getRepoLine('@userRow', repo).should('not.exist');
|
|
478
783
|
}
|
|
479
784
|
|
|
@@ -492,6 +797,12 @@ describe('User and Access', () => {
|
|
|
492
797
|
UserAndAccessSteps.findWriteIconAlias('@repoLine').should('not.exist');
|
|
493
798
|
}
|
|
494
799
|
|
|
800
|
+
if (manage) {
|
|
801
|
+
UserAndAccessSteps.findManageIconAlias('@repoLine').should('be.visible');
|
|
802
|
+
} else {
|
|
803
|
+
UserAndAccessSteps.findManageIconAlias('@repoLine').should('not.exist');
|
|
804
|
+
}
|
|
805
|
+
|
|
495
806
|
if (graphql) {
|
|
496
807
|
UserAndAccessSteps.findGraphqlIconAlias('@repoLine').should('exist');
|
|
497
808
|
} else {
|
|
@@ -499,28 +810,56 @@ describe('User and Access', () => {
|
|
|
499
810
|
}
|
|
500
811
|
}
|
|
501
812
|
|
|
502
|
-
function
|
|
813
|
+
function setUserAuths({repo, read = false, write = false, graphql = false, manage = false} = {}) {
|
|
503
814
|
if (read === true) {
|
|
504
815
|
UserAndAccessSteps.toggleReadAccessForRepo(repo);
|
|
816
|
+
UserAndAccessSteps.validateReadAccessForRepo(repo, {checked: read});
|
|
505
817
|
}
|
|
506
818
|
|
|
507
819
|
if (write === true) {
|
|
508
820
|
UserAndAccessSteps.toggleWriteAccessForRepo(repo);
|
|
821
|
+
UserAndAccessSteps.validateWriteAccessForRepo(repo, {checked: write});
|
|
509
822
|
}
|
|
510
823
|
|
|
511
824
|
if (graphql === true) {
|
|
512
825
|
UserAndAccessSteps.toggleGraphqlAccessForRepo(repo);
|
|
826
|
+
UserAndAccessSteps.validateGraphqlAccessForRepo(repo, {checked: graphql});
|
|
827
|
+
}
|
|
828
|
+
|
|
829
|
+
if (manage === true) {
|
|
830
|
+
UserAndAccessSteps.toggleManageRepoForRepo(repo);
|
|
831
|
+
UserAndAccessSteps.validateManageAccessForRepo(repo, {checked: manage});
|
|
513
832
|
}
|
|
514
833
|
}
|
|
515
834
|
|
|
835
|
+
function verifyCheckedUserAuth(repo, {read = false, write = false, graphql = false, manage = false} = {}) {
|
|
836
|
+
UserAndAccessSteps.validateReadAccessForRepo(repo, {checked: read});
|
|
837
|
+
UserAndAccessSteps.validateWriteAccessForRepo(repo, {checked: write});
|
|
838
|
+
UserAndAccessSteps.validateGraphqlAccessForRepo(repo, {checked: graphql});
|
|
839
|
+
UserAndAccessSteps.validateManageAccessForRepo(repo, {checked: manage});
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
function verifyDisabledUserAuth(repo, {read = false, write = false, graphql = false, manage = false} = {}) {
|
|
843
|
+
UserAndAccessSteps.validateReadAccessForRepo(repo, {disabled: read});
|
|
844
|
+
UserAndAccessSteps.validateWriteAccessForRepo(repo, {disabled: write});
|
|
845
|
+
UserAndAccessSteps.validateGraphqlAccessForRepo(repo, {disabled: graphql});
|
|
846
|
+
UserAndAccessSteps.validateManageAccessForRepo(repo, {disabled: manage});
|
|
847
|
+
}
|
|
848
|
+
|
|
516
849
|
function navigateMenuPath(pathArray, expectedUrl, expectedTitle) {
|
|
517
850
|
pathArray.forEach((label, index) => {
|
|
518
851
|
if (index === 0) {
|
|
519
852
|
MainMenuSteps.clickOnMenu(label);
|
|
853
|
+
if (pathArray.length > 1) {
|
|
854
|
+
MainMenuSteps.getSubmenuFor(label).scrollIntoView().should('be.visible');
|
|
855
|
+
}
|
|
520
856
|
} else {
|
|
521
857
|
MainMenuSteps.clickOnSubMenu(label);
|
|
858
|
+
}
|
|
859
|
+
if (index === pathArray.length - 1) {
|
|
860
|
+
// wait for the page label on the last navigation step to be visible before moving on
|
|
522
861
|
const title = expectedTitle ? expectedTitle : label;
|
|
523
|
-
cy.get('h1').should('contain', title);
|
|
862
|
+
cy.get('h1').should('be.visible').should('contain', title);
|
|
524
863
|
}
|
|
525
864
|
});
|
|
526
865
|
|
|
@@ -558,9 +897,6 @@ describe('User and Access', () => {
|
|
|
558
897
|
}
|
|
559
898
|
|
|
560
899
|
const noAuthChecks = {
|
|
561
|
-
'div[role="main]': [
|
|
562
|
-
'not.exist',
|
|
563
|
-
],
|
|
564
900
|
'.no-authority-panel .alert-warning': [
|
|
565
901
|
'be.visible',
|
|
566
902
|
['contains.text', 'Some functionalities are not available because'],
|
|
@@ -569,10 +905,6 @@ describe('User and Access', () => {
|
|
|
569
905
|
};
|
|
570
906
|
|
|
571
907
|
const hasAuthChecks = {
|
|
572
|
-
'div[role="main"]': [
|
|
573
|
-
'exist',
|
|
574
|
-
'be.visible',
|
|
575
|
-
],
|
|
576
908
|
'.no-authority-panel .alert-warning': [
|
|
577
909
|
'not.exist',
|
|
578
910
|
],
|
|
@@ -813,13 +1145,5 @@ describe('User and Access', () => {
|
|
|
813
1145
|
expectedUrl: '/sparql-templates',
|
|
814
1146
|
checks: noAuthChecks,
|
|
815
1147
|
},
|
|
816
|
-
|
|
817
|
-
// 7) Help
|
|
818
|
-
{
|
|
819
|
-
path: ['Help', 'REST API'],
|
|
820
|
-
expectedUrl: '/webapi',
|
|
821
|
-
expectedTitle: 'REST API documentation',
|
|
822
|
-
checks: hasAuthChecks,
|
|
823
|
-
},
|
|
824
1148
|
];
|
|
825
1149
|
});
|