evennia/docs/latest/_modules/evennia/locks/lockhandler.html
Evennia docbuilder action d17f22fc2c Updated HTML docs.
2024-03-17 13:48:03 +00:00

923 lines
No EOL
87 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>evennia.locks.lockhandler &#8212; Evennia latest documentation</title>
<link rel="stylesheet" href="../../../_static/nature.css" type="text/css" />
<link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
<script src="../../../_static/jquery.js"></script>
<script src="../../../_static/underscore.js"></script>
<script src="../../../_static/doctools.js"></script>
<script src="../../../_static/language_data.js"></script>
<link rel="shortcut icon" href="../../../_static/favicon.ico"/>
<link rel="index" title="Index" href="../../../genindex.html" />
<link rel="search" title="Search" href="../../../search.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../../../genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="../../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="nav-item nav-item-0"><a href="../../../index.html">Evennia latest</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="../../index.html" >Module code</a> &#187;</li>
<li class="nav-item nav-item-2"><a href="../../evennia.html" accesskey="U">evennia</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">evennia.locks.lockhandler</a></li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<p class="logo"><a href="../../../index.html">
<img class="logo" src="../../../_static/evennia_logo.png" alt="Logo"/>
</a></p>
<div id="searchbox" style="display: none" role="search">
<h3 id="searchlabel">Quick search</h3>
<div class="searchformwrapper">
<form class="search" action="../../../search.html" method="get">
<input type="text" name="q" aria-labelledby="searchlabel" />
<input type="submit" value="Go" />
</form>
</div>
</div>
<script>$('#searchbox').show(0);</script><h3>Links</h3>
<ul>
<li><a href="https://www.evennia.com/docs/latest/index.html">Documentation Top</a> </li>
<li><a href="https://www.evennia.com">Evennia Home</a> </li>
<li><a href="https://github.com/evennia/evennia">Github</a> </li>
<li><a href="http://games.evennia.com">Game Index</a> </li>
<li>
<a href="https://discord.gg/AJJpcRUhtF">Discord</a> -
<a href="https://github.com/evennia/evennia/discussions">Discussions</a> -
<a href="https://evennia.blogspot.com/">Blog</a>
</li>
</ul>
<h3>Doc Versions</h3>
<ul>
<li><a href="lockhandler.html">latest (main branch)</a></li>
<li><a href="../4.x/index.html">v4.0.0 branch (outdated)</a></li>
<li><a href="../3.x/index.html">v3.0.0 branch (outdated)</a></li>
<li><a href="../2.x/index.html">v2.0.0 branch (outdated)</a></li>
<li><a href="../1.x/index.html">v1.0.0 branch (outdated)</a></li>
<li><a href="../0.x/index.html">v0.9.5 branch (outdated)</a></li>
</ul>
</div>
</div>
<div class="bodywrapper">
<div class="body" role="main">
<h1>Source code for evennia.locks.lockhandler</h1><div class="highlight"><pre>
<span></span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">A *lock* defines access to a particular subsystem or property of</span>
<span class="sd">Evennia. For example, the &quot;owner&quot; property can be impmemented as a</span>
<span class="sd">lock. Or the disability to lift an object or to ban users.</span>
<span class="sd">A lock consists of three parts:</span>
<span class="sd"> - access_type - this defines what kind of access this lock regulates. This</span>
<span class="sd"> just a string.</span>
<span class="sd"> - function call - this is one or many calls to functions that will determine</span>
<span class="sd"> if the lock is passed or not.</span>
<span class="sd"> - lock function(s). These are regular python functions with a special</span>
<span class="sd"> set of allowed arguments. They should always return a boolean depending</span>
<span class="sd"> on if they allow access or not.</span>
<span class="sd">A lock function is defined by existing in one of the modules</span>
<span class="sd">listed by settings.LOCK_FUNC_MODULES. It should also always</span>
<span class="sd">take four arguments looking like this:</span>
<span class="sd"> funcname(accessing_obj, accessed_obj, *args, **kwargs):</span>
<span class="sd"> [...]</span>
<span class="sd">The accessing object is the object wanting to gain access.</span>
<span class="sd">The accessed object is the object this lock resides on</span>
<span class="sd">args and kwargs will hold optional arguments and/or keyword arguments</span>
<span class="sd">to the function as a list and a dictionary respectively.</span>
<span class="sd">Example:</span>
<span class="sd"> perm(accessing_obj, accessed_obj, *args, **kwargs):</span>
<span class="sd"> &quot;Checking if the object has a particular, desired permission&quot;</span>
<span class="sd"> if args:</span>
<span class="sd"> desired_perm = args[0]</span>
<span class="sd"> return desired_perm in accessing_obj.permissions.all()</span>
<span class="sd"> return False</span>
<span class="sd">Lock functions should most often be pretty general and ideally possible to</span>
<span class="sd">re-use and combine in various ways to build clever locks.</span>
<span class="sd">Lock definition (&quot;Lock string&quot;)</span>
<span class="sd">A lock definition is a string with a special syntax. It is added to</span>
<span class="sd">each object&#39;s lockhandler, making that lock available from then on.</span>
<span class="sd">The lock definition looks like this:</span>
<span class="sd"> &#39;access_type:[NOT] func1(args)[ AND|OR][NOT] func2() ...&#39;</span>
<span class="sd">That is, the access_type, a colon followed by calls to lock functions</span>
<span class="sd">combined with AND or OR. NOT negates the result of the following call.</span>
<span class="sd">Example:</span>
<span class="sd"> We want to limit who may edit a particular object (let&#39;s call this access_type</span>
<span class="sd">for &#39;edit&#39;, it depends on what the command is looking for). We want this to</span>
<span class="sd">only work for those with the Permission &#39;Builder&#39;. So we use our lock</span>
<span class="sd">function above and define it like this:</span>
<span class="sd"> &#39;edit:perm(Builder)&#39;</span>
<span class="sd">Here, the lock-function perm() will be called with the string</span>
<span class="sd">&#39;Builder&#39; (accessing_obj and accessed_obj are added automatically,</span>
<span class="sd">you only need to add the args/kwargs, if any).</span>
<span class="sd">If we wanted to make sure the accessing object was BOTH a Builder and a</span>
<span class="sd">GoodGuy, we could use AND:</span>
<span class="sd"> &#39;edit:perm(Builder) AND perm(GoodGuy)&#39;</span>
<span class="sd">To allow EITHER Builder and GoodGuys, we replace AND with OR. perm() is just</span>
<span class="sd">one example, the lock function can do anything and compare any properties of</span>
<span class="sd">the calling object to decide if the lock is passed or not.</span>
<span class="sd"> &#39;lift:attrib(very_strong) AND NOT attrib(bad_back)&#39;</span>
<span class="sd">To make these work, add the string to the lockhandler of the object you want</span>
<span class="sd">to apply the lock to:</span>
<span class="sd"> obj.lockhandler.add(&#39;edit:perm(Builder)&#39;)</span>
<span class="sd">From then on, a command that wants to check for &#39;edit&#39; access on this</span>
<span class="sd">object would do something like this:</span>
<span class="sd"> if not target_obj.lockhandler.has_perm(caller, &#39;edit&#39;):</span>
<span class="sd"> caller.msg(&quot;Sorry, you cannot edit that.&quot;)</span>
<span class="sd">All objects also has a shortcut called &#39;access&#39; that is recommended to</span>
<span class="sd">use instead:</span>
<span class="sd"> if not target_obj.access(caller, &#39;edit&#39;):</span>
<span class="sd"> caller.msg(&quot;Sorry, you cannot edit that.&quot;)</span>
<span class="sd">Permissions</span>
<span class="sd">Permissions are just text strings stored in a comma-separated list on</span>
<span class="sd">typeclassed objects. The default perm() lock function uses them,</span>
<span class="sd">taking into account settings.PERMISSION_HIERARCHY. Also, the</span>
<span class="sd">restricted @perm command sets them, but otherwise they are identical</span>
<span class="sd">to any other identifier you can use.</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">re</span>
<span class="kn">from</span> <span class="nn">django.conf</span> <span class="kn">import</span> <span class="n">settings</span>
<span class="kn">from</span> <span class="nn">django.utils.translation</span> <span class="kn">import</span> <span class="n">gettext</span> <span class="k">as</span> <span class="n">_</span>
<span class="kn">import</span> <span class="nn">evennia</span>
<span class="kn">from</span> <span class="nn">evennia.utils</span> <span class="kn">import</span> <span class="n">logger</span><span class="p">,</span> <span class="n">utils</span>
<span class="n">__all__</span> <span class="o">=</span> <span class="p">(</span><span class="s2">&quot;LockHandler&quot;</span><span class="p">,</span> <span class="s2">&quot;LockException&quot;</span><span class="p">)</span>
<span class="n">WARNING_LOG</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">LOCKWARNING_LOG_FILE</span>
<span class="n">_LOCK_HANDLER</span> <span class="o">=</span> <span class="kc">None</span>
<span class="c1">#</span>
<span class="c1"># Exception class. This will be raised</span>
<span class="c1"># by errors in lock definitions.</span>
<span class="c1">#</span>
<div class="viewcode-block" id="LockException"><a class="viewcode-back" href="../../../api/evennia.locks.lockhandler.html#evennia.locks.lockhandler.LockException">[docs]</a><span class="k">class</span> <span class="nc">LockException</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Raised during an error in a lock.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">pass</span></div>
<span class="c1">#</span>
<span class="c1"># Cached lock functions</span>
<span class="c1">#</span>
<span class="n">_LOCKFUNCS</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">def</span> <span class="nf">_cache_lockfuncs</span><span class="p">():</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Updates the cache.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">global</span> <span class="n">_LOCKFUNCS</span>
<span class="n">_LOCKFUNCS</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">for</span> <span class="n">modulepath</span> <span class="ow">in</span> <span class="n">settings</span><span class="o">.</span><span class="n">LOCK_FUNC_MODULES</span><span class="p">:</span>
<span class="n">_LOCKFUNCS</span><span class="o">.</span><span class="n">update</span><span class="p">(</span><span class="n">utils</span><span class="o">.</span><span class="n">callables_from_module</span><span class="p">(</span><span class="n">modulepath</span><span class="p">))</span>
<span class="c1">#</span>
<span class="c1"># pre-compiled regular expressions</span>
<span class="c1">#</span>
<span class="n">_RE_FUNCS</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;\w+\([^)]*\)&quot;</span><span class="p">)</span>
<span class="n">_RE_SEPS</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;(?&lt;=[ )])AND(?=\s)|(?&lt;=[ )])OR(?=\s)|(?&lt;=[ )])NOT(?=\s)&quot;</span><span class="p">)</span>
<span class="n">_RE_OK</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2">|and|or|not&quot;</span><span class="p">)</span>
<span class="c1">#</span>
<span class="c1">#</span>
<span class="c1"># Lock handler</span>
<span class="c1">#</span>
<span class="c1">#</span>
<div class="viewcode-block" id="LockHandler"><a class="viewcode-back" href="../../../api/evennia.locks.lockhandler.html#evennia.locks.lockhandler.LockHandler">[docs]</a><span class="k">class</span> <span class="nc">LockHandler</span><span class="p">:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> This handler should be attached to all objects implementing</span>
<span class="sd"> permission checks, under the property &#39;lockhandler&#39;.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<div class="viewcode-block" id="LockHandler.__init__"><a class="viewcode-back" href="../../../api/evennia.locks.lockhandler.html#evennia.locks.lockhandler.LockHandler.__init__">[docs]</a> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Loads and pre-caches all relevant locks and their functions.</span>
<span class="sd"> Args:</span>
<span class="sd"> obj (object): The object on which the lockhandler is</span>
<span class="sd"> defined.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">_LOCKFUNCS</span><span class="p">:</span>
<span class="n">_cache_lockfuncs</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">obj</span> <span class="o">=</span> <span class="n">obj</span>
<span class="bp">self</span><span class="o">.</span><span class="n">locks</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">try</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">reset</span><span class="p">()</span>
<span class="k">except</span> <span class="n">LockException</span> <span class="k">as</span> <span class="n">err</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_trace</span><span class="p">(</span><span class="n">err</span><span class="p">)</span></div>
<span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="k">return</span> <span class="s2">&quot;;&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">locks</span><span class="p">[</span><span class="n">key</span><span class="p">][</span><span class="mi">2</span><span class="p">]</span> <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">locks</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">_log_error</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">message</span><span class="p">):</span>
<span class="s2">&quot;Try to log errors back to object&quot;</span>
<span class="k">raise</span> <span class="n">LockException</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_parse_lockstring</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">storage_lockstring</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Helper function. This is normally only called when the</span>
<span class="sd"> lockstring is cached and does preliminary checking. locks are</span>
<span class="sd"> stored as a string</span>
<span class="sd"> atype:[NOT] lock()[[ AND|OR [NOT] lock()[...]];atype...</span>
<span class="sd"> Args:</span>
<span class="sd"> storage_locksring (str): The lockstring to parse.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">locks</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">storage_lockstring</span><span class="p">:</span>
<span class="k">return</span> <span class="n">locks</span>
<span class="n">duplicates</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">elist</span> <span class="o">=</span> <span class="p">[]</span> <span class="c1"># errors</span>
<span class="n">wlist</span> <span class="o">=</span> <span class="p">[]</span> <span class="c1"># warnings</span>
<span class="k">for</span> <span class="n">raw_lockstring</span> <span class="ow">in</span> <span class="n">storage_lockstring</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;;&quot;</span><span class="p">):</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">raw_lockstring</span><span class="p">:</span>
<span class="k">continue</span>
<span class="n">lock_funcs</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">access_type</span><span class="p">,</span> <span class="n">rhs</span> <span class="o">=</span> <span class="p">(</span><span class="n">part</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">part</span> <span class="ow">in</span> <span class="n">raw_lockstring</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;:&quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_trace</span><span class="p">()</span>
<span class="k">return</span> <span class="n">locks</span>
<span class="c1"># parse the lock functions and separators</span>
<span class="n">funclist</span> <span class="o">=</span> <span class="n">_RE_FUNCS</span><span class="o">.</span><span class="n">findall</span><span class="p">(</span><span class="n">rhs</span><span class="p">)</span>
<span class="n">evalstring</span> <span class="o">=</span> <span class="n">rhs</span>
<span class="k">for</span> <span class="n">pattern</span> <span class="ow">in</span> <span class="p">(</span><span class="s2">&quot;AND&quot;</span><span class="p">,</span> <span class="s2">&quot;OR&quot;</span><span class="p">,</span> <span class="s2">&quot;NOT&quot;</span><span class="p">):</span>
<span class="n">evalstring</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;\b</span><span class="si">%s</span><span class="s2">\b&quot;</span> <span class="o">%</span> <span class="n">pattern</span><span class="p">,</span> <span class="n">pattern</span><span class="o">.</span><span class="n">lower</span><span class="p">(),</span> <span class="n">evalstring</span><span class="p">)</span>
<span class="n">nfuncs</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">funclist</span><span class="p">)</span>
<span class="k">for</span> <span class="n">funcstring</span> <span class="ow">in</span> <span class="n">funclist</span><span class="p">:</span>
<span class="n">funcname</span><span class="p">,</span> <span class="n">rest</span> <span class="o">=</span> <span class="p">(</span><span class="n">part</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="o">.</span><span class="n">strip</span><span class="p">(</span><span class="s2">&quot;)&quot;</span><span class="p">)</span> <span class="k">for</span> <span class="n">part</span> <span class="ow">in</span> <span class="n">funcstring</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;(&quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
<span class="n">func</span> <span class="o">=</span> <span class="n">_LOCKFUNCS</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">funcname</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="nb">callable</span><span class="p">(</span><span class="n">func</span><span class="p">):</span>
<span class="n">elist</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
<span class="n">_</span><span class="p">(</span><span class="s2">&quot;Lock: lock-function &#39;</span><span class="si">{lockfunc}</span><span class="s2">&#39; is not available.&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
<span class="n">lockfunc</span><span class="o">=</span><span class="n">funcstring</span>
<span class="p">)</span>
<span class="p">)</span>
<span class="k">continue</span>
<span class="n">args</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">arg</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">rest</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;,&quot;</span><span class="p">)</span> <span class="k">if</span> <span class="n">arg</span> <span class="ow">and</span> <span class="s2">&quot;=&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">arg</span><span class="p">)</span>
<span class="n">kwargs</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span>
<span class="p">[</span>
<span class="p">(</span><span class="n">part</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">part</span> <span class="ow">in</span> <span class="n">arg</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;=&quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>
<span class="k">for</span> <span class="n">arg</span> <span class="ow">in</span> <span class="n">rest</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;,&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">arg</span> <span class="ow">and</span> <span class="s2">&quot;=&quot;</span> <span class="ow">in</span> <span class="n">arg</span>
<span class="p">]</span>
<span class="p">)</span>
<span class="n">lock_funcs</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">func</span><span class="p">,</span> <span class="n">args</span><span class="p">,</span> <span class="n">kwargs</span><span class="p">))</span>
<span class="n">evalstring</span> <span class="o">=</span> <span class="n">evalstring</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="n">funcstring</span><span class="p">,</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">lock_funcs</span><span class="p">)</span> <span class="o">&lt;</span> <span class="n">nfuncs</span><span class="p">:</span>
<span class="k">continue</span>
<span class="k">try</span><span class="p">:</span>
<span class="c1"># purge the eval string of any superfluous items, then test it</span>
<span class="n">evalstring</span> <span class="o">=</span> <span class="s2">&quot; &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">_RE_OK</span><span class="o">.</span><span class="n">findall</span><span class="p">(</span><span class="n">evalstring</span><span class="p">))</span>
<span class="nb">eval</span><span class="p">(</span><span class="n">evalstring</span> <span class="o">%</span> <span class="nb">tuple</span><span class="p">(</span><span class="kc">True</span> <span class="k">for</span> <span class="n">func</span> <span class="ow">in</span> <span class="n">funclist</span><span class="p">),</span> <span class="p">{},</span> <span class="p">{})</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="n">elist</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
<span class="n">_</span><span class="p">(</span><span class="s2">&quot;Lock: definition &#39;</span><span class="si">{lock_string}</span><span class="s2">&#39; has syntax errors.&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
<span class="n">lock_string</span><span class="o">=</span><span class="n">raw_lockstring</span>
<span class="p">)</span>
<span class="p">)</span>
<span class="k">continue</span>
<span class="k">if</span> <span class="n">access_type</span> <span class="ow">in</span> <span class="n">locks</span><span class="p">:</span>
<span class="n">duplicates</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="n">wlist</span><span class="o">.</span><span class="n">append</span><span class="p">(</span>
<span class="n">_</span><span class="p">(</span>
<span class="s2">&quot;LockHandler on </span><span class="si">{obj}</span><span class="s2">: access type &#39;</span><span class="si">{access_type}</span><span class="s2">&#39; &quot;</span>
<span class="s2">&quot;changed from &#39;</span><span class="si">{source}</span><span class="s2">&#39; to &#39;</span><span class="si">{goal}</span><span class="s2">&#39; &quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
<span class="n">obj</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="p">,</span>
<span class="n">access_type</span><span class="o">=</span><span class="n">access_type</span><span class="p">,</span>
<span class="n">source</span><span class="o">=</span><span class="n">locks</span><span class="p">[</span><span class="n">access_type</span><span class="p">][</span><span class="mi">2</span><span class="p">],</span>
<span class="n">goal</span><span class="o">=</span><span class="n">raw_lockstring</span><span class="p">,</span>
<span class="p">)</span>
<span class="p">)</span>
<span class="p">)</span>
<span class="n">locks</span><span class="p">[</span><span class="n">access_type</span><span class="p">]</span> <span class="o">=</span> <span class="p">(</span><span class="n">evalstring</span><span class="p">,</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">lock_funcs</span><span class="p">),</span> <span class="n">raw_lockstring</span><span class="p">)</span>
<span class="k">if</span> <span class="n">wlist</span> <span class="ow">and</span> <span class="n">WARNING_LOG</span><span class="p">:</span>
<span class="c1"># a warning text was set, it&#39;s not an error, so only report</span>
<span class="n">logger</span><span class="o">.</span><span class="n">log_file</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">wlist</span><span class="p">),</span> <span class="n">WARNING_LOG</span><span class="p">)</span>
<span class="k">if</span> <span class="n">elist</span><span class="p">:</span>
<span class="c1"># an error text was set, raise exception.</span>
<span class="k">raise</span> <span class="n">LockException</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">elist</span><span class="p">))</span>
<span class="c1"># return the gathered locks in an easily executable form</span>
<span class="k">return</span> <span class="n">locks</span>
<span class="k">def</span> <span class="nf">_cache_locks</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">storage_lockstring</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Store data</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">locks</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_parse_lockstring</span><span class="p">(</span><span class="n">storage_lockstring</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">_save_locks</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Store locks to obj</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">lock_storage</span> <span class="o">=</span> <span class="s2">&quot;;&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="n">tup</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="k">for</span> <span class="n">tup</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">locks</span><span class="o">.</span><span class="n">values</span><span class="p">()])</span>
<div class="viewcode-block" id="LockHandler.cache_lock_bypass"><a class="viewcode-back" href="../../../api/evennia.locks.lockhandler.html#evennia.locks.lockhandler.LockHandler.cache_lock_bypass">[docs]</a> <span class="k">def</span> <span class="nf">cache_lock_bypass</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">obj</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> We cache superuser bypass checks here for efficiency. This</span>
<span class="sd"> needs to be re-run when an account is assigned to a character.</span>
<span class="sd"> We need to grant access to superusers. We need to check both</span>
<span class="sd"> directly on the object (accounts), through obj.account and using</span>
<span class="sd"> the get_account() method (this sits on serversessions, in some</span>
<span class="sd"> rare cases where a check is done before the login process has</span>
<span class="sd"> yet been fully finalized)</span>
<span class="sd"> Args:</span>
<span class="sd"> obj (object): This is checked for the `is_superuser` property.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">lock_bypass</span> <span class="o">=</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="s2">&quot;is_superuser&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="n">obj</span><span class="o">.</span><span class="n">is_superuser</span></div>
<div class="viewcode-block" id="LockHandler.add"><a class="viewcode-back" href="../../../api/evennia.locks.lockhandler.html#evennia.locks.lockhandler.LockHandler.add">[docs]</a> <span class="k">def</span> <span class="nf">add</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">lockstring</span><span class="p">,</span> <span class="n">validate_only</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Add a new lockstring to handler.</span>
<span class="sd"> Args:</span>
<span class="sd"> lockstring (str or list): A string on the form</span>
<span class="sd"> `&quot;&lt;access_type&gt;:&lt;functions&gt;&quot;`. Multiple access types</span>
<span class="sd"> should be separated by semicolon (`;`). Alternatively,</span>
<span class="sd"> a list with lockstrings.</span>
<span class="sd"> validate_only (bool, optional): If True, validate the lockstring but</span>
<span class="sd"> don&#39;t actually store it.</span>
<span class="sd"> Returns:</span>
<span class="sd"> success (bool): The outcome of the addition, `False` on</span>
<span class="sd"> error. If `validate_only` is True, this will be a tuple</span>
<span class="sd"> (bool, error), for pass/fail and a string error.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">lockstring</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
<span class="n">lockdefs</span> <span class="o">=</span> <span class="p">[</span>
<span class="n">stripped</span> <span class="k">for</span> <span class="n">lockdef</span> <span class="ow">in</span> <span class="n">lockstring</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;;&quot;</span><span class="p">)</span> <span class="k">if</span> <span class="p">(</span><span class="n">stripped</span> <span class="o">:=</span> <span class="n">lockdef</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span>
<span class="p">]</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">lockdefs</span> <span class="o">=</span> <span class="p">[</span>
<span class="n">stripped</span>
<span class="k">for</span> <span class="n">locks</span> <span class="ow">in</span> <span class="n">lockstring</span>
<span class="k">for</span> <span class="n">lockdef</span> <span class="ow">in</span> <span class="n">locks</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;;&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</span><span class="n">stripped</span> <span class="o">:=</span> <span class="n">lockdef</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span>
<span class="p">]</span>
<span class="n">lockstring</span> <span class="o">=</span> <span class="s2">&quot;;&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">lockdefs</span><span class="p">)</span>
<span class="n">err</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="c1"># sanity checks</span>
<span class="k">for</span> <span class="n">lockdef</span> <span class="ow">in</span> <span class="n">lockdefs</span><span class="p">:</span>
<span class="k">if</span> <span class="s2">&quot;:&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">lockdef</span><span class="p">:</span>
<span class="n">err</span> <span class="o">=</span> <span class="n">_</span><span class="p">(</span><span class="s2">&quot;Lock: &#39;</span><span class="si">{lockdef}</span><span class="s2">&#39; contains no colon (:).&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">lockdef</span><span class="o">=</span><span class="n">lockdef</span><span class="p">)</span>
<span class="k">if</span> <span class="n">validate_only</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">False</span><span class="p">,</span> <span class="n">err</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_log_error</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="n">access_type</span><span class="p">,</span> <span class="n">rhs</span> <span class="o">=</span> <span class="p">[</span><span class="n">part</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span> <span class="k">for</span> <span class="n">part</span> <span class="ow">in</span> <span class="n">lockdef</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;:&quot;</span><span class="p">,</span> <span class="mi">1</span><span class="p">)]</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">access_type</span><span class="p">:</span>
<span class="n">err</span> <span class="o">=</span> <span class="n">_</span><span class="p">(</span>
<span class="s2">&quot;Lock: &#39;</span><span class="si">{lockdef}</span><span class="s2">&#39; has no access_type &quot;</span> <span class="s2">&quot;(left-side of colon is empty).&quot;</span>
<span class="p">)</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">lockdef</span><span class="o">=</span><span class="n">lockdef</span><span class="p">)</span>
<span class="k">if</span> <span class="n">validate_only</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">False</span><span class="p">,</span> <span class="n">err</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_log_error</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">if</span> <span class="n">rhs</span><span class="o">.</span><span class="n">count</span><span class="p">(</span><span class="s2">&quot;(&quot;</span><span class="p">)</span> <span class="o">!=</span> <span class="n">rhs</span><span class="o">.</span><span class="n">count</span><span class="p">(</span><span class="s2">&quot;)&quot;</span><span class="p">):</span>
<span class="n">err</span> <span class="o">=</span> <span class="n">_</span><span class="p">(</span><span class="s2">&quot;Lock: &#39;</span><span class="si">{lockdef}</span><span class="s2">&#39; has mismatched parentheses.&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">lockdef</span><span class="o">=</span><span class="n">lockdef</span><span class="p">)</span>
<span class="k">if</span> <span class="n">validate_only</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">False</span><span class="p">,</span> <span class="n">err</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_log_error</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">_RE_FUNCS</span><span class="o">.</span><span class="n">findall</span><span class="p">(</span><span class="n">rhs</span><span class="p">):</span>
<span class="n">err</span> <span class="o">=</span> <span class="n">_</span><span class="p">(</span><span class="s2">&quot;Lock: &#39;</span><span class="si">{lockdef}</span><span class="s2">&#39; has no valid lock functions.&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">lockdef</span><span class="o">=</span><span class="n">lockdef</span><span class="p">)</span>
<span class="k">if</span> <span class="n">validate_only</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">False</span><span class="p">,</span> <span class="n">err</span>
<span class="k">else</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_log_error</span><span class="p">(</span><span class="n">err</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="k">if</span> <span class="n">validate_only</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">True</span><span class="p">,</span> <span class="kc">None</span>
<span class="c1"># get the lock string</span>
<span class="n">storage_lockstring</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">lock_storage</span>
<span class="k">if</span> <span class="n">storage_lockstring</span><span class="p">:</span>
<span class="n">storage_lockstring</span> <span class="o">=</span> <span class="n">storage_lockstring</span> <span class="o">+</span> <span class="s2">&quot;;&quot;</span> <span class="o">+</span> <span class="n">lockstring</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">storage_lockstring</span> <span class="o">=</span> <span class="n">lockstring</span>
<span class="c1"># cache the locks will get rid of eventual doublets</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_cache_locks</span><span class="p">(</span><span class="n">storage_lockstring</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_save_locks</span><span class="p">()</span>
<span class="k">return</span> <span class="kc">True</span></div>
<div class="viewcode-block" id="LockHandler.validate"><a class="viewcode-back" href="../../../api/evennia.locks.lockhandler.html#evennia.locks.lockhandler.LockHandler.validate">[docs]</a> <span class="k">def</span> <span class="nf">validate</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">lockstring</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Validate lockstring syntactically, without saving it.</span>
<span class="sd"> Args:</span>
<span class="sd"> lockstring (str): Lockstring to validate.</span>
<span class="sd"> Returns:</span>
<span class="sd"> valid (bool): If validation passed or not.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">lockstring</span><span class="p">,</span> <span class="n">validate_only</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span></div>
<div class="viewcode-block" id="LockHandler.replace"><a class="viewcode-back" href="../../../api/evennia.locks.lockhandler.html#evennia.locks.lockhandler.LockHandler.replace">[docs]</a> <span class="k">def</span> <span class="nf">replace</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">lockstring</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Replaces the lockstring entirely.</span>
<span class="sd"> Args:</span>
<span class="sd"> lockstring (str): The new lock definition.</span>
<span class="sd"> Return:</span>
<span class="sd"> success (bool): False if an error occurred.</span>
<span class="sd"> Raises:</span>
<span class="sd"> LockException: If a critical error occurred.</span>
<span class="sd"> If so, the old string is recovered.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">old_lockstring</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">clear</span><span class="p">()</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">lockstring</span><span class="p">)</span>
<span class="k">except</span> <span class="n">LockException</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">old_lockstring</span><span class="p">)</span>
<span class="k">raise</span></div>
<div class="viewcode-block" id="LockHandler.get"><a class="viewcode-back" href="../../../api/evennia.locks.lockhandler.html#evennia.locks.lockhandler.LockHandler.get">[docs]</a> <span class="k">def</span> <span class="nf">get</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">access_type</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Get the full lockstring or the lockstring of a particular</span>
<span class="sd"> access type.</span>
<span class="sd"> Args:</span>
<span class="sd"> access_type (str, optional):</span>
<span class="sd"> Returns:</span>
<span class="sd"> lockstring (str): The matched lockstring, or the full</span>
<span class="sd"> lockstring if no access_type was given.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">access_type</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">locks</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">access_type</span><span class="p">,</span> <span class="p">[</span><span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">])[</span><span class="mi">2</span><span class="p">]</span>
<span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span></div>
<div class="viewcode-block" id="LockHandler.all"><a class="viewcode-back" href="../../../api/evennia.locks.lockhandler.html#evennia.locks.lockhandler.LockHandler.all">[docs]</a> <span class="k">def</span> <span class="nf">all</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Return all lockstrings</span>
<span class="sd"> Returns:</span>
<span class="sd"> lockstrings (list): All separate lockstrings</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s2">&quot;;&quot;</span><span class="p">)</span></div>
<div class="viewcode-block" id="LockHandler.remove"><a class="viewcode-back" href="../../../api/evennia.locks.lockhandler.html#evennia.locks.lockhandler.LockHandler.remove">[docs]</a> <span class="k">def</span> <span class="nf">remove</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">access_type</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Remove a particular lock from the handler</span>
<span class="sd"> Args:</span>
<span class="sd"> access_type (str): The type of lock to remove.</span>
<span class="sd"> Returns:</span>
<span class="sd"> success (bool): If the access_type was not found</span>
<span class="sd"> in the lock, this returns `False`.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">access_type</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">locks</span><span class="p">:</span>
<span class="k">del</span> <span class="bp">self</span><span class="o">.</span><span class="n">locks</span><span class="p">[</span><span class="n">access_type</span><span class="p">]</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_save_locks</span><span class="p">()</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">return</span> <span class="kc">False</span></div>
<span class="n">delete</span> <span class="o">=</span> <span class="n">remove</span> <span class="c1"># alias for historical reasons</span>
<div class="viewcode-block" id="LockHandler.clear"><a class="viewcode-back" href="../../../api/evennia.locks.lockhandler.html#evennia.locks.lockhandler.LockHandler.clear">[docs]</a> <span class="k">def</span> <span class="nf">clear</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Remove all locks in the handler.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">locks</span> <span class="o">=</span> <span class="p">{}</span>
<span class="bp">self</span><span class="o">.</span><span class="n">lock_storage</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_save_locks</span><span class="p">()</span></div>
<div class="viewcode-block" id="LockHandler.reset"><a class="viewcode-back" href="../../../api/evennia.locks.lockhandler.html#evennia.locks.lockhandler.LockHandler.reset">[docs]</a> <span class="k">def</span> <span class="nf">reset</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Set the reset flag, so the the lock will be re-cached at next</span>
<span class="sd"> checking. This is usually called by @reload.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_cache_locks</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="o">.</span><span class="n">lock_storage</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cache_lock_bypass</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="p">)</span></div>
<div class="viewcode-block" id="LockHandler.append"><a class="viewcode-back" href="../../../api/evennia.locks.lockhandler.html#evennia.locks.lockhandler.LockHandler.append">[docs]</a> <span class="k">def</span> <span class="nf">append</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">access_type</span><span class="p">,</span> <span class="n">lockstring</span><span class="p">,</span> <span class="n">op</span><span class="o">=</span><span class="s2">&quot;or&quot;</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Append a lock definition to access_type if it doesn&#39;t already exist.</span>
<span class="sd"> Args:</span>
<span class="sd"> access_type (str): Access type.</span>
<span class="sd"> lockstring (str): A valid lockstring, without the operator to</span>
<span class="sd"> link it to an eventual existing lockstring.</span>
<span class="sd"> op (str): An operator &#39;and&#39;, &#39;or&#39;, &#39;and not&#39;, &#39;or not&#39; used</span>
<span class="sd"> for appending the lockstring to an existing access-type.</span>
<span class="sd"> Note:</span>
<span class="sd"> The most common use of this method is for use in commands where</span>
<span class="sd"> the user can specify their own lockstrings. This method allows</span>
<span class="sd"> the system to auto-add things like Admin-override access.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">old_lockstring</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">access_type</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">lockstring</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="ow">in</span> <span class="n">old_lockstring</span><span class="o">.</span><span class="n">lower</span><span class="p">():</span>
<span class="n">lockstring</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">{old}</span><span class="s2"> </span><span class="si">{op}</span><span class="s2"> </span><span class="si">{new}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span>
<span class="n">old</span><span class="o">=</span><span class="n">old_lockstring</span><span class="p">,</span> <span class="n">op</span><span class="o">=</span><span class="n">op</span><span class="p">,</span> <span class="n">new</span><span class="o">=</span><span class="n">lockstring</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">lockstring</span><span class="p">)</span></div>
<div class="viewcode-block" id="LockHandler.check"><a class="viewcode-back" href="../../../api/evennia.locks.lockhandler.html#evennia.locks.lockhandler.LockHandler.check">[docs]</a> <span class="k">def</span> <span class="nf">check</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">accessing_obj</span><span class="p">,</span> <span class="n">access_type</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">no_superuser_bypass</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Checks a lock of the correct type by passing execution off to</span>
<span class="sd"> the lock function(s).</span>
<span class="sd"> Args:</span>
<span class="sd"> accessing_obj (object): The object seeking access.</span>
<span class="sd"> access_type (str): The type of access wanted.</span>
<span class="sd"> default (bool, optional): If no suitable lock type is</span>
<span class="sd"> found, default to this result.</span>
<span class="sd"> no_superuser_bypass (bool): Don&#39;t use this unless you</span>
<span class="sd"> really, really need to, it makes supersusers susceptible</span>
<span class="sd"> to the lock check.</span>
<span class="sd"> Notes:</span>
<span class="sd"> A lock is executed in the follwoing way:</span>
<span class="sd"> Parsing the lockstring, we (during cache) extract the valid</span>
<span class="sd"> lock functions and store their function objects in the right</span>
<span class="sd"> order along with their args/kwargs. These are now executed in</span>
<span class="sd"> sequence, creating a list of True/False values. This is put</span>
<span class="sd"> into the evalstring, which is a string of AND/OR/NOT entries</span>
<span class="sd"> separated by placeholders where each function result should</span>
<span class="sd"> go. We just put those results in and evaluate the string to</span>
<span class="sd"> get a final, combined True/False value for the lockstring.</span>
<span class="sd"> The important bit with this solution is that the full</span>
<span class="sd"> lockstring is never blindly evaluated, and thus there (should</span>
<span class="sd"> be) no way to sneak in malign code in it. Only &quot;safe&quot; lock</span>
<span class="sd"> functions (as defined by your settings) are executed.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">try</span><span class="p">:</span>
<span class="c1"># check if the lock should be bypassed (e.g. superuser status)</span>
<span class="k">if</span> <span class="n">accessing_obj</span><span class="o">.</span><span class="n">locks</span><span class="o">.</span><span class="n">lock_bypass</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">no_superuser_bypass</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
<span class="c1"># happens before session is initiated.</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">no_superuser_bypass</span> <span class="ow">and</span> <span class="p">(</span>
<span class="p">(</span><span class="nb">hasattr</span><span class="p">(</span><span class="n">accessing_obj</span><span class="p">,</span> <span class="s2">&quot;is_superuser&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="n">accessing_obj</span><span class="o">.</span><span class="n">is_superuser</span><span class="p">)</span>
<span class="ow">or</span> <span class="p">(</span>
<span class="n">utils</span><span class="o">.</span><span class="n">inherits_from</span><span class="p">(</span><span class="n">accessing_obj</span><span class="p">,</span> <span class="n">evennia</span><span class="o">.</span><span class="n">DefaultObject</span><span class="p">)</span>
<span class="ow">and</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">accessing_obj</span><span class="o">.</span><span class="n">account</span><span class="p">,</span> <span class="s2">&quot;is_superuser&quot;</span><span class="p">)</span>
<span class="ow">and</span> <span class="n">accessing_obj</span><span class="o">.</span><span class="n">account</span><span class="o">.</span><span class="n">is_superuser</span>
<span class="p">)</span>
<span class="ow">or</span> <span class="p">(</span>
<span class="nb">hasattr</span><span class="p">(</span><span class="n">accessing_obj</span><span class="p">,</span> <span class="s2">&quot;get_account&quot;</span><span class="p">)</span>
<span class="ow">and</span> <span class="p">(</span>
<span class="ow">not</span> <span class="n">accessing_obj</span><span class="o">.</span><span class="n">get_account</span><span class="p">()</span> <span class="ow">or</span> <span class="n">accessing_obj</span><span class="o">.</span><span class="n">get_account</span><span class="p">()</span><span class="o">.</span><span class="n">is_superuser</span>
<span class="p">)</span>
<span class="p">)</span>
<span class="p">):</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="c1"># no superuser or bypass -&gt; normal lock operation</span>
<span class="k">if</span> <span class="n">access_type</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">locks</span><span class="p">:</span>
<span class="c1"># we have a lock, test it.</span>
<span class="n">evalstring</span><span class="p">,</span> <span class="n">func_tup</span><span class="p">,</span> <span class="n">raw_string</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">locks</span><span class="p">[</span><span class="n">access_type</span><span class="p">]</span>
<span class="c1"># execute all lock funcs in the correct order, producing a tuple of True/False results.</span>
<span class="n">true_false</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span>
<span class="nb">bool</span><span class="p">(</span><span class="n">tup</span><span class="p">[</span><span class="mi">0</span><span class="p">](</span><span class="n">accessing_obj</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="p">,</span> <span class="o">*</span><span class="n">tup</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">access_type</span><span class="o">=</span><span class="n">access_type</span><span class="p">,</span> <span class="o">**</span><span class="n">tup</span><span class="p">[</span><span class="mi">2</span><span class="p">]))</span>
<span class="k">for</span> <span class="n">tup</span> <span class="ow">in</span> <span class="n">func_tup</span>
<span class="p">)</span>
<span class="c1"># the True/False tuple goes into evalstring, which combines them</span>
<span class="c1"># with AND/OR/NOT in order to get the final result.</span>
<span class="k">return</span> <span class="nb">eval</span><span class="p">(</span><span class="n">evalstring</span> <span class="o">%</span> <span class="n">true_false</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="n">default</span></div>
<span class="k">def</span> <span class="nf">_eval_access_type</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">accessing_obj</span><span class="p">,</span> <span class="n">locks</span><span class="p">,</span> <span class="n">access_type</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Helper method for evaluating the access type using eval().</span>
<span class="sd"> Args:</span>
<span class="sd"> accessing_obj (object): Object seeking access.</span>
<span class="sd"> locks (dict): The pre-parsed representation of all access-types.</span>
<span class="sd"> access_type (str): An access-type key to evaluate.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">evalstring</span><span class="p">,</span> <span class="n">func_tup</span><span class="p">,</span> <span class="n">raw_string</span> <span class="o">=</span> <span class="n">locks</span><span class="p">[</span><span class="n">access_type</span><span class="p">]</span>
<span class="n">true_false</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">(</span><span class="n">tup</span><span class="p">[</span><span class="mi">0</span><span class="p">](</span><span class="n">accessing_obj</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">obj</span><span class="p">,</span> <span class="o">*</span><span class="n">tup</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="o">**</span><span class="n">tup</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span> <span class="k">for</span> <span class="n">tup</span> <span class="ow">in</span> <span class="n">func_tup</span><span class="p">)</span>
<span class="k">return</span> <span class="nb">eval</span><span class="p">(</span><span class="n">evalstring</span> <span class="o">%</span> <span class="n">true_false</span><span class="p">)</span>
<div class="viewcode-block" id="LockHandler.check_lockstring"><a class="viewcode-back" href="../../../api/evennia.locks.lockhandler.html#evennia.locks.lockhandler.LockHandler.check_lockstring">[docs]</a> <span class="k">def</span> <span class="nf">check_lockstring</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span> <span class="n">accessing_obj</span><span class="p">,</span> <span class="n">lockstring</span><span class="p">,</span> <span class="n">no_superuser_bypass</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">access_type</span><span class="o">=</span><span class="kc">None</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Do a direct check against a lockstring (&#39;atype:func()..&#39;),</span>
<span class="sd"> without any intermediary storage on the accessed object.</span>
<span class="sd"> Args:</span>
<span class="sd"> accessing_obj (object or None): The object seeking access.</span>
<span class="sd"> Importantly, this can be left unset if the lock functions</span>
<span class="sd"> don&#39;t access it, no updating or storage of locks are made</span>
<span class="sd"> against this object in this method.</span>
<span class="sd"> lockstring (str): Lock string to check, on the form</span>
<span class="sd"> `&quot;access_type:lock_definition&quot;` where the `access_type`</span>
<span class="sd"> part can potentially be set to a dummy value to just check</span>
<span class="sd"> a lock condition.</span>
<span class="sd"> no_superuser_bypass (bool, optional): Force superusers to heed lock.</span>
<span class="sd"> default (bool, optional): Fallback result to use if `access_type` is set</span>
<span class="sd"> but no such `access_type` is found in the given `lockstring`.</span>
<span class="sd"> access_type (str, bool): If set, only this access_type will be looked up</span>
<span class="sd"> among the locks defined by `lockstring`.</span>
<span class="sd"> Return:</span>
<span class="sd"> access (bool): If check is passed or not.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">if</span> <span class="n">accessing_obj</span><span class="o">.</span><span class="n">locks</span><span class="o">.</span><span class="n">lock_bypass</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">no_superuser_bypass</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">except</span> <span class="ne">AttributeError</span><span class="p">:</span>
<span class="k">if</span> <span class="n">no_superuser_bypass</span> <span class="ow">and</span> <span class="p">(</span>
<span class="p">(</span><span class="nb">hasattr</span><span class="p">(</span><span class="n">accessing_obj</span><span class="p">,</span> <span class="s2">&quot;is_superuser&quot;</span><span class="p">)</span> <span class="ow">and</span> <span class="n">accessing_obj</span><span class="o">.</span><span class="n">is_superuser</span><span class="p">)</span>
<span class="ow">or</span> <span class="p">(</span>
<span class="n">utils</span><span class="o">.</span><span class="n">inherits_from</span><span class="p">(</span><span class="n">accessing_obj</span><span class="p">,</span> <span class="n">evennia</span><span class="o">.</span><span class="n">DefaultObject</span><span class="p">)</span>
<span class="ow">and</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">accessing_obj</span><span class="o">.</span><span class="n">account</span><span class="p">,</span> <span class="s2">&quot;is_superuser&quot;</span><span class="p">)</span>
<span class="ow">and</span> <span class="n">accessing_obj</span><span class="o">.</span><span class="n">account</span><span class="o">.</span><span class="n">is_superuser</span>
<span class="p">)</span>
<span class="ow">or</span> <span class="p">(</span>
<span class="nb">hasattr</span><span class="p">(</span><span class="n">accessing_obj</span><span class="p">,</span> <span class="s2">&quot;get_account&quot;</span><span class="p">)</span>
<span class="ow">and</span> <span class="p">(</span>
<span class="ow">not</span> <span class="n">accessing_obj</span><span class="o">.</span><span class="n">get_account</span><span class="p">()</span> <span class="ow">or</span> <span class="n">accessing_obj</span><span class="o">.</span><span class="n">get_account</span><span class="p">()</span><span class="o">.</span><span class="n">is_superuser</span>
<span class="p">)</span>
<span class="p">)</span>
<span class="p">):</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">if</span> <span class="s2">&quot;:&quot;</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">lockstring</span><span class="p">:</span>
<span class="n">lockstring</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="si">%s</span><span class="s2">:</span><span class="si">%s</span><span class="s2">&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="s2">&quot;_dummy&quot;</span><span class="p">,</span> <span class="n">lockstring</span><span class="p">)</span>
<span class="n">locks</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_parse_lockstring</span><span class="p">(</span><span class="n">lockstring</span><span class="p">)</span>
<span class="k">if</span> <span class="n">access_type</span><span class="p">:</span>
<span class="k">if</span> <span class="n">access_type</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">locks</span><span class="p">:</span>
<span class="k">return</span> <span class="n">default</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_eval_access_type</span><span class="p">(</span><span class="n">accessing_obj</span><span class="p">,</span> <span class="n">locks</span><span class="p">,</span> <span class="n">access_type</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="c1"># if no access types was given and multiple locks were</span>
<span class="c1"># embedded in the lockstring we assume all must be true</span>
<span class="k">return</span> <span class="nb">all</span><span class="p">(</span>
<span class="bp">self</span><span class="o">.</span><span class="n">_eval_access_type</span><span class="p">(</span><span class="n">accessing_obj</span><span class="p">,</span> <span class="n">locks</span><span class="p">,</span> <span class="n">access_type</span><span class="p">)</span> <span class="k">for</span> <span class="n">access_type</span> <span class="ow">in</span> <span class="n">locks</span>
<span class="p">)</span></div></div>
<span class="c1"># convenience access function</span>
<span class="c1"># dummy to be able to call check_lockstring from the outside</span>
<span class="k">class</span> <span class="nc">_ObjDummy</span><span class="p">:</span>
<span class="n">lock_storage</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="k">def</span> <span class="nf">check_lockstring</span><span class="p">(</span>
<span class="n">accessing_obj</span><span class="p">,</span> <span class="n">lockstring</span><span class="p">,</span> <span class="n">no_superuser_bypass</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="kc">False</span><span class="p">,</span> <span class="n">access_type</span><span class="o">=</span><span class="kc">None</span>
<span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Do a direct check against a lockstring (&#39;atype:func()..&#39;),</span>
<span class="sd"> without any intermediary storage on the accessed object.</span>
<span class="sd"> Args:</span>
<span class="sd"> accessing_obj (object or None): The object seeking access.</span>
<span class="sd"> Importantly, this can be left unset if the lock functions</span>
<span class="sd"> don&#39;t access it, no updating or storage of locks are made</span>
<span class="sd"> against this object in this method.</span>
<span class="sd"> lockstring (str): Lock string to check, on the form</span>
<span class="sd"> `&quot;access_type:lock_definition&quot;` where the `access_type`</span>
<span class="sd"> part can potentially be set to a dummy value to just check</span>
<span class="sd"> a lock condition.</span>
<span class="sd"> no_superuser_bypass (bool, optional): Force superusers to heed lock.</span>
<span class="sd"> default (bool, optional): Fallback result to use if `access_type` is set</span>
<span class="sd"> but no such `access_type` is found in the given `lockstring`.</span>
<span class="sd"> access_type (str, bool): If set, only this access_type will be looked up</span>
<span class="sd"> among the locks defined by `lockstring`.</span>
<span class="sd"> Return:</span>
<span class="sd"> access (bool): If check is passed or not.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">global</span> <span class="n">_LOCK_HANDLER</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">_LOCK_HANDLER</span><span class="p">:</span>
<span class="n">_LOCK_HANDLER</span> <span class="o">=</span> <span class="n">LockHandler</span><span class="p">(</span><span class="n">_ObjDummy</span><span class="p">())</span>
<span class="k">return</span> <span class="n">_LOCK_HANDLER</span><span class="o">.</span><span class="n">check_lockstring</span><span class="p">(</span>
<span class="n">accessing_obj</span><span class="p">,</span>
<span class="n">lockstring</span><span class="p">,</span>
<span class="n">no_superuser_bypass</span><span class="o">=</span><span class="n">no_superuser_bypass</span><span class="p">,</span>
<span class="n">default</span><span class="o">=</span><span class="n">default</span><span class="p">,</span>
<span class="n">access_type</span><span class="o">=</span><span class="n">access_type</span><span class="p">,</span>
<span class="p">)</span>
<span class="k">def</span> <span class="nf">check_perm</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="n">permission</span><span class="p">,</span> <span class="n">no_superuser_bypass</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Shortcut for checking if an object has the given `permission`. If the</span>
<span class="sd"> permission is in `settings.PERMISSION_HIERARCHY`, the check passes</span>
<span class="sd"> if the object has this permission or higher.</span>
<span class="sd"> This is equivalent to calling the perm() lockfunc, but without needing</span>
<span class="sd"> an accessed object.</span>
<span class="sd"> Args:</span>
<span class="sd"> obj (Object, Account): The object to check access. If this has a linked</span>
<span class="sd"> Account, the account is checked instead (same rules as per perm()).</span>
<span class="sd"> permission (str): The permission string to check.</span>
<span class="sd"> no_superuser_bypass (bool, optional): If unset, the superuser</span>
<span class="sd"> will always pass this check.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="kn">from</span> <span class="nn">evennia.locks.lockfuncs</span> <span class="kn">import</span> <span class="n">perm</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">no_superuser_bypass</span> <span class="ow">and</span> <span class="n">obj</span><span class="o">.</span><span class="n">is_superuser</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="k">return</span> <span class="n">perm</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="n">permission</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">validate_lockstring</span><span class="p">(</span><span class="n">lockstring</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Validate so lockstring is on a valid form.</span>
<span class="sd"> Args:</span>
<span class="sd"> lockstring (str): Lockstring to validate.</span>
<span class="sd"> Returns:</span>
<span class="sd"> is_valid (bool): If the lockstring is valid or not.</span>
<span class="sd"> error (str or None): A string describing the error, or None</span>
<span class="sd"> if no error was found.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">global</span> <span class="n">_LOCK_HANDLER</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">_LOCK_HANDLER</span><span class="p">:</span>
<span class="n">_LOCK_HANDLER</span> <span class="o">=</span> <span class="n">LockHandler</span><span class="p">(</span><span class="n">_ObjDummy</span><span class="p">())</span>
<span class="k">return</span> <span class="n">_LOCK_HANDLER</span><span class="o">.</span><span class="n">validate</span><span class="p">(</span><span class="n">lockstring</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">get_all_lockfuncs</span><span class="p">():</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Get a dict of available lock funcs.</span>
<span class="sd"> Returns:</span>
<span class="sd"> lockfuncs (dict): Mapping {lockfuncname:func}.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">_LOCKFUNCS</span><span class="p">:</span>
<span class="n">_cache_lockfuncs</span><span class="p">()</span>
<span class="k">return</span> <span class="n">_LOCKFUNCS</span>
<span class="k">def</span> <span class="nf">_test</span><span class="p">():</span>
<span class="c1"># testing</span>
<span class="k">class</span> <span class="nc">TestObj</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">pass</span>
<span class="kn">import</span> <span class="nn">pdb</span>
<span class="n">obj1</span> <span class="o">=</span> <span class="n">TestObj</span><span class="p">()</span>
<span class="n">obj2</span> <span class="o">=</span> <span class="n">TestObj</span><span class="p">()</span>
<span class="c1"># obj1.lock_storage = &quot;owner:dbref(#4);edit:dbref(#5) or perm(Admin);examine:perm(Builder);delete:perm(Admin);get:all()&quot;</span>
<span class="c1"># obj1.lock_storage = &quot;cmd:all();admin:id(1);listen:all();send:all()&quot;</span>
<span class="n">obj1</span><span class="o">.</span><span class="n">lock_storage</span> <span class="o">=</span> <span class="s2">&quot;listen:perm(Developer)&quot;</span>
<span class="n">pdb</span><span class="o">.</span><span class="n">set_trace</span><span class="p">()</span>
<span class="n">obj1</span><span class="o">.</span><span class="n">locks</span> <span class="o">=</span> <span class="n">LockHandler</span><span class="p">(</span><span class="n">obj1</span><span class="p">)</span>
<span class="n">obj2</span><span class="o">.</span><span class="n">permissions</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="s2">&quot;Developer&quot;</span><span class="p">)</span>
<span class="n">obj2</span><span class="o">.</span><span class="n">id</span> <span class="o">=</span> <span class="mi">4</span>
<span class="c1"># obj1.locks.add(&quot;edit:attr(test)&quot;)</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">&quot;comparing obj2.permissions (</span><span class="si">%s</span><span class="s2">) vs obj1.locks (</span><span class="si">%s</span><span class="s2">)&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">obj2</span><span class="o">.</span><span class="n">permissions</span><span class="p">,</span> <span class="n">obj1</span><span class="o">.</span><span class="n">locks</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="n">obj1</span><span class="o">.</span><span class="n">locks</span><span class="o">.</span><span class="n">check</span><span class="p">(</span><span class="n">obj2</span><span class="p">,</span> <span class="s2">&quot;owner&quot;</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="n">obj1</span><span class="o">.</span><span class="n">locks</span><span class="o">.</span><span class="n">check</span><span class="p">(</span><span class="n">obj2</span><span class="p">,</span> <span class="s2">&quot;edit&quot;</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="n">obj1</span><span class="o">.</span><span class="n">locks</span><span class="o">.</span><span class="n">check</span><span class="p">(</span><span class="n">obj2</span><span class="p">,</span> <span class="s2">&quot;examine&quot;</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="n">obj1</span><span class="o">.</span><span class="n">locks</span><span class="o">.</span><span class="n">check</span><span class="p">(</span><span class="n">obj2</span><span class="p">,</span> <span class="s2">&quot;delete&quot;</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="n">obj1</span><span class="o">.</span><span class="n">locks</span><span class="o">.</span><span class="n">check</span><span class="p">(</span><span class="n">obj2</span><span class="p">,</span> <span class="s2">&quot;get&quot;</span><span class="p">))</span>
<span class="nb">print</span><span class="p">(</span><span class="n">obj1</span><span class="o">.</span><span class="n">locks</span><span class="o">.</span><span class="n">check</span><span class="p">(</span><span class="n">obj2</span><span class="p">,</span> <span class="s2">&quot;listen&quot;</span><span class="p">))</span>
</pre></div>
</div>
</div>
</div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../../../genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="../../../py-modindex.html" title="Python Module Index"
>modules</a> |</li>
<li class="nav-item nav-item-0"><a href="../../../index.html">Evennia latest</a> &#187;</li>
<li class="nav-item nav-item-1"><a href="../../index.html" >Module code</a> &#187;</li>
<li class="nav-item nav-item-2"><a href="../../evennia.html" >evennia</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">evennia.locks.lockhandler</a></li>
</ul>
</div>
<div class="footer" role="contentinfo">
&#169; Copyright 2024, The Evennia developer community.
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 3.2.1.
</div>
</body>
</html>