Skip to content

Commit

Permalink
Make the action's downloadable for the shared user
Browse files Browse the repository at this point in the history
  • Loading branch information
ningyougang committed Jun 8, 2020
1 parent 02099e1 commit 4af70b8
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -367,23 +367,41 @@ object WhiskAction extends DocumentFactory[WhiskAction] with WhiskEntityQueries[

// notes on users, just have 2 type users,
// 1. the action's owner
// 2. the user (not the owner) who used the shared action directly(e.g. get, invoke)
// 2. the user (not the owner) who used the shared action directly(e.g. get, invoke), we call it "the shared user"
//
// Notes on permission control
// 1. the action's read permission should open forever, because under invoke action or update action and so on,
// need to use `fetch` api to get the action to judge it whether exist.
// 2. the user(not the owner) can't update/delete the action forever.
// 3. the owner's permission can affect other user's permission, e.g
// if the owner is not given execute permission, the user(not the owner) can't have execute permission as well.
// 1. the owner has read(or download) permission on any situation, but for the shared user,
// in spite of has read permission on any situation, but can set it undownloadable or downloadable
// 2. the shared user can't update/delete the action on any situation.
// 3. the owner's permission can affect the shared user's permission, e.g
// if the owner is not given execute permission, the shared user can't have execute permission as well.
//
// Notes on permission values, include below permission value
// 1. permission code:rwxr-x: owner:read(yes)/write(yes)/execute(yes)|the shared action's user:read(yes)/write(no)/execute(yes), this is default
// 2. permission code:rwxr--: owner:read(yes)/write(yes)/execute(yes)|the shared action's user:read(yes)/write(no)/execute(no)
// 3. permission code:r-xr-x: owner:read(yes)/write(no)/execute(yes)|the shared action's user:read(yes)/write(no)/execute(yes)
// 4. permission code:r-xr--: owner:read(yes)/write(no)/execute(yes)|the shared action's user:read(yes)/write(no)/execute(no)
// 5. permission code:r--r--: owner:read(yes)/write(no)/execute(no)|the shared action's user:read(yes)/write(no)/execute(no)
// 6. permission code:rw-r--: owner:read(yes)/write(yes)/execute(no)|the shared action's user:read(yes)/write(no)/execute(no)
val permissionList = List(defaultPermissions, "rwxr--", "r-xr-x", "r-xr--", "r--r--", "rw-r--")
// 1. permission code:rwxr-x: owner:read(yes)/write(yes)/execute(yes)|the shared action's user:download(yes)/write(no)/execute(yes), this is default
// 2. permission code:rwxr--: owner:read(yes)/write(yes)/execute(yes)|the shared action's user:download(yes)/write(no)/execute(no)
// 3. permission code:r-xr-x: owner:read(yes)/write(no)/execute(yes)|the shared action's user:download(yes)/write(no)/execute(yes)
// 4. permission code:r-xr--: owner:read(yes)/write(no)/execute(yes)|the shared action's user:download(yes)/write(no)/execute(no)
// 5. permission code:r--r--: owner:read(yes)/write(no)/execute(no)|the shared action's user:download(yes)/write(no)/execute(no)
// 6. permission code:rw-r--: owner:read(yes)/write(yes)/execute(no)|the shared action's user:download(yes)/write(no)/execute(no)
// 7. permission code:rwx--x: owner:read(yes)/write(yes)/execute(yes)|the shared action's user:download(no)/write(no)/execute(yes)
// 8. permission code:rwx---: owner:read(yes)/write(yes)/execute(yes)|the shared action's user:download(no)/write(no)/execute(no)
// 9. permission code:r-x--x: owner:read(yes)/write(no)/execute(yes)|the shared action's user:download(no)/write(no)/execute(yes)
// 10. permission code:r-x---: owner:read(yes)/write(no)/execute(yes)|the shared action's user:download(no)/write(no)/execute(no)
// 11. permission code:r-----: owner:read(yes)/write(no)/execute(no)|the shared action's user:download(no)/write(no)/execute(no)
// 12. permission code:rw----: owner:read(yes)/write(yes)/execute(no)|the shared action's user:download(no)/write(no)/execute(no)
val permissionList = List(
defaultPermissions,
"rwxr--",
"r-xr-x",
"r-xr--",
"r--r--",
"rw-r--",
"rwx--x",
"rwx---",
"r-x--x",
"r-x---",
"r-----",
"rw----")

override val collectionName = "actions"
override val cacheEnabled = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -368,12 +368,19 @@ trait WhiskActionsApi extends WhiskCollectionAPI with PostActionActivation with
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)
})
onComplete(
entitlementProvider
.checkActionPermissions("download", user, entityStore, entityName, WhiskAction.get)) {
case Success(_) =>
getEntity(WhiskAction.resolveActionAndMergeParameters(entityStore, entityName), Some {
action: WhiskAction =>
val mergedAction = env map {
action inherit _
} getOrElse action
complete(OK, mergedAction)
})
case Failure(f) => super.handleEntitlementFailure(f)
}
case false =>
getEntity(WhiskActionMetaData.resolveActionAndMergeParameters(entityStore, entityName), Some {
action: WhiskActionMetaData =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -334,8 +334,26 @@ protected[core] abstract class EntitlementProvider(
Future.successful(())
}
}
} else { //get
Future.successful(())
} else { // download the code
get(entityStore, entityName.toDocId, DocRevision.empty, true).flatMap { whiskAction =>
val currentPermissions = whiskAction.annotations
.get(WhiskAction.permissionsFieldName)
.map(value => value.convertTo[String])
.getOrElse(WhiskAction.defaultPermissions)

val errorInfo = s"have no permission to download this shared action"
val currentDownloadPermission = currentPermissions.charAt(3)
if (user.namespace.name.asString != entityName.path.root.asString) { // the shared user who download the action
if (currentDownloadPermission == '-') {
Future.failed(RejectRequest(Forbidden, Some(ErrorResponse(errorInfo, transid))))
} else {
Future.successful(())
}
} else {
// the owner has download permission on any situation
Future.successful(())
}
}
}
}

Expand Down
16 changes: 11 additions & 5 deletions docs/actions.md
Original file line number Diff line number Diff line change
Expand Up @@ -662,14 +662,14 @@ You can clean up by deleting actions that you do not want to use.

* Notes on users, just have 2 type users,
- the action's owner
- the user (not the owner) who used the shared action directly(e.g. get, invoke)
- the user (not the owner) who used the shared action directly(e.g. get, invoke), we call it "the shared user"

* Notes on permission control
- the action's read permission should open forever, because under invoke action or update action and so on,
need to use `fetch` api to get the action to judge it whether exist.
- the user(not the owner) can't update/delete the action forever.
- the owner has read(or download) permission on any situation, but for the shared user,
in spite of has read permission on any situation, but can set it undownloadable or downloadable
- the shared user can't update/delete the action forever.
- the owner's permission can affect other user's permission, e.g
if the owner is not given execute permission, the user(not the owner) can't have execute permission as well.
if the owner is not given execute permission, the shared user can't have execute permission as well.

* Notes on permission values, include below permission value
- permission code:rwxr-x: owner:read(yes)/write(yes)/execute(yes)|the shared action's user:read(yes)/write(no)/execute(yes), this is default
Expand All @@ -678,6 +678,12 @@ You can clean up by deleting actions that you do not want to use.
- permission code:r-xr--: owner:read(yes)/write(no)/execute(yes)|the shared action's user:read(yes)/write(no)/execute(no)
- permission code:r--r--: owner:read(yes)/write(no)/execute(no)|the shared action's user:read(yes)/write(no)/execute(no)
- permission code:rw-r--: owner:read(yes)/write(yes)/execute(no)|the shared action's user:read(yes)/write(no)/execute(no)
- permission code:rwx--x: owner:read(yes)/write(yes)/execute(yes)|the shared action's user:download(no)/write(no)/execute(yes)
- permission code:rwx---: owner:read(yes)/write(yes)/execute(yes)|the shared action's user:download(no)/write(no)/execute(no)
- permission code:r-x--x: owner:read(yes)/write(no)/execute(yes)|the shared action's user:download(no)/write(no)/execute(yes)
- permission code:r-x---: owner:read(yes)/write(no)/execute(yes)|the shared action's user:download(no)/write(no)/execute(no)
- permission code:r-----: owner:read(yes)/write(no)/execute(no)|the shared action's user:download(no)/write(no)/execute(no)
- permission code:rw----: owner:read(yes)/write(yes)/execute(no)|the shared action's user:download(no)/write(no)/execute(no)

When create action without permissions annotation, permission control keeps the same as before,
e.g. the owner has all permissions(create/update(or delete)/invoke), the user(not owner) doesn't have update/delete permission on the shared action.
Expand Down

0 comments on commit 4af70b8

Please sign in to comment.