Skip to content

Commit d77a80f

Browse files
committed
Change permission to unix style
1 parent 38053a6 commit d77a80f

File tree

5 files changed

+69
-70
lines changed

5 files changed

+69
-70
lines changed

common/scala/src/main/scala/org/apache/openwhisk/core/entity/WhiskAction.scala

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,7 @@ case class WhiskActionPut(exec: Option[Exec] = None,
5656
limits: Option[ActionLimitsOption] = None,
5757
version: Option[SemVer] = None,
5858
publish: Option[Boolean] = None,
59-
annotations: Option[Parameters] = None,
60-
unlock: Option[Boolean] = None) {
59+
annotations: Option[Parameters] = None) {
6160

6261
protected[core] def replace(exec: Exec) = {
6362
WhiskActionPut(Some(exec), parameters, limits, version, publish, annotations)
@@ -76,6 +75,17 @@ case class WhiskActionPut(exec: Option[Exec] = None,
7675
case _ => this
7776
} getOrElse this
7877
}
78+
79+
protected[core] def getPermissions(): String = {
80+
annotations match {
81+
case Some(value) =>
82+
value
83+
.get(WhiskAction.permissionsFieldName)
84+
.map(value => value.convertTo[String])
85+
.getOrElse(WhiskAction.defaultPermissions)
86+
case None => WhiskAction.defaultPermissions
87+
}
88+
}
7989
}
8090

8191
abstract class WhiskActionLike(override val name: EntityName) extends WhiskEntity(name, "action") {
@@ -352,6 +362,24 @@ object WhiskAction extends DocumentFactory[WhiskAction] with WhiskEntityQueries[
352362
val requireWhiskAuthHeader = "x-require-whisk-auth"
353363
val lockFieldName = "lock"
354364

365+
// annotation permission key name
366+
val permissionsFieldName = "permissions"
367+
368+
// action is used by two type user, one is its owner, the owner has read(yes)/write(yes)/execute(yes) permissions by default,
369+
// another user uses the shared action who has read(yes)/write(no)/execute(yes) permissions permissions by default
370+
// only the owner can modify the permissions
371+
val defaultPermissions = "rwxr-x"
372+
373+
// includes below permission codes only for action.
374+
// permission code:rwxr-x or 75: owner:read(yes)/write(yes)/execute(yes)|the shared action's user:read(yes)/write(no)/execute(yes), this is default
375+
// permission code:r-xr-x or 55: owner:read(yes)/write(no)/execute(yes)|the shared action's user:read(yes)/write(no)/execute(yes)
376+
// permission code:r--r-- or 44: owner:read(yes)/write(no)/execute(no)|the shared action's user:read(yes)/write(no)/execute(no)
377+
// permission code:rx-r-- or 64: owner:read(yes)/write(yes)/execute(no)|the shared action's user:read(yes)/write(no)/execute(no)
378+
// permission code:-wx--x or 31: owner:read(no)/write(yes)/execute(yes)|the shared action's user:read(no)/write(no)/execute(yes)
379+
// permission code:--x--x or 11: owner:read(no)/write(no)/execute(yes)|the shared action's user:read(no)/write(no)/execute(yes)
380+
// permission code:------ or 00: owner:read(no)/write(no)/execute(no)|the shared action's user:read(no)/write(no)/execute(no)
381+
val permissionList = List(defaultPermissions, "r-xr-x", "r--r--", "rx-r--", "-wx--x", "--x--x", "------")
382+
355383
override val collectionName = "actions"
356384
override val cacheEnabled = true
357385

@@ -645,5 +673,5 @@ object ActionLimitsOption extends DefaultJsonProtocol {
645673
}
646674

647675
object WhiskActionPut extends DefaultJsonProtocol {
648-
implicit val serdes = jsonFormat7(WhiskActionPut.apply)
676+
implicit val serdes = jsonFormat6(WhiskActionPut.apply)
649677
}

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

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,16 @@ package org.apache.openwhisk.http
2020
import scala.concurrent.duration.Duration
2121
import scala.concurrent.duration.FiniteDuration
2222
import scala.util.Try
23-
2423
import akka.http.scaladsl.model.StatusCode
2524
import akka.http.scaladsl.model.StatusCodes.Forbidden
2625
import akka.http.scaladsl.model.StatusCodes.NotFound
2726
import akka.http.scaladsl.model.MediaType
2827
import akka.http.scaladsl.server.Directives
2928
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport.sprayJsonMarshaller
3029
import akka.http.scaladsl.server.StandardRoute
31-
3230
import spray.json._
33-
3431
import org.apache.openwhisk.common.TransactionId
35-
import org.apache.openwhisk.core.entity.SizeError
36-
import org.apache.openwhisk.core.entity.ByteSize
37-
import org.apache.openwhisk.core.entity.Exec
38-
import org.apache.openwhisk.core.entity.ExecMetaDataBase
39-
import org.apache.openwhisk.core.entity.ActivationId
32+
import org.apache.openwhisk.core.entity.{ActivationId, ByteSize, Exec, ExecMetaDataBase, SizeError, WhiskAction}
4033

4134
object Messages {
4235

@@ -83,6 +76,8 @@ object Messages {
8376
s"The supplied authentication is not authorized to access '$value'."
8477
def notAuthorizedtoActionKind(value: String) =
8578
s"The supplied authentication is not authorized to access actions of kind '$value'."
79+
def notAuthorizedtoActionPermission(value: String) =
80+
s"The supplied authentication is not authorized to give permission code: '$value', available permission is in ${WhiskAction.permissionList}"
8681

8782
/** Standard error message for malformed fully qualified entity names. */
8883
val malformedFullyQualifiedEntityName =

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

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -209,13 +209,16 @@ trait WhiskActionsApi extends WhiskCollectionAPI with PostActionActivation with
209209
val checkAdditionalPrivileges = entitleReferencedEntities(user, Privilege.READ, request.exec).flatMap {
210210
case _ => entitlementProvider.check(user, content.exec)
211211
}
212-
val unlock = content.unlock.getOrElse(false)
213212

214213
onComplete(checkAdditionalPrivileges) {
215214
case Success(_) =>
216-
putEntity(WhiskAction, entityStore, entityName.toDocId, overwrite, update(user, request) _, () => {
217-
make(user, entityName, request)
218-
}, unlock = unlock)
215+
onComplete(entitlementProvider.checkActionPermissions(content.getPermissions())) {
216+
case Success(_) =>
217+
putEntity(WhiskAction, entityStore, entityName.toDocId, overwrite, update(user, request) _, () => {
218+
make(user, entityName, request)
219+
})
220+
case Failure(f) => super.handleEntitlementFailure(f)
221+
}
219222
case Failure(f) =>
220223
super.handleEntitlementFailure(f)
221224
}
@@ -554,9 +557,7 @@ trait WhiskActionsApi extends WhiskCollectionAPI with PostActionActivation with
554557
content.version getOrElse action.version.upPatch,
555558
content.publish getOrElse action.publish,
556559
WhiskActionsApi
557-
.amendAnnotations(content.annotations getOrElse action.annotations, exec, create = false) ++ content.unlock
558-
.map(u => Parameters(WhiskAction.lockFieldName, JsBoolean(!u)))
559-
.getOrElse(Parameters()))
560+
.amendAnnotations(content.annotations getOrElse action.annotations, exec, create = false))
560561
.revision[WhiskAction](action.docinfo.rev)
561562
}
562563

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

Lines changed: 12 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -25,22 +25,18 @@ import scala.util.Failure
2525
import scala.util.Success
2626
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
2727
import akka.http.scaladsl.model.StatusCode
28-
import akka.http.scaladsl.model.StatusCodes._
28+
import akka.http.scaladsl.model.StatusCodes.Conflict
29+
import akka.http.scaladsl.model.StatusCodes.InternalServerError
30+
import akka.http.scaladsl.model.StatusCodes.NotFound
31+
import akka.http.scaladsl.model.StatusCodes.OK
2932
import akka.http.scaladsl.server.{Directives, RequestContext, RouteResult}
3033
import spray.json.DefaultJsonProtocol._
3134
import spray.json.{JsObject, JsValue, RootJsonFormat}
3235
import org.apache.openwhisk.common.Logging
3336
import org.apache.openwhisk.common.TransactionId
3437
import org.apache.openwhisk.core.controller.PostProcess.PostProcessEntity
3538
import org.apache.openwhisk.core.database._
36-
import org.apache.openwhisk.core.entity.{
37-
ActivationId,
38-
ActivationLogs,
39-
DocId,
40-
WhiskAction,
41-
WhiskActivation,
42-
WhiskDocument
43-
}
39+
import org.apache.openwhisk.core.entity.{ActivationId, ActivationLogs, DocId, WhiskActivation, WhiskDocument}
4440
import org.apache.openwhisk.http.ErrorResponse
4541
import org.apache.openwhisk.http.ErrorResponse.terminate
4642
import org.apache.openwhisk.http.Messages._
@@ -314,8 +310,7 @@ trait WriteOps extends Directives {
314310
update: A => Future[A],
315311
create: () => Future[A],
316312
treatExistsAsConflict: Boolean = true,
317-
postProcess: Option[PostProcessEntity[A]] = None,
318-
unlock: Boolean = false)(
313+
postProcess: Option[PostProcessEntity[A]] = None)(
319314
implicit transid: TransactionId,
320315
format: RootJsonFormat[A],
321316
notifier: Option[CacheChangeNotification],
@@ -340,24 +335,8 @@ trait WriteOps extends Directives {
340335
} flatMap {
341336
case (old, a) =>
342337
logging.debug(this, s"[PUT] entity created/updated, writing back to datastore")
343-
if (overwrite && !unlock && old.getOrElse(None).isInstanceOf[WhiskAction]) {
344-
val oldWhiskAction = old.getOrElse(None).asInstanceOf[WhiskAction]
345-
oldWhiskAction.annotations.get(WhiskAction.lockFieldName) match {
346-
case Some(value) if (value.convertTo[Boolean]) => {
347-
Future failed RejectRequest(
348-
MethodNotAllowed,
349-
s"this action can't be updated until ${WhiskAction.lockFieldName} annotation is updated to false")
350-
}
351-
case _ => {
352-
factory.put(datastore, a, old) map { _ =>
353-
a
354-
}
355-
}
356-
}
357-
} else {
358-
factory.put(datastore, a, old) map { _ =>
359-
a
360-
}
338+
factory.put(datastore, a, old) map { _ =>
339+
a
361340
}
362341
}) {
363342
case Success(entity) =>
@@ -411,30 +390,11 @@ trait WriteOps extends Directives {
411390
notifier: Option[CacheChangeNotification],
412391
ma: Manifest[A]) = {
413392
onComplete(factory.get(datastore, docid) flatMap { entity =>
414-
if (entity.isInstanceOf[WhiskAction]) {
415-
val whiskAction = entity.asInstanceOf[WhiskAction]
416-
whiskAction.annotations.get(WhiskAction.lockFieldName) match {
417-
case Some(value) if (value.convertTo[Boolean]) => {
418-
Future failed RejectRequest(
419-
MethodNotAllowed,
420-
s"this action can't be deleted until ${WhiskAction.lockFieldName} annotation is updated to false")
393+
confirm(entity) flatMap {
394+
case _ =>
395+
factory.del(datastore, entity.docinfo) map { _ =>
396+
entity
421397
}
422-
case _ => {
423-
confirm(entity) flatMap {
424-
case _ =>
425-
factory.del(datastore, entity.docinfo) map { _ =>
426-
entity
427-
}
428-
}
429-
}
430-
}
431-
} else {
432-
confirm(entity) flatMap {
433-
case _ =>
434-
factory.del(datastore, entity.docinfo) map { _ =>
435-
entity
436-
}
437-
}
438398
}
439399
}) {
440400
case Success(entity) =>

core/controller/src/main/scala/org/apache/openwhisk/core/entitlement/Entitlement.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,21 @@ protected[core] abstract class EntitlementProvider(
231231
.getOrElse(Future.successful(()))
232232
}
233233

234+
/**
235+
* Checks if an action permission code is whether right
236+
*
237+
* @param permissions the permission code
238+
* @return a promise that completes with success iff the permission code is right
239+
*/
240+
protected[core] def checkActionPermissions(permissions: String)(implicit transid: TransactionId): Future[Unit] = {
241+
if (WhiskAction.permissionList.contains(permissions)) {
242+
Future.successful(())
243+
} else {
244+
Future.failed(
245+
RejectRequest(Forbidden, Some(ErrorResponse(Messages.notAuthorizedtoActionPermission(permissions), transid))))
246+
}
247+
}
248+
234249
/**
235250
* Checks if a subject has the right to access a specific resource. The entitlement may be implicit,
236251
* that is, inferred based on namespaces that a subject belongs to and the namespace of the

0 commit comments

Comments
 (0)