<h1>Permissions<aclass="headerlink"href="#permissions"title="Permalink to this headline">¶</a></h1>
<p>A <em>permission</em> is simply a text string stored in the handler <codeclass="docutils literal notranslate"><spanclass="pre">permissions</span></code> on <codeclass="docutils literal notranslate"><spanclass="pre">Objects</span></code>
and <codeclass="docutils literal notranslate"><spanclass="pre">Accounts</span></code>. Think of it as a specialized sort of <aclass="reference internal"href="Tags.html"><spanclass="doc std std-doc">Tag</span></a> - one specifically dedicated
to access checking. They are thus often tightly coupled to <aclass="reference internal"href="Locks.html"><spanclass="doc std std-doc">Locks</span></a>.
hierarchies. It is set by the <codeclass="docutils literal notranslate"><spanclass="pre">perm</span></code> command and checked by the
<codeclass="docutils literal notranslate"><spanclass="pre">PermissionHandler.check</span></code> method as well as by the specially the <codeclass="docutils literal notranslate"><spanclass="pre">perm()</span></code> and
<p>Note the use of the <codeclass="docutils literal notranslate"><spanclass="pre">/account</span></code> switch. It means you assign the permission to the
<aclass="reference internal"href="Accounts.html"><spanclass="doc std std-doc">Accounts</span></a> Tommy instead of any <aclass="reference internal"href="Objects.html"><spanclass="doc std std-doc">Character</span></a> that also
<p>In code, you add/remove Permissions via the <codeclass="docutils literal notranslate"><spanclass="pre">PermissionHandler</span></code>, which sits on all
typeclassed entities as the property <codeclass="docutils literal notranslate"><spanclass="pre">.permissions</span></code>:</p>
<h2>The permission hierarchy<aclass="headerlink"href="#the-permission-hierarchy"title="Permalink to this headline">¶</a></h2>
<p>Selected permission strings can be organized in a <em>permission hierarchy</em> by editing the tuple
<codeclass="docutils literal notranslate"><spanclass="pre">settings.PERMISSION_HIERARCHY</span></code>. Evennia’s default permission hierarchy is as follows
<p>(Besides being case-insensitive, hierarchical permissions also understand the
plural form, so you could use <codeclass="docutils literal notranslate"><spanclass="pre">Developers</span></code> and <codeclass="docutils literal notranslate"><spanclass="pre">Developer</span></code> interchangeably).</p>
<blockquote>
<div><p>There is also a <codeclass="docutils literal notranslate"><spanclass="pre">Guest</span></code> level below <codeclass="docutils literal notranslate"><spanclass="pre">Player</span></code> that is only active if <codeclass="docutils literal notranslate"><spanclass="pre">settings.GUEST_ENABLED</span></code> is
set. The Guest is is never part of <codeclass="docutils literal notranslate"><spanclass="pre">settings.PERMISSION_HIERARCHY</span></code>.</p>
</div></blockquote>
<p>When checking a hierarchical permission (using one of the methods to follow),
you will pass checks for your level and all <em>below</em> you. That is, even if the
check explicitly checks for “Builder” level access, you will actually pass if you have
one of “Builder”, “Admin” or “Developer”. By contrast, if you check for a
non-hierarchical permission, like “Blacksmith” you <em>must</em> have exactly
that permission to pass.</p>
</section>
<sectionid="checking-permissions">
<h2>Checking permissions<aclass="headerlink"href="#checking-permissions"title="Permalink to this headline">¶</a></h2>
<p>It’s important to note that you check for the permission of a <em>puppeted</em>
permissions of any <codeclass="docutils literal notranslate"><spanclass="pre">Account</span></code> connected to that Object before checking for
permissions on the Object. In the case of hierarchical permissions (Admins,
Builders etc), the Account permission will always be used (this stops an Account
from escalating their permission by puppeting a high-level Character). If the
permission looked for is not in the hierarchy, an exact match is required, first
on the Account and if not found there (or if no Account is connected), then on
the Object itself.</p>
<sectionid="checking-with-obj-permissions-check">
<h3>Checking with obj.permissions.check()<aclass="headerlink"href="#checking-with-obj-permissions-check"title="Permalink to this headline">¶</a></h3>
<p>The simplest way to check if an entity has a permission is to check its
<em>PermissionHandler</em>, stored as <codeclass="docutils literal notranslate"><spanclass="pre">.permissions</span></code> on all typeclassed entities.</p>
<divclass="highlight-none notranslate"><divclass="highlight"><pre><span></span>Don't confuse `.permissions.check()` with `.permissions.has()`. The .has()
method checks if a string is defined specifically on that PermissionHandler.
It will not consider permission-hierarchy, puppeting etc. `.has` can be useful
if you are manipulating permissions, but use `.check` for access checking.
<p>While the <codeclass="docutils literal notranslate"><spanclass="pre">PermissionHandler</span></code> offers a simple way to check perms, <aclass="reference internal"href="Locks.html"><spanclass="doc std std-doc">Lock
strings</span></a> offers a mini-language for describing how something is accessed.
The <codeclass="docutils literal notranslate"><spanclass="pre">perm()</span></code><em>lock function</em> is the main tool for using Permissions in locks.</p>
<p>Let’s say we have a <codeclass="docutils literal notranslate"><spanclass="pre">red_key</span></code> object. We also have red chests that we want to
<divclass="highlight-python notranslate"><divclass="highlight"><pre><span></span><spanclass="c1"># in some typeclass file where chest is defined</span>
<spanclass="n">who</span><spanclass="o">.</span><spanclass="n">msg</span><spanclass="p">(</span><spanclass="s2">"The key does not fit!"</span><spanclass="p">)</span>
<p>There are several variations to the default <codeclass="docutils literal notranslate"><spanclass="pre">perm</span></code> lockfunc:</p>
<ulclass="simple">
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">perm_above</span></code> - requires a hierarchical permission <em>higher</em> than the one
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">pperm</span></code> - looks <em>only</em> for permissions on <codeclass="docutils literal notranslate"><spanclass="pre">Accounts</span></code>, never at any puppeted
objects (regardless of hierarchical perm or not).</p></li>
<li><p><codeclass="docutils literal notranslate"><spanclass="pre">pperm_above</span></code> - like <codeclass="docutils literal notranslate"><spanclass="pre">perm_above</span></code>, but for Accounts only.</p></li>
</ul>
</section>
<sectionid="some-examples">
<h3>Some examples<aclass="headerlink"href="#some-examples"title="Permalink to this headline">¶</a></h3>
<spanclass="n">account</span><spanclass="o">.</span><spanclass="n">locks</span><spanclass="o">.</span><spanclass="n">add</span><spanclass="p">(</span><spanclass="s2">"enter:perm_above(Player) and perm(cool_guy)"</span><spanclass="p">)</span>
<spanclass="n">account</span><spanclass="o">.</span><spanclass="n">access</span><spanclass="p">(</span><spanclass="n">obj1</span><spanclass="p">,</span><spanclass="s2">"enter"</span><spanclass="p">)</span><spanclass="c1"># this returns True!</span>
<spanclass="n">obj2</span><spanclass="o">.</span><spanclass="n">locks</span><spanclass="o">.</span><spanclass="n">add</span><spanclass="p">(</span><spanclass="s2">"enter:perm_above(Accounts) and perm(cool_guy)"</span><spanclass="p">)</span>
<spanclass="n">obj2</span><spanclass="o">.</span><spanclass="n">access</span><spanclass="p">(</span><spanclass="n">puppet</span><spanclass="p">,</span><spanclass="s2">"enter"</span><spanclass="p">)</span><spanclass="c1"># this returns False, since puppet permission</span>
<spanclass="c1"># is lower than Account's perm, and perm takes</span>
<p>The <codeclass="docutils literal notranslate"><spanclass="pre">quell</span></code> command can be used to enforce the <codeclass="docutils literal notranslate"><spanclass="pre">perm()</span></code> lockfunc to ignore
permissions on the Account and instead use the permissions on the Character
only. This can be used e.g. by staff to test out things with a lower permission
level. Return to the normal operation with <codeclass="docutils literal notranslate"><spanclass="pre">unquell</span></code>. Note that quelling will
use the smallest of any hierarchical permission on the Account or Character, so
one cannot escalate one’s Account permission by quelling to a high-permission
Character. Also the superuser can quell their powers this way, making them