<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>lua nova &#187; sputnik</title>
	<atom:link href="http://www.luanova.org/tag/sputnik/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.luanova.org</link>
	<description>welcome to the moon</description>
	<lastBuildDate>Thu, 23 Sep 2010 12:46:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Authentication-based permission groups in Sputnik</title>
		<link>http://www.luanova.org/authentication-based-permission-groups-in-sputnik/</link>
		<comments>http://www.luanova.org/authentication-based-permission-groups-in-sputnik/#comments</comments>
		<pubDate>Thu, 20 May 2010 07:17:34 +0000</pubDate>
		<dc:creator>jimwhitehead</dc:creator>
				<category><![CDATA[Lua]]></category>
		<category><![CDATA[sputnik]]></category>

		<guid isPermaLink="false">http://luanova.org/?p=63</guid>
		<description><![CDATA[Sputnik is a novel document-storage-based wiki written in Lua which has been previously featured on LuaNova. Today I&#8217;d like to share my experiences adding authentication-based permission groups to my running Sputnik installation at wowprogramming.com. Over the course of the past two months I have had two spam posts on our forums which were fixed by [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://sputnik.freewisdom.org/">Sputnik</a> is a novel document-storage-based wiki written in Lua which
has been previously featured on LuaNova. Today I&#8217;d like to share my
experiences adding authentication-based permission groups to my
running Sputnik installation at <a href="http://wowprogramming.com">wowprogramming.com</a>. Over the
course of the past two months I have had two spam posts on our forums
which were fixed by removing those nodes from the document store, but
this left me with a question of what to do with the user account that
posted the spam message.</p>

<p>First, I should state that we have had very few instances of spam on
our site. Any user accounts must be verified by email and require the
user to input a captcha from the <a href="http://recaptcha.net/">reCaptcha</a> project. Once this is done,
the user is free to make edits to the API documentation and to post
new topics and replies on the discussion forums. However, the process
of posting spam on the site is very difficult to automate due to the
honeypots, field hashing, and post tokens that a default Sputnik
installation employs. That&#8217;s not to say that the software is
bullet-proof, but in practice it seems to work for my needs on a real
site.</p>

<p>The first few accounts, I simply removed from my authentication system
via a simple mysql query (although removing it from a default
installation would be a easier, a simple edit of the sputnik/passwords
node.) But then I realised I was giving up information about the
spammers, including the email addresses they were using to register,
something I could share with some of the spam registration databases
that exist. It was clear that I needed an easier way to stop those
user accounts from posting on the site without simply nuking their
user accounts from the system. Really what I wanted was a way to &#8216;ban&#8217;
a user account and prevent them from making edits on the site.</p>

<h2>Permissions in Sputnik</h2>

<p>Each node in a Sputnik document store is a Lua script that is compiled
and assembled into a Lua object at runtime. Consider the following
simple node:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">    title <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;Some Page&quot;</span>
    content <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>This is a simple test node <span style="color: #b1b100;">for</span> a Sputnik installation.
&nbsp;
    Hello World<span style="color: #66cc66;">!</span><span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span></pre></div></div>


<p>Sputnik nodes can be more than just a symbolic representation of text
data. For example, you can restrict the permissions of a node by
adding a permissions field. Consider the following definition:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">    permissions    <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#91;</span>
      deny<span style="color: #66cc66;">&#40;</span>all_users, all_actions<span style="color: #66cc66;">&#41;</span>
      allow<span style="color: #66cc66;">&#40;</span>all_users, show<span style="color: #66cc66;">&#41;</span>  <span style="color: #808080; font-style: italic;">-- show, show_content, cancel</span>
      allow<span style="color: #66cc66;">&#40;</span>Authenticated, edit_and_save<span style="color: #66cc66;">&#41;</span> <span style="color: #808080; font-style: italic;">-- edit, save, preview</span>
      allow<span style="color: #66cc66;">&#40;</span>all_users, <span style="color: #ff0000;">&quot;post&quot;</span><span style="color: #66cc66;">&#41;</span>  <span style="color: #808080; font-style: italic;">-- needed for login</span>
      allow<span style="color: #66cc66;">&#40;</span>all_users, <span style="color: #ff0000;">&quot;rss&quot;</span><span style="color: #66cc66;">&#41;</span>
      allow<span style="color: #66cc66;">&#40;</span>Admin, all_actions<span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#93;</span><span style="color: #66cc66;">&#93;</span></pre></div></div>


<p>When this field is loaded, it&#8217;s obviously a string that we can then
further process. Specifically, we load it in an environment where a
few helpers functions are defined. The all_users function returns true
for all users, all_actions does the same for all action types.
Authenticated is a special function that returns true if the current
user is authenticated, while Anonymous can be used when the user is
not logged in. There&#8217;s also a special function called Admin that
queries the authentication metadata for the current user and checks if
the is_admin flag is set.</p>

<p>When I started looking for a way to ban users, I started looking in
this section of the code and found the following gem that Yuri sneaked
in after the definition for the Admin group:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">      <span style="color: #b1b100;">local</span> groups <span style="color: #66cc66;">=</span> self.saci.permission_groups <span style="color: #808080; font-style: italic;">-- just a local alias</span>
      <span style="color: #808080; font-style: italic;">-- Define group &quot;Admin&quot; as any user that has is_admin set to true</span>
      groups.Admin <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">function</span><span style="color: #66cc66;">&#40;</span>user<span style="color: #66cc66;">&#41;</span>
         <span style="color: #b1b100;">return</span> user <span style="color: #b1b100;">and</span> self.auth:get_metadata<span style="color: #66cc66;">&#40;</span>user, <span style="color: #ff0000;">&quot;is_admin&quot;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">==</span> <span style="color: #ff0000;">&quot;true&quot;</span>
      <span style="color: #b1b100;">end</span>
&nbsp;
      <span style="color: #808080; font-style: italic;">-- Define any group that starts with &quot;is.&lt;group&gt;&quot; as including all users</span>
      <span style="color: #808080; font-style: italic;">-- for whom &quot;is_&lt;group&gt;&quot; is set to true. For example, if is_clown is set</span>
      <span style="color: #808080; font-style: italic;">-- to true than user is a member of group &quot;is.clown&quot; and we can set:</span>
      <span style="color: #808080; font-style: italic;">--</span>
      <span style="color: #808080; font-style: italic;">--     allow(is.clown, &quot;show&quot;)</span>
      <span style="color: #808080; font-style: italic;">--</span>
      <span style="color: #b1b100;">local</span> groups_mt <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#123;</span>
         __index <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">table</span>, key<span style="color: #66cc66;">&#41;</span>
            <span style="color: #b1b100;">return</span> <span style="color: #b1b100;">function</span> <span style="color: #66cc66;">&#40;</span>user<span style="color: #66cc66;">&#41;</span>
                      <span style="color: #b1b100;">return</span> user <span style="color: #b1b100;">and</span> self.auth:get_metadata<span style="color: #66cc66;">&#40;</span>user,
    <span style="color: #ff0000;">&quot;is_&quot;</span>..key<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">==</span> <span style="color: #ff0000;">&quot;true&quot;</span>
                   <span style="color: #b1b100;">end</span>
         <span style="color: #b1b100;">end</span>
      <span style="color: #66cc66;">&#125;</span>
      groups.is <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">setmetatable</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#125;</span>, groups_mt<span style="color: #66cc66;">&#41;</span></pre></div></div>


<p>Bingo! With this bit of code, without making any changes to the
Sputnik core, I had a way to ban users in my system, by setting the
<strong>is_banned</strong> flag in their authentication metadata. For a simple
authentication system (the default) this is just a matter of setting
the given flag in the user&#8217;s authentication entry, whereas in a mysql
authentication system I just add a row to the database. This was only
part of the puzzle, since Sputnik doesn&#8217;t know anything about the new
user group. I had to make a few edits to the @Root prototype to add
the following at the end:</p>


<div class="wp_syntax"><div class="code"><pre class="lua" style="font-family:monospace;">    deny<span style="color: #66cc66;">&#40;</span>is.banned, edit_and_save<span style="color: #66cc66;">&#41;</span></pre></div></div>


<p>Since earlier in the permissions script the edit_and_save permissions
are granted to all authenticated users, I needed to make sure the
denial runs after that point, since the final &#8216;permission&#8217; is what
really matters. Since I have custom forums in my system, I needed to
make the same one-line change in a few other places.</p>

<p>It took a total of about 6 minutes to familiarize myself with the code
and make the necessary changes, and now I have an easy way to ban a
user from being able to post anywhere on my website.</p>

<p>Down with the spammers!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.luanova.org/authentication-based-permission-groups-in-sputnik/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

