Skip to content
This repository has been archived by the owner on Sep 22, 2022. It is now read-only.

Commit

Permalink
Merge pull request #10 from F3Joule/f3-pallet-permissions
Browse files Browse the repository at this point in the history
Loose coupling of pallets: Roles + Social
  • Loading branch information
siman committed Jun 5, 2020
2 parents 88f06ae + ed534f9 commit cb4f689
Show file tree
Hide file tree
Showing 29 changed files with 1,079 additions and 4,075 deletions.
17 changes: 14 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions Cargo.toml
Expand Up @@ -23,6 +23,7 @@ log = '0.4.8'
parking_lot = '0.9.0'
tokio = '0.1.22'
trie-root = '0.15.2'
hex-literal = "0.2.1"

[dependencies.codec]
package = 'parity-scale-codec'
Expand Down Expand Up @@ -91,6 +92,12 @@ git = 'https://github.com/paritytech/substrate.git'
rev = '3e651110aa06aa835790df63410a29676243fc54'
version = '2.0.0'

[dependencies.telemetry]
package = 'sc-telemetry'
git = 'https://github.com/paritytech/substrate.git'
rev = '3e651110aa06aa835790df63410a29676243fc54'
version = '2.0.0'

[dependencies.sp-consensus]
git = 'https://github.com/paritytech/substrate.git'
rev = '3e651110aa06aa835790df63410a29676243fc54'
Expand Down
4 changes: 0 additions & 4 deletions docker/docker-compose.yml
Expand Up @@ -8,10 +8,6 @@ services:
image: dappforce/subsocial-node:latest
container_name: subsocial-node
network_mode: "host"
ports:
- "9944:9944"
- "30333:30333"
- "9933:9933"
restart: on-failure
volumes:
- chain_data:/data
Expand Down
10 changes: 8 additions & 2 deletions pallets/permissions/Cargo.toml
Expand Up @@ -8,11 +8,12 @@ edition = "2018"
default = ['std']
std = [
'codec/std',
'frame-support/std',
'sp-runtime/std',
'frame-support/std',
'system/std',
'sp-io/std',
'sp-std/std',
'system/std'
'pallet-utils/std'
]

[dependencies.codec]
Expand Down Expand Up @@ -52,6 +53,11 @@ git = 'https://github.com/paritytech/substrate.git'
rev = '3e651110aa06aa835790df63410a29676243fc54'
version = '2.0.0'

[dependencies.pallet-utils]
default-features = false
path = '../utils'
version = '2.0.0'

[dev-dependencies.sp-core]
default-features = false
git = 'https://github.com/paritytech/substrate.git'
Expand Down
142 changes: 112 additions & 30 deletions pallets/permissions/src/lib.rs
@@ -1,82 +1,164 @@
#![cfg_attr(not(feature = "std"), no_std)]

use sp_std::prelude::*;
use sp_std::collections::btree_set::BTreeSet;
use sp_std::{
prelude::*,
collections::btree_set::BTreeSet
};
use codec::{Encode, Decode};
use frame_support::{decl_module, traits::Get};
use frame_support::{
decl_module,
traits::Get
};
use sp_runtime::RuntimeDebug;

use pallet_utils::SpaceId;

#[derive(Encode, Decode, Ord, PartialOrd, Clone, Eq, PartialEq, RuntimeDebug)]
pub enum SpacePermission {
/// Create, update, grant and revoke roles in this space.
ManageRoles,
/// Create, update own and delete any subspaces in this space.
ManageSubspaces,
/// Create, update own and delete any root posts in this space.
ManagePosts,
/// Create, update own and delete any comments in this space.
ManageComments,

/// Act on behalf of this space within this space.
RepresentSpaceInternally,
/// Act on behalf of this space outside of this space.
RepresentSpaceExternally,

UpdateSpace,
BlockUsers, // or BlockUsers

// TODO what about 'DeleteSpace'? (too dangerous)
BlockUsers,

// Related to subspaces in this space:
CreateSubspaces,
UpdateOwnSubspaces,
UpdateAnySubspaces,
DeleteOwnSubspaces,
DeleteAnySubspaces,
BlockSubspaces,

// Related to posts in this space:
CreatePosts,
UpdateOwnPosts,
UpdateAnyPosts,
DeleteOwnPosts,
DeleteAnyPosts,
BlockPosts,

// Related to comments in this space:
CreateComments,
UpdateOwnComments,
DeleteOwnComments,
DeleteAnyComments,
BlockComments,

/// Upvote on any post or comment in this space.
Upvote,
/// Upvote on any post or comment in this space.
Downvote,
/// Share any post or comment from this space to another outer space.
Share,

OverridePostPermissions,
}

#[derive(Encode, Decode, Ord, PartialOrd, Clone, Eq, PartialEq, RuntimeDebug)]
pub enum PostPermission {
// Related to comments on this post:
CreateComments,
UpdateOwnComments,
DeleteOwnComments,
pub type SpacePermissionSet = BTreeSet<SpacePermission>;

// Related to this post and its comments:
Upvote,
Downvote,
Share,
#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug)]
pub struct SpacePermissions {
pub none: Option<SpacePermissionSet>,
pub everyone: Option<SpacePermissionSet>,
pub follower: Option<SpacePermissionSet>,
pub space_owner: Option<SpacePermissionSet>,
}

impl Default for SpacePermissions {
fn default() -> SpacePermissions {
SpacePermissions {
none: None,
everyone: None,
follower: None,
space_owner: None,
}
}
}

#[derive(Encode, Decode, Clone, Eq, PartialEq, RuntimeDebug)]
pub struct SpacePermissionsContext {
pub space_id: SpaceId,
pub is_space_owner: bool,
pub is_space_follower: bool,
pub space_perms: Option<SpacePermissions>
}

/// The pallet's configuration trait.
pub trait Trait: system::Trait {
type DefaultEveryoneSpacePermissions: Get<BTreeSet<SpacePermission>>;

type DefaultFollowerSpacePermissions: Get<BTreeSet<SpacePermission>>;
type DefaultSpacePermissions: Get<SpacePermissions>;
}

decl_module! {
pub struct Module<T: Trait> for enum Call where origin: T::Origin {
const DefaultEveryoneSpacePermissions: BTreeSet<SpacePermission> = T::DefaultEveryoneSpacePermissions::get();
const DefaultSpacePermissions: SpacePermissions = T::DefaultSpacePermissions::get();
}
}

const DefaultFollowerSpacePermissions: BTreeSet<SpacePermission> = T::DefaultFollowerSpacePermissions::get();
impl SpacePermission {
fn is_present_in_role(&self, perms_opt: Option<SpacePermissionSet>) -> bool {
if let Some(perms) = perms_opt {
if perms.contains(self) {
return true
}
}
false
}
}

impl<T: Trait> Module<T> {

fn get_overrides_or_defaults(
overrides: Option<SpacePermissionSet>,
defaults: Option<SpacePermissionSet>
) -> Option<SpacePermissionSet> {

return if overrides.is_some() {
overrides
} else {
defaults
}
}

fn resolve_space_perms(
space_perms: Option<SpacePermissions>,
) -> SpacePermissions {

let defaults = T::DefaultSpacePermissions::get();
let overrides = space_perms.unwrap_or_default();

SpacePermissions {
none: Self::get_overrides_or_defaults(overrides.none, defaults.none),
everyone: Self::get_overrides_or_defaults(overrides.everyone, defaults.everyone),
follower: Self::get_overrides_or_defaults(overrides.follower, defaults.follower),
space_owner: Self::get_overrides_or_defaults(overrides.space_owner, defaults.space_owner)
}
}

pub fn has_user_a_space_permission(
ctx: SpacePermissionsContext,
permission: SpacePermission,
) -> Option<bool> {

let perms_by_role = Self::resolve_space_perms(ctx.space_perms);

// Check if this permission is forbidden:
if permission.is_present_in_role(perms_by_role.none) {
return Some(false)
}

let is_space_owner = ctx.is_space_owner;
let is_follower = is_space_owner || ctx.is_space_follower;

if
permission.is_present_in_role(perms_by_role.everyone) ||
is_follower && permission.is_present_in_role(perms_by_role.follower) ||
is_space_owner && permission.is_present_in_role(perms_by_role.space_owner)
{
return Some(true)
}

None
}
}
41 changes: 23 additions & 18 deletions pallets/permissions/types.json
@@ -1,40 +1,45 @@
{
"SpacePermission":{
"_enum":[
"SpacePermissionSet": "BTreeSet<SpacePermission>",

"SpacePermission": {
"_enum": [
"ManageRoles",
"ManageSubspaces",
"ManagePosts",
"ManageComments",
"RepresentSpaceInternally",
"RepresentSpaceExternally",
"UpdateSpace",
"BlockUsers",
"CreateSubspaces",
"UpdateOwnSubspaces",
"UpdateAnySubspaces",
"DeleteOwnSubspaces",
"DeleteAnySubspaces",
"BlockSubspaces",
"CreatePosts",
"UpdateOwnPosts",
"UpdateAnyPosts",
"DeleteOwnPosts",
"DeleteAnyPosts",
"BlockPosts",
"CreateComments",
"UpdateOwnComments",
"DeleteOwnComments",
"DeleteAnyComments",
"BlockComments",
"Upvote",
"Downvote",
"Share"
"Share",
"OverridePostPermissions"
]
},

"PostPermission":{
"_enum":[
"CreateComments",
"UpdateOwnComments",
"DeleteOwnComments",
"Upvote",
"Downvote",
"Share"
]
"SpacePermissions": {
"none": "Option<SpacePermissionSet>",
"everyone": "Option<SpacePermissionSet>",
"follower": "Option<SpacePermissionSet>",
"space_owner": "Option<SpacePermissionSet>"
},

"SpacePermissionsContext": {
"space_id": "SpaceId",
"is_space_owner": "bool",
"is_space_follower": "bool",
"space_perms": "Option<SpacePermissionSet>"
}
}

0 comments on commit cb4f689

Please sign in to comment.