Fix #3067: Service Creation should only be done by Bots or admins and Update should only done by owners

This commit is contained in:
Sriharsha Chintalapani 2022-03-02 21:20:20 -08:00 committed by GitHub
parent bec8c74ecb
commit e4e11a7a07
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 38 additions and 4 deletions

View File

@ -313,7 +313,7 @@ public class DashboardServiceResource {
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateDashboardService update)
throws IOException, ParseException {
DashboardService service = getService(update, securityContext);
SecurityUtil.checkAdminRoleOrPermissions(authorizer, securityContext, dao.getOriginalOwner(service));
SecurityUtil.checkAdminOrBotOrOwner(authorizer, securityContext, dao.getOriginalOwner(service));
PutResponse<DashboardService> response = dao.createOrUpdate(uriInfo, service, true);
addHref(uriInfo, response.getEntity());
return response.toResponse();

View File

@ -334,7 +334,7 @@ public class DatabaseServiceResource {
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreateDatabaseService update)
throws IOException, ParseException {
DatabaseService service = getService(update, securityContext);
SecurityUtil.checkAdminRoleOrPermissions(authorizer, securityContext, dao.getOriginalOwner(service));
SecurityUtil.checkAdminOrBotOrOwner(authorizer, securityContext, dao.getOriginalOwner(service));
PutResponse<DatabaseService> response = dao.createOrUpdate(uriInfo, service, true);
addHref(uriInfo, decryptOrNullify(securityContext, response.getEntity()));
return response.toResponse();

View File

@ -320,7 +320,7 @@ public class MessagingServiceResource {
@Valid CreateMessagingService update)
throws IOException, ParseException {
MessagingService service = getService(update, securityContext);
SecurityUtil.checkAdminRoleOrPermissions(authorizer, securityContext, dao.getOriginalOwner(service));
SecurityUtil.checkAdminOrBotOrOwner(authorizer, securityContext, dao.getOriginalOwner(service));
PutResponse<MessagingService> response = dao.createOrUpdate(uriInfo, service, true);
addHref(uriInfo, response.getEntity());
return response.toResponse();

View File

@ -316,7 +316,7 @@ public class PipelineServiceResource {
@Context UriInfo uriInfo, @Context SecurityContext securityContext, @Valid CreatePipelineService update)
throws IOException, ParseException {
PipelineService service = getService(update, securityContext);
SecurityUtil.checkAdminRoleOrPermissions(authorizer, securityContext, dao.getOriginalOwner(service));
SecurityUtil.checkAdminOrBotOrOwner(authorizer, securityContext, dao.getOriginalOwner(service));
PutResponse<PipelineService> response = dao.createOrUpdate(uriInfo, service, true);
addHref(uriInfo, response.getEntity());
return response.toResponse();

View File

@ -42,4 +42,6 @@ public interface Authorizer {
boolean isAdmin(AuthenticationContext ctx);
boolean isBot(AuthenticationContext ctx);
boolean isOwner(AuthenticationContext ctx, EntityReference entityReference);
}

View File

@ -240,6 +240,22 @@ public class DefaultAuthorizer implements Authorizer {
}
}
@Override
public boolean isOwner(AuthenticationContext ctx, EntityReference owner) {
validateAuthenticationContext(ctx);
String userName = SecurityUtil.getUserName(ctx);
EntityUtil.Fields fields = new EntityUtil.Fields(UserResource.ALLOWED_FIELDS, FIELDS_PARAM);
try {
User user = userRepository.getByName(null, userName, fields);
if (owner == null) {
return false;
}
return isOwnedByUser(user, owner);
} catch (IOException | EntityNotFoundException | ParseException ex) {
return false;
}
}
private void validateAuthenticationContext(AuthenticationContext ctx) {
if (ctx == null || ctx.getPrincipal() == null) {
throw new AuthenticationException("No principal in AuthenticationContext");

View File

@ -71,6 +71,11 @@ public class NoopAuthorizer implements Authorizer {
return true;
}
@Override
public boolean isOwner(AuthenticationContext ctx, EntityReference entityReference) {
return true;
}
private void addAnonymousUser() {
EntityUtil.Fields fields = new EntityUtil.Fields(UserResource.ALLOWED_FIELDS, FIELDS_PARAM);
String username = "anonymous";

View File

@ -57,6 +57,17 @@ public final class SecurityUtil {
}
}
public static void checkAdminOrBotOrOwner(
Authorizer authorizer, SecurityContext securityContext, EntityReference ownerReference) {
Principal principal = securityContext.getUserPrincipal();
AuthenticationContext authenticationCtx = SecurityUtil.getAuthenticationContext(principal);
if (!authorizer.isAdmin(authenticationCtx)
&& !authorizer.isBot(authenticationCtx)
&& !authorizer.isOwner(authenticationCtx, ownerReference)) {
throw new AuthorizationException(noPermission(principal));
}
}
public static void checkAdminRoleOrPermissions(
Authorizer authorizer, SecurityContext securityContext, EntityReference entityReference) {
Principal principal = securityContext.getUserPrincipal();