Skip to content

Commit d7c7d27

Browse files
authored
Merge commit from fork
* Fix permission check * Adapt exception message when forbidden * Added changelog
1 parent 173c31b commit d7c7d27

File tree

3 files changed

+17
-24
lines changed

3 files changed

+17
-24
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
type = "security"
2+
message = "Fix permission check for creating a new API-token. See [GHSA-3m86-c9x3-vwm9](https://github.com/Graylog2/graylog2-server/security/advisories/GHSA-3m86-c9x3-vwm9) for details."

graylog2-server/src/main/java/org/graylog2/rest/resources/users/UsersResource.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -727,13 +727,9 @@ public Token generateNewToken(
727727
@ApiParam(name = "name", value = "Descriptive name for this token (e.g. 'cronjob') ", required = true) @PathParam("name") String name,
728728
@ApiParam(name = "JSON Body", value = "Can optionally contain the token's TTL.", defaultValue = "{\"token_ttl\":null}") GenerateTokenTTL body) {
729729
final User futureOwner = loadUserById(userId);
730-
final User currentUser = getCurrentUser();
731730

732-
if (currentUser == null) {
733-
throw new ForbiddenException("Not allowed to create tokens for unknown user.");
734-
}
735-
if (!isPermitted(USERS_TOKENCREATE, currentUser.getName())) {
736-
throw new ForbiddenException(currentUser.getName() + " is not allowed to create token.");
731+
if (!isPermitted(USERS_TOKENCREATE, futureOwner.getName())) {
732+
throw new ForbiddenException("You are not allowed to create a token for user " + futureOwner.getName() + ".");
737733
}
738734

739735
if (body == null) {

graylog2-server/src/test/java/org/graylog2/rest/resources/users/UsersResourceTest.java

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ public class UsersResourceTest {
9393
private static final String TOKEN_NAME = "tokenName";
9494

9595
private static final String ADMIN_OBJECT_ID = new ObjectId().toHexString();
96-
private static final PeriodDuration PD_30_DAYS = PeriodDuration.parse("P30D");
9796

9897
@Rule
9998
public MockitoRule rule = MockitoJUnit.rule();
@@ -212,7 +211,6 @@ public void createTokenFailsIfCreateNotAllowed() {
212211
final UsersResource.GenerateTokenTTL ttl = new UsersResource.GenerateTokenTTL(Optional.of(PeriodDuration.of(Duration.ofDays(30))));
213212
assertThrows(ForbiddenException.class, () -> usersResource.generateNewToken(USERNAME, TOKEN_NAME, ttl));
214213
} finally {
215-
verify(subject).getPrincipal();
216214
verify(subject).isPermitted(USERS_TOKENCREATE + ":" + USERNAME);
217215
verifyNoMoreInteractions(clusterConfigService, accessTokenService);
218216
}
@@ -227,7 +225,6 @@ public void createTokenSucceedsEvenWithNULLBody() {
227225
final Token actual = usersResource.generateNewToken(USERNAME, TOKEN_NAME, null);
228226
assertEquals(expected, actual);
229227
} finally {
230-
verify(subject).getPrincipal();
231228
verify(subject).isPermitted(USERS_TOKENCREATE + ":" + USERNAME);
232229
verify(clusterConfigService).getOrDefault(UserConfiguration.class, UserConfiguration.DEFAULT_VALUES);
233230
verify(accessTokenService).create(USERNAME, TOKEN_NAME, PeriodDuration.of(Duration.ofDays(30)));
@@ -246,8 +243,7 @@ public void adminCanCreateTokensForOtherUsers() {
246243
final Token actual = usersResource.generateNewToken(USERNAME, TOKEN_NAME, null);
247244
assertEquals(expected, actual);
248245
} finally {
249-
verify(subject).getPrincipal();
250-
verify(subject).isPermitted(USERS_TOKENCREATE + ":" + adminUserName);
246+
verify(subject).isPermitted(USERS_TOKENCREATE + ":" + USERNAME);
251247
verify(clusterConfigService).getOrDefault(UserConfiguration.class, UserConfiguration.DEFAULT_VALUES);
252248
verify(accessTokenService).create(USERNAME, TOKEN_NAME, PeriodDuration.of(Duration.ofDays(30)));
253249
verifyNoMoreInteractions(clusterConfigService, accessTokenService);
@@ -264,8 +260,7 @@ public void regularUserCannotCreateTokensForOtherUsers() {
264260
try {
265261
assertThrows(ForbiddenException.class, () -> usersResource.generateNewToken(USERNAME, TOKEN_NAME, null));
266262
} finally {
267-
verify(subject).getPrincipal();
268-
verify(subject).isPermitted(USERS_TOKENCREATE + ":" + otherUserName);
263+
verify(subject).isPermitted(USERS_TOKENCREATE + ":" + USERNAME);
269264
verifyNoMoreInteractions(clusterConfigService, accessTokenService);
270265
}
271266
}
@@ -290,14 +285,14 @@ private Token createTokenAndPrepareMocks(Map<String, Object> owningUser, Map<Str
290285
user.setRoleIds(Set.of(ADMIN_OBJECT_ID));
291286
}
292287

293-
when(subject.getPrincipal()).thenReturn(callingUserName);
294-
when(userService.loadById(callingUserName)).thenReturn(user);
295-
when(roleService.getAdminRoleObjectId()).thenReturn(ADMIN_OBJECT_ID);
288+
final boolean allowedToCreateToken = callingUserName.equals(owningUserName) || isAdmin;
296289
when(userManagementService.loadById(USERNAME)).thenReturn(userImplFactory.create(owningUser));
297-
when(subject.isPermitted(USERS_TOKENCREATE + ":" + callingUserName)).thenReturn(callingUserName.equals(owningUserName) || isAdmin);
298-
when(clusterConfigService.getOrDefault(UserConfiguration.class, UserConfiguration.DEFAULT_VALUES))
299-
.thenReturn(UserConfiguration.create(false, Duration.of(8, ChronoUnit.HOURS), false, false, PeriodDuration.of(Duration.ofDays(30))));
300-
when(accessTokenService.create(USERNAME, UsersResourceTest.TOKEN_NAME, PeriodDuration.of(Duration.ofDays(30)))).thenReturn(accessToken);
290+
when(subject.isPermitted(USERS_TOKENCREATE + ":" + owningUserName)).thenReturn(allowedToCreateToken);
291+
if (allowedToCreateToken) {
292+
when(clusterConfigService.getOrDefault(UserConfiguration.class, UserConfiguration.DEFAULT_VALUES))
293+
.thenReturn(UserConfiguration.create(false, Duration.of(8, ChronoUnit.HOURS), false, false, PeriodDuration.of(Duration.ofDays(30))));
294+
when(accessTokenService.create(USERNAME, UsersResourceTest.TOKEN_NAME, PeriodDuration.of(Duration.ofDays(30)))).thenReturn(accessToken);
295+
}
301296

302297
return Token.create(tokenId.toHexString(), TOKEN_NAME, token, lastAccess);
303298

@@ -308,7 +303,7 @@ private Token createTokenAndPrepareMocks(Map<String, Object> userProps, boolean
308303
final DateTime lastAccess = Tools.nowUTC();
309304
final Map<String, Object> tokenProps = Map.of(AccessTokenImpl.NAME, TOKEN_NAME, AccessTokenImpl.TOKEN, token, AccessTokenImpl.LAST_ACCESS, lastAccess);
310305
final ObjectId tokenId = new ObjectId();
311-
final AccessToken accessToken = new AccessTokenImpl(tokenId, tokenProps);
306+
final AccessToken accessToken = allowCreateToken ? new AccessTokenImpl(tokenId, tokenProps) : null;
312307

313308
prepareMocks(userProps, accessToken, allowCreateToken);
314309

@@ -317,11 +312,11 @@ private Token createTokenAndPrepareMocks(Map<String, Object> userProps, boolean
317312

318313
private void prepareMocks(Map<String, Object> userProps, AccessToken accessToken, boolean allow) {
319314
final User user = userImplFactory.create(userProps);
320-
when(subject.getPrincipal()).thenReturn(USERNAME);
321-
when(userService.loadById(USERNAME)).thenReturn(user);
322315
when(userManagementService.loadById(USERNAME)).thenReturn(user);
323316
when(subject.isPermitted(USERS_TOKENCREATE + ":" + USERNAME)).thenReturn(allow);
324-
when(clusterConfigService.getOrDefault(UserConfiguration.class, UserConfiguration.DEFAULT_VALUES)).thenReturn(UserConfiguration.DEFAULT_VALUES);
317+
if (allow) {
318+
when(clusterConfigService.getOrDefault(UserConfiguration.class, UserConfiguration.DEFAULT_VALUES)).thenReturn(UserConfiguration.DEFAULT_VALUES);
319+
}
325320
if (accessToken != null) {
326321
when(accessTokenService.create(USERNAME, UsersResourceTest.TOKEN_NAME, PeriodDuration.of(Duration.ofDays(30)))).thenReturn(accessToken);
327322
}

0 commit comments

Comments
 (0)