Difference between revisions of "Permissions"

From SocialStack
 
(3 intermediate revisions by one other user not shown)
Line 63: Line 63:


* Custom Rule (a string)
* Custom Rule (a string)
   This is a [[filter|Filters]] string, but one which supports constants. Typically you'd use filter functions in here.
   This is a [[Filters|filter]] string, but one which supports constants. Typically you'd use filter functions in here.


Whenever the API is considering returning a result, the grant rule is effectively AND'ed with any user provided filter.
Whenever the API is considering returning a result, the grant rule is effectively AND'ed with any user provided filter.
= How the permission system runs =
During startup, the permission system goes over every AutoService (including non-content type ones) and adds itself as an event handler with priority 1 on specific event handlers such as any EventHandler<ContentType> Before*. See the section on custom capabilities for more information. For example, page_create is tested by some code in Events.Page.BeforeCreate.AddEventListener(..., 1). Because of the way how [[Events|the event system works]], this means all default event handlers run after the permission system does, but you can also run code just before it by using priority 0:
<syntaxhighlight lang="csharp">
Events.Page.BeforeCreate.AddEventListener(async (Context context, Page page) => {
    // Runs *before* the permission system
    return page;
}, 0);
</syntaxhighlight>
= Custom capabilities =
The easiest way to create a new capability is to define an event handler in your services event group whose name starts with the word Before and the field type is an EventHandler<ContentType> such as EventHandler<User> BeforeHello. If it is not a content type, i.e. EventHandler<X> where X is not a :Content, then you must add [Permissions(Check=true)] to it.
<syntaxhighlight lang="csharp">
// Events.cs
public partial class Events
{
    public ThingEventGroup Thing;
}
public class ThingEventGroup : EventGroup<Thing>
{
    public EventHandler<Thing> BeforeSearch;
    [Permissions(Check=true)]
    public EventHandler<string> BeforeSomething;
}
</syntaxhighlight>
Then specify default permissions for your custom checked ones over in Permissions.cs as they will be blocked to all users except super users by default otherwise.

Latest revision as of 10:50, 22 August 2025

SocialStack has a largely automated roles and capabilities permission system. In summary, a user has exactly one role, and a role is granted capabilities.


Core Roles

All SocialStack API's have 6 core roles, in order of typical privilege:

  • Developer
 The ultimate super user, defaults to no restrictions on anything.
  • Admin
 An administrator which is typically locked from changing potentially site breaking configuration.
  • Member
 A fully setup logged in user on the site.
  • Guest
 Typically this is someone who has created a user account but has not yet activated it in some way.
  • Public
 Anonymous users of the internet.
  • Banned
 A banned user account which typically gets bricked from most things.

Via the admin panel, you can edit the name and grants of these roles. You can also create a custom role which derives from any of them (or derives from none of them if you want a clean slate).

Default Grants

The above core roles are important for thirdparty modules. Ideally you want to be able to install a module and by default its permissions are set well, regardless of what actual roles you have on your website. The pattern here is that a module can optionally define a set of default grants, usually in a file called Permissions.cs, and those grants target the above 6 core roles. Custom roles then inherit from a most appropriate core role in order for it to automatically also inherit general module default grants like this.

If a module does not define a Permissions.cs, it will still gain basic best guess grants which are as follows:

  • Anyone can read it
  • Only developer role can create new ones.
  • You must be either a developer or the owner of a content (it's UserId column equals your ID) to update or delete it.

Importantly, all default grants can be overriden in the admin panel. If you set a grant rule on the admin panel, it will be the rule that wins always, meaning that the admin panels representation of the grants is always accurate.

Capabilities

Each role has a list of capabilities, which themselves are automatically generated based on what is in your project. In general they come in a group of 5:

  • _list
  • _load
  • _create
  • _update
  • _delete

They aren't restricted to this though - custom ones can also be defined. For a given capability in a given role, a grant rule is defined.

Grant Rules

Grant rules are the mechanism to indicate if a particular role is able to do something. They have 4 possible values:

  • Always deny (false)
 Anyone with this role will not be able to perform this capability.
  • Always allow (true)
 Anyone with this role will be able to perform this capability.
  • Inherit (null, the default)
 The grant is based on what the inherited role, if any, specifies. If the grant is not specified by any inherited role, then the grant is based on the default grants from the code.
  • Custom Rule (a string)
 This is a filter string, but one which supports constants. Typically you'd use filter functions in here.

Whenever the API is considering returning a result, the grant rule is effectively AND'ed with any user provided filter.

How the permission system runs

During startup, the permission system goes over every AutoService (including non-content type ones) and adds itself as an event handler with priority 1 on specific event handlers such as any EventHandler<ContentType> Before*. See the section on custom capabilities for more information. For example, page_create is tested by some code in Events.Page.BeforeCreate.AddEventListener(..., 1). Because of the way how the event system works, this means all default event handlers run after the permission system does, but you can also run code just before it by using priority 0:

Events.Page.BeforeCreate.AddEventListener(async (Context context, Page page) => {
    // Runs *before* the permission system
    return page;
}, 0);

Custom capabilities

The easiest way to create a new capability is to define an event handler in your services event group whose name starts with the word Before and the field type is an EventHandler<ContentType> such as EventHandler<User> BeforeHello. If it is not a content type, i.e. EventHandler<X> where X is not a :Content, then you must add [Permissions(Check=true)] to it.


// Events.cs

public partial class Events
{
    public ThingEventGroup Thing;
}

public class ThingEventGroup : EventGroup<Thing>
{
    public EventHandler<Thing> BeforeSearch;

    [Permissions(Check=true)]
    public EventHandler<string> BeforeSomething;
}

Then specify default permissions for your custom checked ones over in Permissions.cs as they will be blocked to all users except super users by default otherwise.