2010年8月7日土曜日

tipfy-ext-authのexampleのmulti-authを使ってみる。

一応multi-authの取得方法
http://code.google.com/p/tipfy-ext-auth/source/checkout
にあるように、
hg clone https://tipfy-ext-auth.googlecode.com/hg/ tipfy-ext-auth
とすると、exampleの中に入っている。

exampleなんだから、そのまま使えればいいのに、使えない...
どのように使うか考えてみる。

方針:/app/auth/の中に入れて、他のアプリからも、multi-authの機能を使えるようにしたい。

まず、
/app/auth/__init__.py
空のファイルを作っておく
/app/auth/urls.py
/app/auth/handlers.py
これをexampleからコピってくる。
exampleのconfig.pyから/config.pyに必要なとこをコピる。(どうせあとで設定が必要だが)

exampleのstaticを/staticへ
exampleのtemplatesをとりあえず/templates/auth/に全て移動。

/app/auth/urls.pyのruleのhandlerのところを
handler='apps.auth.handlers.HomeHandler'
の様に、適切なハンドラーをさすように全て変更。
(hello_worldの'/'とぶつかるので、'/hellosimple'とかにしておいた。)

/app/auth/handlers.pyのrender_response中を
return self.render_response('auth/home.html', section='home')
のようにして、/templates/auth/home.htmlなどを指し示すようにする。

この辺でhttp://localhost:8080/とかすると、エラーをはくので、
テンプレートもいじらねば。

将来的なことを考えて、
/templates/auth/layout.html

/templates/layout.html
に移動。
/templates/auth/login.html
などの中は
{% from 'auth/_form_macros.html' import form_field %}
と_form_macros.htmlのにはauthをつけておいた。

これで、一応エラーはでなくなったのだが、cssまわりが反映されてない。

/app.yaml

- url: /static
static_dir: static
を付け加えて、staticの中をちゃんと読めるようにした。(ただし、robot.txtとかの後に付け加えた。順番大事だったはず)

tipfyはじめました。

調査が終わった感じなので、実際につくりはじめてみる。

appの中に基本は実装していくというのはわかったのだけど、やはり、実際にやってみると、気をつけなければいけないところがあるね。

例えば、もし、appと関係なくutility.pyなど作りたいときにはどこに置くべきなんだろうか?

http://www.tipfy.org/wiki/guide/sitelayout/

によれば、
/app.yaml
/main.py
/config.py
/urls.py
/apps/(appname)/
/lib/
/locale/
/static/
/templates/

が決まっている。
/distlib/
も決まっているはずだ。

そうすると、自作のutility.pyなどは/lib/の中ライブラリとしてくるべきか?

app.yamlはid等を設定すれば十分なはず。
config.pyのapps_installedはいじらないといけないだろう。
urls.pyはconfig.pyから読み込んでRuleなど自動設定っぽいので、いじらなくていいはず。

/app/(appname)/の中でhello_worldではurls.pyとhandlers.pyが定義されているんだけど、models.pyとかforms.pyは分けた方がよいのか?

/templates/の中はappsごとにディレクトリきった方が後の管理は楽か?
/app/(appname)/templates/とした方がもっと管理は楽になりそうではあるが...
http://www.tipfy.org/docs/api/tipfy.ext.jinja2.html
より、templates_dirでディレクトリを決めなくてはいけないらしいので、
/app/(appname)/templates/
はできなさそうだ。

2010年8月3日火曜日

acl tipfy

ちょっとCMS調べ等で寄り道をしたが、tipfyを使ったaclに話題を戻す。
はっきりいって、
http://www.tipfy.org/docs/api/tipfy.ext.acl.html
http://www.tipfy.org/wiki/extensions/acl/
の2カ所以外に資料はみつからない。あとは、ソースを読み解け、ということだと思う。
間違えているかもしれないが、現状思っていることを記録しておく。

[area]
webアプリケーションで範囲を設定して、それごとにaclを設定できるということのようだ。なぜなら、
user_acl = AclRules.get_by_area_and_user('my_area', 'user_2')
としてaclを取得してから、その役割に追加したり、調べたりできるようだからだ。
ここが分かりずらかった。大規模になったときには便利になるんだろう。

[rule]
# Set a dict of roles with an 'admin' role that has full access and
# assign users to it. Each role maps to a list of rules. Each rule is a
# tuple (topic, name, flag), where flag is as bool to allow or disallow
# access. Wildcard '*' can be used to match all topics and/or names.
とあるので、topic, name, flag によって構成されていることがわかる。

[role]
Groupではなく、roleと呼ぶみたいだ。

[roles_map]
Acl.roles_map = {
'admin': [
('*', '*', True),
],
}
roleとruleをタブルで列挙していく。

[使い方-ユーザーの追加]
# Assign users 'user_1' and 'user_2' to the 'admin' role.
AclRules.insert_or_update(area='my_area', user='user_1', roles=['admin'])
AclRules.insert_or_update(area='my_area', user='user_2', roles=['admin'])

[使い方-ユーザーに対する権限の追加/削除]
user_acl = AclRules.get_by_area_and_user('my_area', 'user_2')
user_acl.rules.append(('UserAdmin', '*', False))
user_acl.put()
area,userからAclRulesを取得して、そのrulesからappend()とかremove()すればよさそうだ。

[使い方-実装]
is_one(role)
is_any(roles)
is_all(roles)
has_any_access()
as_access(topic, name)
を使って実装していく。

[app-engine-site-creatorのACLの実装との比較について]
app-engine-site-creatorではACLの実装のかなりの部分をmodels.pyに記述している。
tipfyでもやり方によってはできるか?

[デコレータ]
Handlerを書くときにデコレータで
@login_required
@admin_required
のようにかけたら便利だな、と思っていたところ、
http://groups.google.com/group/tipfy/browse_thread/thread/cca740bf8e131510/c609e94e1e70fa96?lnk=gst&q=acl#c609e94e1e70fa96
に「書いたよ!」という人がいた。
一応、引用しておこう。

I wrote a function decorator for acl, it is according to my needs, but 
maybe it is interesting for others too: 
roles_map = { 
        # roles map definitions 
} 

# function decorator: 
def require(name, topic, area='whole'): 
    def wrap(func): 
        @auth.user_required 
        def decorated(*args, **kwargs): 
            context = {} 
            # user info for the template, getAuth is a custom function 
which 
            # returns username and the links generated by auth 
            #context['auth'] = getAuth() 
            #username = context['auth']['user'].username 
            username = auth.get_current_user().username 
            Acl.roles_map = roles_map 
            acl = Acl(area, username) 
            if acl.has_access(topic=topic, name=name): 
                return func(*args, **kwargs) 
            else: 
                context['errormessage'] = 'No access.' 
                return render_response('error.html', **context) 
        return decorated 
    return wrap 
# a functional form instead of a decorator, which return True or False 
instead of a response 
@auth.user_required 
def is_allowed(name, topic, area='whole'): 
    username = auth.get_current_user().username 
    Acl.roles_map = roles_map 
    acl = Acl(area, username) 
    return acl.has_access(topic=topic, name=name) 
Is there a more appropriate place to publish snippets and samples for 
tipfy? 
/ruben 


さて、そろそろ調査は終わりかな...

2010年8月2日月曜日

cpedialog etupirka vasao

GAE上で使えるブログ
ブログとしては強力なんだけど、Pageはメニュー階層つくれないので、残念...

これを改良するかな。

それとも、
etupirka
http://sites.google.com/site/aboutetupirka/
まだ開発中みたいだけど、CMS/Blogの両方がうまく使えそうな気はする。GAE/Jだけど...

これもGAE/Jだけど
vosao cms
割と強力そうだ。

App Engine Site Creator

ちょっと使ってみようと思ったら...あれ、ここにACLの実装例があるぞー。また悩む...
とりあえず実行して、記事を投稿しようとすると
'ascii' codec can't decode
とかエラーがでるので、
views/admin.pyの220行目
page.content = request.POST['editorHtml']

page.content = request.POST['editorHtml'].decode('utf-8')
と修正したら、なおった。
画像切れは
images/logo.gif -> /static/images/logo.png
に2カ所修正。

http://ringio-blog.appspot.com/tag/GAE
によれば
「複数ユーザでクローズドなページを管理したい!という要求に答える素敵ソフトウェアですね。
任意のGoolgeアカウントに閲覧可否・管理機能使用可否を付与できるのでいい感じです。」