evennia/docs/versions/1.0-dev/_modules/evennia/contrib/email_login.html
2020-06-13 00:15:39 +02:00

448 lines
No EOL
44 KiB
HTML

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>evennia.contrib.email_login &#8212; Evennia 1.0-dev documentation</title>
<link rel="stylesheet" href="../../../_static/alabaster.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="index" title="Index" href="../../../genindex.html" />
<link rel="search" title="Search" href="../../../search.html" />
<link rel="stylesheet" href="../../../_static/custom.css" type="text/css" />
<meta name="viewport" content="width=device-width, initial-scale=0.9, maximum-scale=0.9" />
</head><body>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<h1>Source code for evennia.contrib.email_login</h1><div class="highlight"><pre>
<span></span><span class="sd">&quot;&quot;&quot;</span>
<span class="sd">Email-based login system</span>
<span class="sd">Evennia contrib - Griatch 2012</span>
<span class="sd">This is a variant of the login system that requires an email-address</span>
<span class="sd">instead of a username to login.</span>
<span class="sd">This used to be the default Evennia login before replacing it with a</span>
<span class="sd">more standard username + password system (having to supply an email</span>
<span class="sd">for some reason caused a lot of confusion when people wanted to expand</span>
<span class="sd">on it. The email is not strictly needed internally, nor is any</span>
<span class="sd">confirmation email sent out anyway).</span>
<span class="sd">Installation is simple:</span>
<span class="sd">To your settings file, add/edit the line:</span>
<span class="sd">```python</span>
<span class="sd">CMDSET_UNLOGGEDIN = &quot;contrib.email_login.UnloggedinCmdSet&quot;</span>
<span class="sd">```</span>
<span class="sd">That&#39;s it. Reload the server and try to log in to see it.</span>
<span class="sd">The initial login &quot;graphic&quot; will still not mention email addresses</span>
<span class="sd">after this change. The login splashscreen is taken from strings in</span>
<span class="sd">the module given by settings.CONNECTION_SCREEN_MODULE.</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="k">import</span> <span class="n">settings</span>
<span class="kn">from</span> <span class="nn">evennia.accounts.models</span> <span class="k">import</span> <span class="n">AccountDB</span>
<span class="kn">from</span> <span class="nn">evennia.objects.models</span> <span class="k">import</span> <span class="n">ObjectDB</span>
<span class="kn">from</span> <span class="nn">evennia.server.models</span> <span class="k">import</span> <span class="n">ServerConfig</span>
<span class="kn">from</span> <span class="nn">evennia.commands.cmdset</span> <span class="k">import</span> <span class="n">CmdSet</span>
<span class="kn">from</span> <span class="nn">evennia.utils</span> <span class="k">import</span> <span class="n">logger</span><span class="p">,</span> <span class="n">utils</span><span class="p">,</span> <span class="n">ansi</span>
<span class="kn">from</span> <span class="nn">evennia.commands.default.muxcommand</span> <span class="k">import</span> <span class="n">MuxCommand</span>
<span class="kn">from</span> <span class="nn">evennia.commands.cmdhandler</span> <span class="k">import</span> <span class="n">CMD_LOGINSTART</span>
<span class="kn">from</span> <span class="nn">evennia.commands.default</span> <span class="k">import</span> <span class="p">(</span>
<span class="n">unloggedin</span> <span class="k">as</span> <span class="n">default_unloggedin</span><span class="p">,</span>
<span class="p">)</span> <span class="c1"># Used in CmdUnconnectedCreate</span>
<span class="c1"># limit symbol import for API</span>
<span class="n">__all__</span> <span class="o">=</span> <span class="p">(</span>
<span class="s2">&quot;CmdUnconnectedConnect&quot;</span><span class="p">,</span>
<span class="s2">&quot;CmdUnconnectedCreate&quot;</span><span class="p">,</span>
<span class="s2">&quot;CmdUnconnectedQuit&quot;</span><span class="p">,</span>
<span class="s2">&quot;CmdUnconnectedLook&quot;</span><span class="p">,</span>
<span class="s2">&quot;CmdUnconnectedHelp&quot;</span><span class="p">,</span>
<span class="p">)</span>
<span class="n">MULTISESSION_MODE</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">MULTISESSION_MODE</span>
<span class="n">CONNECTION_SCREEN_MODULE</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">CONNECTION_SCREEN_MODULE</span>
<span class="n">CONNECTION_SCREEN</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">CONNECTION_SCREEN</span> <span class="o">=</span> <span class="n">ansi</span><span class="o">.</span><span class="n">parse_ansi</span><span class="p">(</span><span class="n">utils</span><span class="o">.</span><span class="n">random_string_from_module</span><span class="p">(</span><span class="n">CONNECTION_SCREEN_MODULE</span><span class="p">))</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="c1"># malformed connection screen or no screen given</span>
<span class="k">pass</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">CONNECTION_SCREEN</span><span class="p">:</span>
<span class="n">CONNECTION_SCREEN</span> <span class="o">=</span> <span class="p">(</span>
<span class="s2">&quot;</span><span class="se">\n</span><span class="s2">Evennia: Error in CONNECTION_SCREEN MODULE&quot;</span>
<span class="s2">&quot; (randomly picked connection screen variable is not a string). </span><span class="se">\n</span><span class="s2">Enter &#39;help&#39; for aid.&quot;</span>
<span class="p">)</span>
<div class="viewcode-block" id="CmdUnconnectedConnect"><a class="viewcode-back" href="../../../api/evennia.contrib.html#evennia.contrib.email_login.CmdUnconnectedConnect">[docs]</a><span class="k">class</span> <span class="nc">CmdUnconnectedConnect</span><span class="p">(</span><span class="n">MuxCommand</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Connect to the game.</span>
<span class="sd"> Usage (at login screen):</span>
<span class="sd"> connect &lt;email&gt; &lt;password&gt;</span>
<span class="sd"> Use the create command to first create an account before logging in.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;connect&quot;</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;conn&quot;</span><span class="p">,</span> <span class="s2">&quot;con&quot;</span><span class="p">,</span> <span class="s2">&quot;co&quot;</span><span class="p">]</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:all()&quot;</span> <span class="c1"># not really needed</span>
<div class="viewcode-block" id="CmdUnconnectedConnect.func"><a class="viewcode-back" href="../../../api/evennia.contrib.html#evennia.contrib.email_login.CmdUnconnectedConnect.func">[docs]</a> <span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Uses the Django admin api. Note that unlogged-in commands</span>
<span class="sd"> have a unique position in that their `func()` receives</span>
<span class="sd"> a session object instead of a `source_object` like all</span>
<span class="sd"> other types of logged-in commands (this is because</span>
<span class="sd"> there is no object yet before the account has logged in)</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">session</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span>
<span class="n">arglist</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">arglist</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">arglist</span> <span class="ow">or</span> <span class="nb">len</span><span class="p">(</span><span class="n">arglist</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">2</span><span class="p">:</span>
<span class="n">session</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n\r</span><span class="s2"> Usage (without &lt;&gt;): connect &lt;email&gt; &lt;password&gt;&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="n">email</span> <span class="o">=</span> <span class="n">arglist</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">password</span> <span class="o">=</span> <span class="n">arglist</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<span class="c1"># Match an email address to an account.</span>
<span class="n">account</span> <span class="o">=</span> <span class="n">AccountDB</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get_account_from_email</span><span class="p">(</span><span class="n">email</span><span class="p">)</span>
<span class="c1"># No accountname match</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">account</span><span class="p">:</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;The email &#39;</span><span class="si">%s</span><span class="s2">&#39; does not match any accounts.&quot;</span> <span class="o">%</span> <span class="n">email</span>
<span class="n">string</span> <span class="o">+=</span> <span class="s2">&quot;</span><span class="se">\n\r\n\r</span><span class="s2">If you are new you should first create a new account &quot;</span>
<span class="n">string</span> <span class="o">+=</span> <span class="s2">&quot;using the &#39;create&#39; command.&quot;</span>
<span class="n">session</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
<span class="k">return</span>
<span class="c1"># We have at least one result, so we can check the password.</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">account</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">check_password</span><span class="p">(</span><span class="n">password</span><span class="p">):</span>
<span class="n">session</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Incorrect password.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="c1"># Check IP and/or name bans</span>
<span class="n">bans</span> <span class="o">=</span> <span class="n">ServerConfig</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">conf</span><span class="p">(</span><span class="s2">&quot;server_bans&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">bans</span> <span class="ow">and</span> <span class="p">(</span>
<span class="nb">any</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="o">==</span> <span class="n">account</span><span class="o">.</span><span class="n">name</span> <span class="k">for</span> <span class="n">tup</span> <span class="ow">in</span> <span class="n">bans</span><span class="p">)</span>
<span class="ow">or</span> <span class="nb">any</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="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">session</span><span class="o">.</span><span class="n">address</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="k">for</span> <span class="n">tup</span> <span class="ow">in</span> <span class="n">bans</span> <span class="k">if</span> <span class="n">tup</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
<span class="p">):</span>
<span class="c1"># this is a banned IP or name!</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;|rYou have been banned and cannot continue from here.&quot;</span>
<span class="n">string</span> <span class="o">+=</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">If you feel this ban is in error, please email an admin.|x&quot;</span>
<span class="n">session</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
<span class="n">session</span><span class="o">.</span><span class="n">execute_cmd</span><span class="p">(</span><span class="s2">&quot;quit&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="c1"># actually do the login. This will call all hooks.</span>
<span class="n">session</span><span class="o">.</span><span class="n">sessionhandler</span><span class="o">.</span><span class="n">login</span><span class="p">(</span><span class="n">session</span><span class="p">,</span> <span class="n">account</span><span class="p">)</span></div></div>
<div class="viewcode-block" id="CmdUnconnectedCreate"><a class="viewcode-back" href="../../../api/evennia.contrib.html#evennia.contrib.email_login.CmdUnconnectedCreate">[docs]</a><span class="k">class</span> <span class="nc">CmdUnconnectedCreate</span><span class="p">(</span><span class="n">MuxCommand</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Create a new account.</span>
<span class="sd"> Usage (at login screen):</span>
<span class="sd"> create \&quot;accountname\&quot; &lt;email&gt; &lt;password&gt;</span>
<span class="sd"> This creates a new account account.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;create&quot;</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;cre&quot;</span><span class="p">,</span> <span class="s2">&quot;cr&quot;</span><span class="p">]</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:all()&quot;</span>
<div class="viewcode-block" id="CmdUnconnectedCreate.parse"><a class="viewcode-back" href="../../../api/evennia.contrib.html#evennia.contrib.email_login.CmdUnconnectedCreate.parse">[docs]</a> <span class="k">def</span> <span class="nf">parse</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> The parser must handle the multiple-word account</span>
<span class="sd"> name enclosed in quotes:</span>
<span class="sd"> connect &quot;Long name with many words&quot; my@myserv.com mypassw</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">parse</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">accountinfo</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">arglist</span><span class="p">)</span> <span class="o">&lt;</span> <span class="mi">3</span><span class="p">:</span>
<span class="k">return</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">arglist</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">3</span><span class="p">:</span>
<span class="c1"># this means we have a multi_word accountname. pop from the back.</span>
<span class="n">password</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">arglist</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
<span class="n">email</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">arglist</span><span class="o">.</span><span class="n">pop</span><span class="p">()</span>
<span class="c1"># what remains is the accountname.</span>
<span class="n">accountname</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="bp">self</span><span class="o">.</span><span class="n">arglist</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">accountname</span><span class="p">,</span> <span class="n">email</span><span class="p">,</span> <span class="n">password</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">arglist</span>
<span class="n">accountname</span> <span class="o">=</span> <span class="n">accountname</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s1">&#39;&quot;&#39;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span> <span class="c1"># remove &quot;</span>
<span class="n">accountname</span> <span class="o">=</span> <span class="n">accountname</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s2">&quot;&#39;&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">accountinfo</span> <span class="o">=</span> <span class="p">(</span><span class="n">accountname</span><span class="p">,</span> <span class="n">email</span><span class="p">,</span> <span class="n">password</span><span class="p">)</span></div>
<div class="viewcode-block" id="CmdUnconnectedCreate.func"><a class="viewcode-back" href="../../../api/evennia.contrib.html#evennia.contrib.email_login.CmdUnconnectedCreate.func">[docs]</a> <span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Do checks and create account&quot;&quot;&quot;</span>
<span class="n">session</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">accountname</span><span class="p">,</span> <span class="n">email</span><span class="p">,</span> <span class="n">password</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">accountinfo</span>
<span class="k">except</span> <span class="ne">ValueError</span><span class="p">:</span>
<span class="n">string</span> <span class="o">=</span> <span class="s1">&#39;</span><span class="se">\n\r</span><span class="s1"> Usage (without &lt;&gt;): create &quot;&lt;accountname&gt;&quot; &lt;email&gt; &lt;password&gt;&#39;</span>
<span class="n">session</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">email</span> <span class="ow">or</span> <span class="ow">not</span> <span class="n">password</span><span class="p">:</span>
<span class="n">session</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;</span><span class="se">\n\r</span><span class="s2"> You have to supply an e-mail address followed by a password.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">utils</span><span class="o">.</span><span class="n">validate_email_address</span><span class="p">(</span><span class="n">email</span><span class="p">):</span>
<span class="c1"># check so the email at least looks ok.</span>
<span class="n">session</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;&#39;</span><span class="si">%s</span><span class="s2">&#39; is not a valid e-mail address.&quot;</span> <span class="o">%</span> <span class="n">email</span><span class="p">)</span>
<span class="k">return</span>
<span class="c1"># sanity checks</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">re</span><span class="o">.</span><span class="n">findall</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;^[\w. @+\-&#39;]+$&quot;</span><span class="p">,</span> <span class="n">accountname</span><span class="p">)</span> <span class="ow">or</span> <span class="ow">not</span> <span class="p">(</span><span class="mi">0</span> <span class="o">&lt;</span> <span class="nb">len</span><span class="p">(</span><span class="n">accountname</span><span class="p">)</span> <span class="o">&lt;=</span> <span class="mi">30</span><span class="p">):</span>
<span class="c1"># this echoes the restrictions made by django&#39;s auth</span>
<span class="c1"># module (except not allowing spaces, for convenience of</span>
<span class="c1"># logging in).</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="se">\n\r</span><span class="s2"> Accountname can max be 30 characters or fewer. Letters, spaces, digits and @/./+/-/_/&#39; only.&quot;</span>
<span class="n">session</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
<span class="k">return</span>
<span class="c1"># strip excessive spaces in accountname</span>
<span class="n">accountname</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;\s+&quot;</span><span class="p">,</span> <span class="s2">&quot; &quot;</span><span class="p">,</span> <span class="n">accountname</span><span class="p">)</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span>
<span class="k">if</span> <span class="n">AccountDB</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">filter</span><span class="p">(</span><span class="n">username__iexact</span><span class="o">=</span><span class="n">accountname</span><span class="p">):</span>
<span class="c1"># account already exists (we also ignore capitalization here)</span>
<span class="n">session</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Sorry, there is already an account with the name &#39;</span><span class="si">%s</span><span class="s2">&#39;.&quot;</span> <span class="o">%</span> <span class="n">accountname</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="n">AccountDB</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get_account_from_email</span><span class="p">(</span><span class="n">email</span><span class="p">):</span>
<span class="c1"># email already set on an account</span>
<span class="n">session</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;Sorry, there is already an account with that email address.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="c1"># Reserve accountnames found in GUEST_LIST</span>
<span class="k">if</span> <span class="n">settings</span><span class="o">.</span><span class="n">GUEST_LIST</span> <span class="ow">and</span> <span class="n">accountname</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="ow">in</span> <span class="p">(</span>
<span class="n">guest</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="k">for</span> <span class="n">guest</span> <span class="ow">in</span> <span class="n">settings</span><span class="o">.</span><span class="n">GUEST_LIST</span>
<span class="p">):</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="se">\n\r</span><span class="s2"> That name is reserved. Please choose another Accountname.&quot;</span>
<span class="n">session</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
<span class="k">return</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">re</span><span class="o">.</span><span class="n">findall</span><span class="p">(</span><span class="sa">r</span><span class="s2">&quot;^[\w. @+\-&#39;]+$&quot;</span><span class="p">,</span> <span class="n">password</span><span class="p">)</span> <span class="ow">or</span> <span class="ow">not</span> <span class="p">(</span><span class="mi">3</span> <span class="o">&lt;</span> <span class="nb">len</span><span class="p">(</span><span class="n">password</span><span class="p">)):</span>
<span class="n">string</span> <span class="o">=</span> <span class="p">(</span>
<span class="s2">&quot;</span><span class="se">\n\r</span><span class="s2"> Password should be longer than 3 characters. Letters, spaces, digits and @/./+/-/_/&#39; only.&quot;</span>
<span class="s2">&quot;</span><span class="se">\n</span><span class="s2">For best security, make it longer than 8 characters. You can also use a phrase of&quot;</span>
<span class="s2">&quot;</span><span class="se">\n</span><span class="s2">many words if you enclose the password in double quotes.&quot;</span>
<span class="p">)</span>
<span class="n">session</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
<span class="k">return</span>
<span class="c1"># Check IP and/or name bans</span>
<span class="n">bans</span> <span class="o">=</span> <span class="n">ServerConfig</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">conf</span><span class="p">(</span><span class="s2">&quot;server_bans&quot;</span><span class="p">)</span>
<span class="k">if</span> <span class="n">bans</span> <span class="ow">and</span> <span class="p">(</span>
<span class="nb">any</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="o">==</span> <span class="n">accountname</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span> <span class="k">for</span> <span class="n">tup</span> <span class="ow">in</span> <span class="n">bans</span><span class="p">)</span>
<span class="ow">or</span> <span class="nb">any</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="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">session</span><span class="o">.</span><span class="n">address</span><span class="p">)</span> <span class="k">for</span> <span class="n">tup</span> <span class="ow">in</span> <span class="n">bans</span> <span class="k">if</span> <span class="n">tup</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
<span class="p">):</span>
<span class="c1"># this is a banned IP or name!</span>
<span class="n">string</span> <span class="o">=</span> <span class="p">(</span>
<span class="s2">&quot;|rYou have been banned and cannot continue from here.&quot;</span>
<span class="s2">&quot;</span><span class="se">\n</span><span class="s2">If you feel this ban is in error, please email an admin.|x&quot;</span>
<span class="p">)</span>
<span class="n">session</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">string</span><span class="p">)</span>
<span class="n">session</span><span class="o">.</span><span class="n">sessionhandler</span><span class="o">.</span><span class="n">disconnect</span><span class="p">(</span><span class="n">session</span><span class="p">,</span> <span class="s2">&quot;Good bye! Disconnecting.&quot;</span><span class="p">)</span>
<span class="k">return</span>
<span class="c1"># everything&#39;s ok. Create the new player account.</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">permissions</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">PERMISSION_ACCOUNT_DEFAULT</span>
<span class="n">typeclass</span> <span class="o">=</span> <span class="n">settings</span><span class="o">.</span><span class="n">BASE_CHARACTER_TYPECLASS</span>
<span class="n">new_account</span> <span class="o">=</span> <span class="n">default_unloggedin</span><span class="o">.</span><span class="n">_create_account</span><span class="p">(</span>
<span class="n">session</span><span class="p">,</span> <span class="n">accountname</span><span class="p">,</span> <span class="n">password</span><span class="p">,</span> <span class="n">permissions</span><span class="p">,</span> <span class="n">email</span><span class="o">=</span><span class="n">email</span>
<span class="p">)</span>
<span class="k">if</span> <span class="n">new_account</span><span class="p">:</span>
<span class="k">if</span> <span class="n">MULTISESSION_MODE</span> <span class="o">&lt;</span> <span class="mi">2</span><span class="p">:</span>
<span class="n">default_home</span> <span class="o">=</span> <span class="n">ObjectDB</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">get_id</span><span class="p">(</span><span class="n">settings</span><span class="o">.</span><span class="n">DEFAULT_HOME</span><span class="p">)</span>
<span class="n">default_unloggedin</span><span class="o">.</span><span class="n">_create_character</span><span class="p">(</span>
<span class="n">session</span><span class="p">,</span> <span class="n">new_account</span><span class="p">,</span> <span class="n">typeclass</span><span class="p">,</span> <span class="n">default_home</span><span class="p">,</span> <span class="n">permissions</span>
<span class="p">)</span>
<span class="c1"># tell the caller everything went well.</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;A new account &#39;</span><span class="si">%s</span><span class="s2">&#39; was created. Welcome!&quot;</span>
<span class="k">if</span> <span class="s2">&quot; &quot;</span> <span class="ow">in</span> <span class="n">accountname</span><span class="p">:</span>
<span class="n">string</span> <span class="o">+=</span> <span class="p">(</span>
<span class="s2">&quot;</span><span class="se">\n\n</span><span class="s2">You can now log in with the command &#39;connect </span><span class="se">\&quot;</span><span class="si">%s</span><span class="se">\&quot;</span><span class="s2"> &lt;your password&gt;&#39;.&quot;</span>
<span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">string</span> <span class="o">+=</span> <span class="s2">&quot;</span><span class="se">\n\n</span><span class="s2">You can now log with the command &#39;connect </span><span class="si">%s</span><span class="s2"> &lt;your password&gt;&#39;.&quot;</span>
<span class="n">session</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">string</span> <span class="o">%</span> <span class="p">(</span><span class="n">accountname</span><span class="p">,</span> <span class="n">email</span><span class="p">))</span>
<span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
<span class="c1"># We are in the middle between logged in and -not, so we have</span>
<span class="c1"># to handle tracebacks ourselves at this point. If we don&#39;t,</span>
<span class="c1"># we won&#39;t see any errors at all.</span>
<span class="n">session</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="s2">&quot;An error occurred. Please e-mail an admin if the problem persists.&quot;</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">raise</span></div></div>
<div class="viewcode-block" id="CmdUnconnectedQuit"><a class="viewcode-back" href="../../../api/evennia.contrib.html#evennia.contrib.email_login.CmdUnconnectedQuit">[docs]</a><span class="k">class</span> <span class="nc">CmdUnconnectedQuit</span><span class="p">(</span><span class="n">MuxCommand</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> We maintain a different version of the `quit` command</span>
<span class="sd"> here for unconnected accounts for the sake of simplicity. The logged in</span>
<span class="sd"> version is a bit more complicated.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;quit&quot;</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;q&quot;</span><span class="p">,</span> <span class="s2">&quot;qu&quot;</span><span class="p">]</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:all()&quot;</span>
<div class="viewcode-block" id="CmdUnconnectedQuit.func"><a class="viewcode-back" href="../../../api/evennia.contrib.html#evennia.contrib.email_login.CmdUnconnectedQuit.func">[docs]</a> <span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Simply close the connection.&quot;&quot;&quot;</span>
<span class="n">session</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">caller</span>
<span class="n">session</span><span class="o">.</span><span class="n">sessionhandler</span><span class="o">.</span><span class="n">disconnect</span><span class="p">(</span><span class="n">session</span><span class="p">,</span> <span class="s2">&quot;Good bye! Disconnecting.&quot;</span><span class="p">)</span></div></div>
<div class="viewcode-block" id="CmdUnconnectedLook"><a class="viewcode-back" href="../../../api/evennia.contrib.html#evennia.contrib.email_login.CmdUnconnectedLook">[docs]</a><span class="k">class</span> <span class="nc">CmdUnconnectedLook</span><span class="p">(</span><span class="n">MuxCommand</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> This is an unconnected version of the `look` command for simplicity.</span>
<span class="sd"> This is called by the server and kicks everything in gear.</span>
<span class="sd"> All it does is display the connect screen.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="n">CMD_LOGINSTART</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;look&quot;</span><span class="p">,</span> <span class="s2">&quot;l&quot;</span><span class="p">]</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:all()&quot;</span>
<div class="viewcode-block" id="CmdUnconnectedLook.func"><a class="viewcode-back" href="../../../api/evennia.contrib.html#evennia.contrib.email_login.CmdUnconnectedLook.func">[docs]</a> <span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Show the connect screen.&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">CONNECTION_SCREEN</span><span class="p">)</span></div></div>
<div class="viewcode-block" id="CmdUnconnectedHelp"><a class="viewcode-back" href="../../../api/evennia.contrib.html#evennia.contrib.email_login.CmdUnconnectedHelp">[docs]</a><span class="k">class</span> <span class="nc">CmdUnconnectedHelp</span><span class="p">(</span><span class="n">MuxCommand</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> This is an unconnected version of the help command,</span>
<span class="sd"> for simplicity. It shows a pane of info.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;help&quot;</span>
<span class="n">aliases</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;h&quot;</span><span class="p">,</span> <span class="s2">&quot;?&quot;</span><span class="p">]</span>
<span class="n">locks</span> <span class="o">=</span> <span class="s2">&quot;cmd:all()&quot;</span>
<div class="viewcode-block" id="CmdUnconnectedHelp.func"><a class="viewcode-back" href="../../../api/evennia.contrib.html#evennia.contrib.email_login.CmdUnconnectedHelp.func">[docs]</a> <span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Shows help&quot;&quot;&quot;</span>
<span class="n">string</span> <span class="o">=</span> <span class="s2">&quot;&quot;&quot;</span>
<span class="s2">You are not yet logged into the game. Commands available at this point:</span>
<span class="s2"> |wcreate, connect, look, help, quit|n</span>
<span class="s2">To login to the system, you need to do one of the following:</span>
<span class="s2">|w1)|n If you have no previous account, you need to use the &#39;create&#39;</span>
<span class="s2"> command like this:</span>
<span class="s2"> |wcreate &quot;Anna the Barbarian&quot; anna@myemail.com c67jHL8p|n</span>
<span class="s2"> It&#39;s always a good idea (not only here, but everywhere on the net)</span>
<span class="s2"> to not use a regular word for your password. Make it longer than</span>
<span class="s2"> 3 characters (ideally 6 or more) and mix numbers and capitalization</span>
<span class="s2"> into it.</span>
<span class="s2">|w2)|n If you have an account already, either because you just created</span>
<span class="s2"> one in |w1)|n above or you are returning, use the &#39;connect&#39; command:</span>
<span class="s2"> |wconnect anna@myemail.com c67jHL8p|n</span>
<span class="s2"> This should log you in. Run |whelp|n again once you&#39;re logged in</span>
<span class="s2"> to get more aid. Hope you enjoy your stay!</span>
<span class="s2">You can use the |wlook|n command if you want to see the connect screen again.</span>
<span class="s2">&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">caller</span><span class="o">.</span><span class="n">msg</span><span class="p">(</span><span class="n">string</span><span class="p">)</span></div></div>
<span class="c1"># command set for the mux-like login</span>
<span class="k">class</span> <span class="nc">UnloggedinCmdSet</span><span class="p">(</span><span class="n">CmdSet</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="sd"> Sets up the unlogged cmdset.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">key</span> <span class="o">=</span> <span class="s2">&quot;Unloggedin&quot;</span>
<span class="n">priority</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">def</span> <span class="nf">at_cmdset_creation</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="sd">&quot;&quot;&quot;Populate the cmdset&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">CmdUnconnectedConnect</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">CmdUnconnectedCreate</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">CmdUnconnectedQuit</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">CmdUnconnectedLook</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">CmdUnconnectedHelp</span><span class="p">())</span>
</pre></div>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<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><div class="relations">
<h3>Related Topics</h3>
<ul>
<li><a href="../../../index.html">Documentation overview</a><ul>
<li><a href="../../index.html">Module code</a><ul>
<li><a href="../../evennia.html">evennia</a><ul>
</ul></li>
</ul></li>
</ul></li>
</ul>
</div>
<h3>Versions</h3>
<ul>
<li><a href="email_login.html">1.0-dev (develop branch)</a></li>
<li><a href="../../../../../versions/0.9.1/index.html">0.9.1 (master branch)</a></li>
</ul>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="footer">
&copy;2020, The Evennia developer community.
|
Powered by <a href="http://sphinx-doc.org/">Sphinx 2.4.4</a>
&amp; <a href="https://github.com/bitprophet/alabaster">Alabaster 0.7.12</a>
</div>
</body>
</html>