Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
util: fix potential cross-tenants queries in InternalCallContextFactory
Restrict usage of NonEntityDao. Because it doesn't validate the context, this DAO should only be used internally. InternalCallContextFactory now features safe wrappers to do the tenant check in code. This also greatly simplifies the code as the CacheControllerDispatcher doesn't need to be injected all over the place. Signed-off-by: Pierre-Alexandre Meyer <pierre@mouraf.org>
- Loading branch information
Showing
39 changed files
with
514 additions
and
661 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
/* | ||
* Copyright 2010-2013 Ning, Inc. | ||
* Copyright 2014 Groupon, Inc | ||
* Copyright 2014 The Billing Project, LLC | ||
* Copyright 2014-2015 Groupon, Inc | ||
* Copyright 2014-2015 The Billing Project, LLC | ||
* | ||
* The Billing Project licenses this file to you under the Apache License, version 2.0 | ||
* (the "License"); you may not use this file except in compliance with the | ||
|
@@ -21,7 +21,6 @@ | |
import java.util.UUID; | ||
|
||
import org.joda.time.DateTime; | ||
import org.killbill.billing.ObjectType; | ||
import org.killbill.billing.callcontext.InternalCallContext; | ||
import org.killbill.billing.entitlement.api.DefaultBlockingTransitionInternalEvent; | ||
import org.killbill.billing.entitlement.api.DefaultEntitlement; | ||
|
@@ -34,12 +33,10 @@ | |
import org.killbill.billing.entitlement.engine.core.EntitlementNotificationKeyAction; | ||
import org.killbill.billing.platform.api.LifecycleHandlerType; | ||
import org.killbill.billing.platform.api.LifecycleHandlerType.LifecycleLevel; | ||
import org.killbill.billing.util.cache.Cachable.CacheType; | ||
import org.killbill.billing.util.cache.CacheControllerDispatcher; | ||
import org.killbill.billing.util.callcontext.CallContext; | ||
import org.killbill.billing.util.callcontext.CallOrigin; | ||
import org.killbill.billing.util.callcontext.InternalCallContextFactory; | ||
import org.killbill.billing.util.callcontext.UserType; | ||
import org.killbill.billing.util.dao.NonEntityDao; | ||
import org.killbill.bus.api.BusEvent; | ||
import org.killbill.bus.api.PersistentBus; | ||
import org.killbill.bus.api.PersistentBus.EventBusException; | ||
|
@@ -62,29 +59,23 @@ public class DefaultEntitlementService implements EntitlementService { | |
|
||
private final EntitlementApi entitlementApi; | ||
private final BlockingStateDao blockingStateDao; | ||
private final NonEntityDao nonEntityDao; | ||
private final PersistentBus eventBus; | ||
private final NotificationQueueService notificationQueueService; | ||
private final InternalCallContextFactory internalCallContextFactory; | ||
private final CacheControllerDispatcher controllerDispatcher; | ||
|
||
private NotificationQueue entitlementEventQueue; | ||
|
||
@Inject | ||
public DefaultEntitlementService(final EntitlementApi entitlementApi, | ||
final BlockingStateDao blockingStateDao, | ||
final NonEntityDao nonEntityDao, | ||
final PersistentBus eventBus, | ||
final NotificationQueueService notificationQueueService, | ||
final InternalCallContextFactory internalCallContextFactory, | ||
final CacheControllerDispatcher controllerDispatcher) { | ||
final InternalCallContextFactory internalCallContextFactory) { | ||
this.entitlementApi = entitlementApi; | ||
this.blockingStateDao = blockingStateDao; | ||
this.nonEntityDao = nonEntityDao; | ||
this.eventBus = eventBus; | ||
this.notificationQueueService = notificationQueueService; | ||
this.internalCallContextFactory = internalCallContextFactory; | ||
this.controllerDispatcher = controllerDispatcher; | ||
} | ||
|
||
@Override | ||
|
@@ -101,8 +92,8 @@ public void handleReadyNotification(final NotificationEvent inputKey, final Date | |
final InternalCallContext internalCallContext = internalCallContextFactory.createInternalCallContext(tenantRecordId, accountRecordId, "EntitlementQueue", CallOrigin.INTERNAL, UserType.SYSTEM, fromNotificationQueueUserToken); | ||
|
||
if (inputKey instanceof EntitlementNotificationKey) { | ||
final UUID tenantId = nonEntityDao.retrieveIdFromObject(tenantRecordId, ObjectType.TENANT, controllerDispatcher.getCacheController(CacheType.OBJECT_ID)); | ||
processEntitlementNotification((EntitlementNotificationKey) inputKey, tenantId, internalCallContext); | ||
final CallContext callContext = internalCallContextFactory.createCallContext(internalCallContext); | ||
processEntitlementNotification((EntitlementNotificationKey) inputKey, internalCallContext, callContext); | ||
} else if (inputKey instanceof BlockingTransitionNotificationKey) { | ||
processBlockingNotification((BlockingTransitionNotificationKey) inputKey, internalCallContext); | ||
} else if (inputKey != null) { | ||
|
@@ -121,10 +112,10 @@ public void handleReadyNotification(final NotificationEvent inputKey, final Date | |
} | ||
} | ||
|
||
private void processEntitlementNotification(final EntitlementNotificationKey key, final UUID tenantId, final InternalCallContext internalCallContext) { | ||
private void processEntitlementNotification(final EntitlementNotificationKey key, final InternalCallContext internalCallContext, final CallContext callContext) { | ||
final Entitlement entitlement; | ||
try { | ||
entitlement = entitlementApi.getEntitlementForId(key.getEntitlementId(), internalCallContext.toTenantContext(tenantId)); | ||
entitlement = entitlementApi.getEntitlementForId(key.getEntitlementId(), callContext); | ||
} catch (final EntitlementApiException e) { | ||
log.error("Error retrieving entitlement for id " + key.getEntitlementId(), e); | ||
return; | ||
|
@@ -139,11 +130,13 @@ private void processEntitlementNotification(final EntitlementNotificationKey key | |
try { | ||
if (EntitlementNotificationKeyAction.CHANGE.equals(entitlementNotificationKeyAction) || | ||
EntitlementNotificationKeyAction.CANCEL.equals(entitlementNotificationKeyAction)) { | ||
((DefaultEntitlement) entitlement).blockAddOnsIfRequired(key.getEffectiveDate(), internalCallContext.toTenantContext(tenantId), internalCallContext); | ||
} else if (EntitlementNotificationKeyAction.PAUSE.equals(entitlementNotificationKeyAction)) { | ||
entitlementApi.pause(key.getBundleId(), key.getEffectiveDate().toLocalDate(), internalCallContext.toCallContext(tenantId)); | ||
} else if (EntitlementNotificationKeyAction.RESUME.equals(entitlementNotificationKeyAction)) { | ||
entitlementApi.resume(key.getBundleId(), key.getEffectiveDate().toLocalDate(), internalCallContext.toCallContext(tenantId)); | ||
((DefaultEntitlement) entitlement).blockAddOnsIfRequired(key.getEffectiveDate(), callContext, internalCallContext); | ||
} else { | ||
if (EntitlementNotificationKeyAction.PAUSE.equals(entitlementNotificationKeyAction)) { | ||
entitlementApi.pause(key.getBundleId(), key.getEffectiveDate().toLocalDate(), callContext); | ||
} else if (EntitlementNotificationKeyAction.RESUME.equals(entitlementNotificationKeyAction)) { | ||
entitlementApi.resume(key.getBundleId(), key.getEffectiveDate().toLocalDate(), callContext); | ||
} | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
pierre
Author
Member
|
||
} | ||
} catch (final EntitlementApiException e) { | ||
log.error("Error processing event for entitlement {}" + entitlement.getId(), e); | ||
|
@@ -164,7 +157,7 @@ private void processBlockingNotification(final BlockingTransitionNotificationKey | |
|
||
try { | ||
eventBus.post(event); | ||
} catch (EventBusException e) { | ||
} catch (final EventBusException e) { | ||
log.warn("Failed to post event {}", e); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Slightly confused with the reordering if the if-then-else but this is probably good.