MoinMoinでアクセス元によってグループに属させる

部で情報蓄積のためのWikiとしてMoinMoinを設置したのであるが、一部のページでログインしない状態では部室内部からのアクセスである場合のみ表示できるようにすることになった。MoinMoinにはACL機能があり、ページ単位でユーザ・グループ別のアクセス許可が出来るのであるが、アクセス元によって制御する機能はない。そこで自前で機能を追加することにした。といっても、本体ソースに手を加えるのはバージョンアップ作業が面倒になるので極力避けたいところであるので、モジュールの追加と設定で解決することにした。

認証処理を拡張して、部室からのアクセスであれば特定のユーザでのアクセスとする事も考えたが、これでは部室からのアクセスが常にログイン状態となり、個々人のログインが出来なくなってしまう。よってこれは却下である。

やはりアクセス元が設定されたものであれば、特定のグループに属しているものとして扱うのが自然だろう。しかし、 http://moinmo.in/Groups2009/ やソースを見るとグループとはユーザ名とグループ名の集合であって、ユーザに関係なくリクエスト単位で属しているかどうかが変わるような使い方はあまり想定されていないように見える。ただし、コンストラクタにrequestを取っているあたり、実装不可能なわけではなさそうだ。

そういうわけで、アクセス元が条件にあえばそのユーザ名のみを含むグループを、条件に合わないなら空のグループを生成するという構造で実装した。ログインしていないユーザに対してもこの構造で動作している。IPアドレス周りの処理はIPyライブラリに丸投げしている。逆引きしたホスト名でのマッチングには未対応である。
http://delegate.uec.ac.jp:8081/club/mma/~ytoku/moin/network_groups.py

設定にあたってはCompositeGroupsを使ってWikiGroupsと組み合わせることで、Wikiのページに記述する通常のグループとの共存が出来る。

from IPy import IP
from network_groups import NetworkGroups
from MoinMoin.datastruct import WikiGroups, CompositeGroups
class FarmConfig(multiconfig.DefaultConfig):
    ...
    groups = lambda cfg, request: CompositeGroups(request,
               NetworkGroups(request, { 'LocalComputer': IP('192.168.0.0/24') }),
               WikiGroups(request))