<pclass="last">You are reading an old version of the Evennia documentation. <ahref="https://www.evennia.com/docs/latest/index.html">The latest version is here</a></p>.
<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>. Permission strings are not case-sensitive, so “Builder” is the same as “builder” etc.</p>
<p>Permissions are used as a convenient way to structure access levels and 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 <codeclass="docutils literal notranslate"><spanclass="pre">pperm()</span></code><aclass="reference internal"href="Locks.html"><spanclass="doc std std-doc">lock functions</span></a>.</p>
<p>All new accounts are given a default set of permissions defined by <codeclass="docutils literal notranslate"><spanclass="pre">settings.PERMISSION_ACCOUNT_DEFAULT</span></code>.</p>
<sectionid="the-super-user">
<h2>The super user<aclass="headerlink"href="#the-super-user"title="Permalink to this headline">¶</a></h2>
<p>There are strictly speaking two types of users in Evennia, the <em>super user</em> and everyone else. The
superuser is the first user you create, object <codeclass="docutils literal notranslate"><spanclass="pre">#1</span></code>. This is the all-powerful server-owner account.
Technically the superuser not only has access to everything, it <em>bypasses</em> the permission checks
entirely.</p>
<p>This makes the superuser impossible to lock out, but makes it unsuitable to actually play-
test the game’s locks and restrictions with (see <codeclass="docutils literal notranslate"><spanclass="pre">quell</span></code> below). Usually there is no need to have
but one superuser.</p>
</section>
<sectionid="working-with-permissions">
<h2>Working with Permissions<aclass="headerlink"href="#working-with-permissions"title="Permalink to this headline">¶</a></h2>
<p>In-game, you use the <codeclass="docutils literal notranslate"><spanclass="pre">perm</span></code> command to add and remove permissions</p>
<divclass="highlight-none notranslate"><divclass="highlight"><pre><span></span>> perm/account Tommy = Builders
> perm/account/del Tommy = Builders
</pre></div>
</div>
<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 happens to be named “Tommy”. If you don’t want to use <codeclass="docutils literal notranslate"><spanclass="pre">/account</span></code>, you can also prefix the name with <codeclass="docutils literal notranslate"><spanclass="pre">*</span></code> to indicate an Account is sought:</p>
<p>There can be reasons for putting permissions on Objects (especially NPCS), but for granting powers to players, you should usually put the permission on the <codeclass="docutils literal notranslate"><spanclass="pre">Account</span></code> - this guarantees that they are kept, <em>regardless</em> of which Character they are currently puppeting.</p>
<p>This is especially important to remember when assigning permissions from the <em>hierarchy tree</em> (see below), as an Account’s permissions will overrule that of its character. So to be sure to avoid confusion you should generally put hierarchy permissions on the Account, not on their Characters/puppets.</p>
<p>If you <em>do</em> want to start using the permissions on your <em>puppet</em>, you use <codeclass="docutils literal notranslate"><spanclass="pre">quell</span></code></p>
<p>This drops to the permissions on the puppeted object, and then back to your Account-permissions again. Quelling is useful if you want to try something “as” someone else. It’s also useful for superusers since this makes them susceptible to locks (so they can test things).</p>
<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>
<h3>The permission hierarchy<aclass="headerlink"href="#the-permission-hierarchy"title="Permalink to this headline">¶</a></h3>
<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
(in increasing order of power):</p>
<divclass="highlight-none notranslate"><divclass="highlight"><pre><span></span> Guest # temporary account, only used if GUEST_ENABLED=True (lowest)
Player # can chat and send tells (default level)
Helper # can edit help files
Builder # can edit the world
Admin # can administrate accounts
Developer # like superuser but affected by locks (highest)
</pre></div>
</div>
<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>
<p>When checking a hierarchical permission (using one of the methods to follow), you will pass checks for your level <em>and below</em>. That is, if you have the “Admin” hierarchical permission, you will also pass checks asking for “Builder”, “Helper” and so on.</p>
<p>By contrast, if you check for a non-hierarchical permission, like “Blacksmith” you must have <em>exactly</em> that permission to pass.</p>
</section>
<sectionid="checking-permissions">
<h3>Checking permissions<aclass="headerlink"href="#checking-permissions"title="Permalink to this headline">¶</a></h3>
<p>It’s important to note that you check for the permission of a <em>puppeted</em><aclass="reference internal"href="Objects.html"><spanclass="doc std std-doc">Object</span></a> (like a Character), the check will always first use the 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>
</section>
<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>
if obj.permissions.check("Blacksmith", "Warrior"):
# do stuff for blacksmiths OR warriors
if obj.permissions.check("Blacksmith", "Warrior", require_all=True):
# only for those that are both blacksmiths AND warriors
</pre></div>
</div>
<p>Using the <codeclass="docutils literal notranslate"><spanclass="pre">.check</span></code> method is the way to go, it will take hierarchical
permissions into account, check accounts/sessions etc.</p>
<divclass="admonition warning">
<pclass="admonition-title">Warning</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.
</pre></div>
</div>
</div>
</section>
<sectionid="lock-funcs">
<h3>Lock funcs<aclass="headerlink"href="#lock-funcs"title="Permalink to this headline">¶</a></h3>
<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
<p>This gives the <codeclass="docutils literal notranslate"><spanclass="pre">red_key</span></code> object the permission “unlocks_red_chests”. Next we
lock our red chests:</p>
<divclass="highlight-none notranslate"><divclass="highlight"><pre><span></span>lock red chest = unlock:perm(unlocks_red_chests)
</pre></div>
</div>
<p>When trying to unlock the red chest with this key, the chest Typeclass could
then take the key and do an access check:</p>
<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>
<spanclass="k">return</span>
<spanclass="k">else</span><spanclass="p">:</span>
<spanclass="n">who</span><spanclass="o">.</span><spanclass="n">msg</span><spanclass="p">(</span><spanclass="s2">"The key fits! The chest opens."</span><spanclass="p">)</span>
<spanclass="c1"># ...</span>
</pre></div>
</div>
<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>
</pre></div>
</div>
<p>An example of a puppet with a connected account:</p>
<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>
<spanclass="c1"># precedence.</span>
</pre></div>
</div>
</section>
</section>
<sectionid="quelling">
<h2>Quelling<aclass="headerlink"href="#quelling"title="Permalink to this headline">¶</a></h2>
<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
<pclass="last">You are reading an old version of the Evennia documentation. <ahref="https://www.evennia.com/docs/latest/index.html">The latest version is here</a></p>.