Skip to content

Commit 13c7f50

Browse files
Bhavesh KemburuBhavesh Kemburu
authored andcommitted
Improved logic of fetching actions
1 parent e11d229 commit 13c7f50

File tree

3 files changed

+48
-68
lines changed

3 files changed

+48
-68
lines changed

common/scala/src/main/scala/org/apache/openwhisk/http/ErrorResponse.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ object Messages {
231231
val resourceProvisionError = "Failed to provision resources to run the action."
232232

233233
def forbiddenGetActionBinding(entityDocId: String) =
234-
s"GET not permitted for '$entityDocId'. Resource does not exist or an action in a shared package binding."
234+
s"GET not permitted for '$entityDocId'. Resource does not exist or is an action in a shared package binding."
235235
def forbiddenGetAction(entityPath: String) =
236236
s"GET not permitted for '$entityPath' since it's an action in a shared package"
237237
def forbiddenGetPackageBinding(packageName: String) =

core/controller/src/main/scala/org/apache/openwhisk/core/controller/Actions.scala

Lines changed: 44 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,7 @@ trait WhiskActionsApi extends WhiskCollectionAPI with PostActionActivation with
106106

107107
/** Config flag for Execute Only for Actions in Shared Packages */
108108
protected def executeOnly =
109-
Try({
110-
loadConfigOrThrow[Boolean](ConfigKeys.sharedPackageExecuteOnly)
111-
}).getOrElse(false)
109+
loadConfigOrThrow[Boolean](ConfigKeys.sharedPackageExecuteOnly)
112110

113111
/** Entity normalizer to JSON object. */
114112
import RestApiCommons.emptyEntityToJsObject
@@ -338,27 +336,27 @@ trait WhiskActionsApi extends WhiskCollectionAPI with PostActionActivation with
338336
deleteEntity(WhiskAction, entityStore, entityName.toDocId, (a: WhiskAction) => Future.successful({}))
339337
}
340338

341-
/**
342-
* Gets action. The action name is prefixed with the namespace to create the primary index key.
343-
*
344-
* Responses are one of (Code, Message)
345-
* - 200 WhiskAction has JSON
346-
* - 404 Not Found
347-
* - 500 Internal Server Error
348-
*/
349-
override def fetch(user: Identity, entityName: FullyQualifiedEntityName, env: Option[Parameters])(
339+
/** Checks for package binding case. we don't want to allow get for a package binding in shared package */
340+
private def fetchEntity(entityName: FullyQualifiedEntityName, env: Option[Parameters], code: Boolean)(
350341
implicit transid: TransactionId) = {
351-
parameter('code ? true) { code =>
352-
//check if execute only is enabled, and if there is a discrepancy between the current user's namespace
353-
//and that of the entity we are trying to fetch
354-
355-
if (executeOnly && user.namespace.name != entityName.namespace) {
356-
terminate(Forbidden, forbiddenGetAction(entityName.path.asString))
357-
} else {
358-
code match {
359-
case true =>
360-
//Resolve Binding(Package) of the action
361-
if (entityName.path.defaultPackage) {
342+
val resolvedPkg: Future[Either[String, FullyQualifiedEntityName]] = if (entityName.path.defaultPackage) {
343+
Future.successful(Right(entityName))
344+
} else {
345+
WhiskPackage.resolveBinding(entityStore, entityName.path.toDocId, mergeParameters = true).map { pkg =>
346+
val originalPackageLocation = pkg.fullyQualifiedName(withVersion = false).namespace
347+
if (executeOnly && originalPackageLocation != entityName.namespace) {
348+
Left(forbiddenGetActionBinding(entityName.toDocId.asString))
349+
} else {
350+
Right(entityName)
351+
}
352+
}
353+
}
354+
onComplete(resolvedPkg) {
355+
case Success(pkgFuture) =>
356+
pkgFuture match {
357+
case Left(f) => terminate(Forbidden, f)
358+
case Right(_) =>
359+
if (code) {
362360
getEntity(WhiskAction.resolveActionAndMergeParameters(entityStore, entityName), Some {
363361
action: WhiskAction =>
364362
val mergedAction = env map {
@@ -367,51 +365,38 @@ trait WhiskActionsApi extends WhiskCollectionAPI with PostActionActivation with
367365
complete(OK, mergedAction)
368366
})
369367
} else {
370-
getEntity(
371-
WhiskPackage.resolveBinding(entityStore, entityName.path.toDocId, mergeParameters = true),
372-
Some { pkg: WhiskPackage =>
373-
val originalPackageLocation = pkg.fullyQualifiedName(withVersion = false).namespace
374-
if (executeOnly && originalPackageLocation != entityName.namespace) {
375-
terminate(Forbidden, forbiddenGetActionBinding(entityName.toDocId.asString))
376-
} else {
377-
getEntity(WhiskAction.resolveActionAndMergeParameters(entityStore, entityName), Some {
378-
action: WhiskAction =>
379-
val mergedAction = env map {
380-
action inherit _
381-
} getOrElse action
382-
complete(OK, mergedAction)
383-
})
384-
}
385-
})
386-
}
387-
case false =>
388-
if (entityName.path.defaultPackage) {
389368
getEntity(WhiskActionMetaData.resolveActionAndMergeParameters(entityStore, entityName), Some {
390369
action: WhiskActionMetaData =>
391370
val mergedAction = env map {
392371
action inherit _
393372
} getOrElse action
394373
complete(OK, mergedAction)
395374
})
396-
} else {
397-
getEntity(
398-
WhiskPackage.resolveBinding(entityStore, entityName.path.toDocId, mergeParameters = true),
399-
Some { pkg: WhiskPackage =>
400-
val originalPackageLocation = pkg.fullyQualifiedName(withVersion = false).namespace
401-
if (executeOnly && originalPackageLocation != entityName.namespace) {
402-
terminate(Forbidden, forbiddenGetActionBinding(entityName.toDocId.asString))
403-
} else {
404-
getEntity(WhiskActionMetaData.resolveActionAndMergeParameters(entityStore, entityName), Some {
405-
action: WhiskActionMetaData =>
406-
val mergedAction = env map {
407-
action inherit _
408-
} getOrElse action
409-
complete(OK, mergedAction)
410-
})
411-
}
412-
})
413375
}
414376
}
377+
case Failure(t: Throwable) =>
378+
logging.error(this, s"[GET] package ${entityName.path.toDocId} failed: ${t.getMessage}")
379+
terminate(InternalServerError)
380+
}
381+
}
382+
383+
/**
384+
* Gets action. The action name is prefixed with the namespace to create the primary index key.
385+
*
386+
* Responses are one of (Code, Message)
387+
* - 200 WhiskAction has JSON
388+
* - 404 Not Found
389+
* - 500 Internal Server Error
390+
*/
391+
override def fetch(user: Identity, entityName: FullyQualifiedEntityName, env: Option[Parameters])(
392+
implicit transid: TransactionId) = {
393+
parameter('code ? true) { code =>
394+
//check if execute only is enabled, and if there is a discrepancy between the current user's namespace
395+
//and that of the entity we are trying to fetch
396+
if (executeOnly && user.namespace.name != entityName.namespace) {
397+
terminate(Forbidden, forbiddenGetAction(entityName.path.asString))
398+
} else {
399+
fetchEntity(entityName, env, code)
415400
}
416401
}
417402
}

core/controller/src/main/scala/org/apache/openwhisk/core/controller/Packages.scala

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
package org.apache.openwhisk.core.controller
1919

2020
import scala.concurrent.Future
21-
import scala.util.{Failure, Success, Try}
21+
import scala.util.{Failure, Success}
2222
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
2323
import akka.http.scaladsl.model.StatusCodes._
2424
import akka.http.scaladsl.server.{RequestContext, RouteResult}
@@ -45,9 +45,7 @@ trait WhiskPackagesApi extends WhiskCollectionAPI with ReferencedEntities {
4545

4646
/** Config flag for Execute Only for Shared Packages */
4747
protected def executeOnly =
48-
Try({
49-
loadConfigOrThrow[Boolean](ConfigKeys.sharedPackageExecuteOnly)
50-
}).getOrElse(false)
48+
loadConfigOrThrow[Boolean](ConfigKeys.sharedPackageExecuteOnly)
5149

5250
/** Notification service for cache invalidation. */
5351
protected implicit val cacheChangeNotification: Some[CacheChangeNotification]
@@ -321,10 +319,7 @@ trait WhiskPackagesApi extends WhiskCollectionAPI with ReferencedEntities {
321319
} else {
322320

323321
/** Here's where I check package execute only case with package binding. */
324-
val packagePath = wp.namespace.asString
325-
val bindingPath = wp.binding.iterator.next().toString
326-
val indexOfSlash = bindingPath.indexOf('/')
327-
if (executeOnly && packagePath != bindingPath.take(indexOfSlash)) {
322+
if (executeOnly && wp.namespace.asString != b.namespace.asString) {
328323
terminate(Forbidden, forbiddenGetPackageBinding(wp.name.asString))
329324
} else {
330325
getEntity(WhiskPackage.get(entityStore, docid), Some {

0 commit comments

Comments
 (0)