-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Execute Only for Shared Actions #4935
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
1039d88
c720879
f7e4bf0
5c193e6
989ad61
38880d9
e11d229
3b0338a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -43,6 +43,8 @@ import org.apache.openwhisk.http.Messages._ | |
| import org.apache.openwhisk.core.entitlement.Resource | ||
| import org.apache.openwhisk.core.entitlement.Collection | ||
| import org.apache.openwhisk.core.loadBalancer.LoadBalancerException | ||
| import pureconfig._ | ||
| import org.apache.openwhisk.core.ConfigKeys | ||
|
|
||
| /** | ||
| * A singleton object which defines the properties that must be present in a configuration | ||
|
|
@@ -102,6 +104,12 @@ trait WhiskActionsApi extends WhiskCollectionAPI with PostActionActivation with | |
| /** Database service to get activations. */ | ||
| protected val activationStore: ActivationStore | ||
|
|
||
| /** Config flag for Execute Only for Actions in Shared Packages */ | ||
| protected def executeOnly = | ||
| Try({ | ||
| loadConfigOrThrow[Boolean](ConfigKeys.sharedPackageExecuteOnly) | ||
| }).getOrElse(false) | ||
|
bkemburu marked this conversation as resolved.
Outdated
|
||
|
|
||
| /** Entity normalizer to JSON object. */ | ||
| import RestApiCommons.emptyEntityToJsObject | ||
|
|
||
|
|
@@ -341,22 +349,69 @@ trait WhiskActionsApi extends WhiskCollectionAPI with PostActionActivation with | |
| override def fetch(user: Identity, entityName: FullyQualifiedEntityName, env: Option[Parameters])( | ||
| implicit transid: TransactionId) = { | ||
| parameter('code ? true) { code => | ||
| code match { | ||
| case true => | ||
| getEntity(WhiskAction.resolveActionAndMergeParameters(entityStore, entityName), Some { action: WhiskAction => | ||
| val mergedAction = env map { | ||
| action inherit _ | ||
| } getOrElse action | ||
| complete(OK, mergedAction) | ||
| }) | ||
| case false => | ||
| getEntity(WhiskActionMetaData.resolveActionAndMergeParameters(entityStore, entityName), Some { | ||
| action: WhiskActionMetaData => | ||
| val mergedAction = env map { | ||
| action inherit _ | ||
| } getOrElse action | ||
| complete(OK, mergedAction) | ||
| }) | ||
| //check if execute only is enabled, and if there is a discrepancy between the current user's namespace | ||
| //and that of the entity we are trying to fetch | ||
|
|
||
| if (executeOnly && user.namespace.name != entityName.namespace) { | ||
| terminate(Forbidden, forbiddenGetAction(entityName.path.asString)) | ||
| } else { | ||
| code match { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: I'd suggest the simpler/cleaner if (code) { } else { }. |
||
| case true => | ||
| //Resolve Binding(Package) of the action | ||
| if (entityName.path.defaultPackage) { | ||
| getEntity(WhiskAction.resolveActionAndMergeParameters(entityStore, entityName), Some { | ||
|
bkemburu marked this conversation as resolved.
|
||
| action: WhiskAction => | ||
| val mergedAction = env map { | ||
| action inherit _ | ||
| } getOrElse action | ||
| complete(OK, mergedAction) | ||
| }) | ||
| } else { | ||
| getEntity( | ||
| WhiskPackage.resolveBinding(entityStore, entityName.path.toDocId, mergeParameters = true), | ||
| Some { pkg: WhiskPackage => | ||
| val originalPackageLocation = pkg.fullyQualifiedName(withVersion = false).namespace | ||
| if (executeOnly && originalPackageLocation != entityName.namespace) { | ||
|
bkemburu marked this conversation as resolved.
Outdated
|
||
| terminate(Forbidden, forbiddenGetActionBinding(entityName.toDocId.asString)) | ||
| } else { | ||
| getEntity(WhiskAction.resolveActionAndMergeParameters(entityStore, entityName), Some { | ||
| action: WhiskAction => | ||
| val mergedAction = env map { | ||
| action inherit _ | ||
| } getOrElse action | ||
| complete(OK, mergedAction) | ||
| }) | ||
| } | ||
| }) | ||
| } | ||
| case false => | ||
| if (entityName.path.defaultPackage) { | ||
| getEntity(WhiskActionMetaData.resolveActionAndMergeParameters(entityStore, entityName), Some { | ||
| action: WhiskActionMetaData => | ||
| val mergedAction = env map { | ||
| action inherit _ | ||
| } getOrElse action | ||
| complete(OK, mergedAction) | ||
| }) | ||
| } else { | ||
| getEntity( | ||
| WhiskPackage.resolveBinding(entityStore, entityName.path.toDocId, mergeParameters = true), | ||
| Some { pkg: WhiskPackage => | ||
| val originalPackageLocation = pkg.fullyQualifiedName(withVersion = false).namespace | ||
| if (executeOnly && originalPackageLocation != entityName.namespace) { | ||
| terminate(Forbidden, forbiddenGetActionBinding(entityName.toDocId.asString)) | ||
| } else { | ||
| getEntity(WhiskActionMetaData.resolveActionAndMergeParameters(entityStore, entityName), Some { | ||
| action: WhiskActionMetaData => | ||
| val mergedAction = env map { | ||
| action inherit _ | ||
| } getOrElse action | ||
| complete(OK, mergedAction) | ||
| }) | ||
| } | ||
| }) | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,13 +18,11 @@ | |
| package org.apache.openwhisk.core.controller | ||
|
|
||
| import scala.concurrent.Future | ||
| import scala.util.{Failure, Success} | ||
|
|
||
| import scala.util.{Failure, Success, Try} | ||
| import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._ | ||
| import akka.http.scaladsl.model.StatusCodes._ | ||
| import akka.http.scaladsl.server.{RequestContext, RouteResult} | ||
| import akka.http.scaladsl.unmarshalling.Unmarshaller | ||
|
|
||
| import org.apache.openwhisk.common.TransactionId | ||
| import org.apache.openwhisk.core.controller.RestApiCommons.{ListLimit, ListSkip} | ||
| import org.apache.openwhisk.core.database.{CacheChangeNotification, DocumentTypeMismatchException, NoDocumentException} | ||
|
|
@@ -33,6 +31,9 @@ import org.apache.openwhisk.core.entity._ | |
| import org.apache.openwhisk.core.entity.types.EntityStore | ||
| import org.apache.openwhisk.http.ErrorResponse.terminate | ||
| import org.apache.openwhisk.http.Messages | ||
| import org.apache.openwhisk.http.Messages._ | ||
| import pureconfig._ | ||
| import org.apache.openwhisk.core.ConfigKeys | ||
|
|
||
| trait WhiskPackagesApi extends WhiskCollectionAPI with ReferencedEntities { | ||
| services: WhiskServices => | ||
|
|
@@ -42,6 +43,12 @@ trait WhiskPackagesApi extends WhiskCollectionAPI with ReferencedEntities { | |
| /** Database service to CRUD packages. */ | ||
| protected val entityStore: EntityStore | ||
|
|
||
| /** Config flag for Execute Only for Shared Packages */ | ||
| protected def executeOnly = | ||
| Try({ | ||
| loadConfigOrThrow[Boolean](ConfigKeys.sharedPackageExecuteOnly) | ||
| }).getOrElse(false) | ||
|
bkemburu marked this conversation as resolved.
Outdated
|
||
|
|
||
| /** Notification service for cache invalidation. */ | ||
| protected implicit val cacheChangeNotification: Some[CacheChangeNotification] | ||
|
|
||
|
|
@@ -155,9 +162,18 @@ trait WhiskPackagesApi extends WhiskCollectionAPI with ReferencedEntities { | |
| * - 404 Not Found | ||
| * - 500 Internal Server Error | ||
| */ | ||
| //get method that also checks for execute only to deny access to shared package, but package binding is handled | ||
| //within the mergePackageWithBinding() method | ||
|
bkemburu marked this conversation as resolved.
Outdated
|
||
| override def fetch(user: Identity, entityName: FullyQualifiedEntityName, env: Option[Parameters])( | ||
| implicit transid: TransactionId) = { | ||
| getEntity(WhiskPackage.get(entityStore, entityName.toDocId), Some { mergePackageWithBinding() _ }) | ||
| if (executeOnly && user.namespace.name != entityName.namespace) { | ||
| val value = entityName.toString | ||
| terminate(Forbidden, forbiddenGetPackage(entityName.asString)) | ||
| } else { | ||
| getEntity(WhiskPackage.get(entityStore, entityName.toDocId), Some { | ||
| mergePackageWithBinding() _ | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -303,9 +319,20 @@ trait WhiskPackagesApi extends WhiskCollectionAPI with ReferencedEntities { | |
| logging.error(this, s"unexpected package binding refers to itself: $docid") | ||
| terminate(UnprocessableEntity, Messages.packageBindingCircularReference(b.fullyQualifiedName.toString)) | ||
| } else { | ||
| getEntity(WhiskPackage.get(entityStore, docid), Some { | ||
| mergePackageWithBinding(Some { wp }) _ | ||
| }) | ||
|
|
||
| /** Here's where I check package execute only case with package binding. */ | ||
| val packagePath = wp.namespace.asString | ||
| val bindingPath = wp.binding.iterator.next().toString | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, because this code falls within a binding case so binding has to hold some value.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah not enough context shown in the diff; then I think you can replace |
||
| val indexOfSlash = bindingPath.indexOf('/') | ||
| if (executeOnly && packagePath != bindingPath.take(indexOfSlash)) { | ||
| terminate(Forbidden, forbiddenGetPackageBinding(wp.name.asString)) | ||
| } else { | ||
| getEntity(WhiskPackage.get(entityStore, docid), Some { | ||
| mergePackageWithBinding(Some { | ||
| wp | ||
| }) _ | ||
| }) | ||
| } | ||
| } | ||
| } getOrElse { | ||
| val pkg = ref map { _ inherit wp.parameters } getOrElse wp | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.