2015年1月29日木曜日

PostgreSQLパスワードハッシュ化関数

crypt()およびgen_salt()関数は特にパスワードのハッシュ化のために設計されたものです。 crypt()がハッシュ処理を行い、gen_salt()はハッシュ処理用のアルゴリズム上のパラメータを準備します。

crypt()アルゴリズムは、以下の点でMD5SHA1のような通常のハッシュ処理アルゴリズムと異なります。

1.    低速です。 データ量が少ないためパスワード総当たり攻撃に対して頑健にする唯一の方法です。

2.    結果にはソルトというランダムな値が含まれます。 このため同じパスワードのユーザでも異なった暗号化パスワードを持ちます。 これはアルゴリズムの逆処理に対する追加の防御です。

3.    結果内にアルゴリズムの種類が含まれます。 このため異なるアルゴリズムでハッシュ化したパスワードが混在可能です。

4.    一部は適合型です。 つまり、コンピュータが高速になったとしても、既存のパスワードとの互換性を損なうことなくアルゴリズムを低速に調整することができます。

F-18. crypt()がサポートするアルゴリズム

アルゴリズム

パスワード最大長

適合型かどうか

ソルトビット長

説明

bf

72

はい

128

Blowfishベース、2a

md5

無制限

いいえ

48

MD5ベースの暗号

xdes

8

はい

24

拡張DES

des

8

いいえ

12

元来のUNIX crypt

F.23.2.1. crypt()

    crypt(password text, salt text) returns text
   

passwordcrypt(3)形式のハッシュを計算します。 新しいパスワードを保管する時には、gen_salt()を使用して新しいsaltを生成する必要があります。 パスワードを検査する時、既存のハッシュ値をsaltとして渡し、結果が格納された値と一致するかどうかを確認します。

新しいパスワードの設定例を以下に示します。

    UPDATE ... SET pswhash = crypt('new password', gen_salt('md5'));
   

認証の例です。

    SELECT pswhash = crypt('entered password', pswhash) FROM ... ;
   

入力パスワードが正しければtrueを返します。

F.23.2.2. gen_salt()

    gen_salt(type text [, iter_count integer ]) returns text
   

crypt()で使用するランダムなソルト文字列を新規に生成します。 また、このソルト文字列はcrypt()にどのアルゴリズムを使用するかを通知します。

typeパラメータはハッシュ化アルゴリズムを指定します。 受付可能な種類は、desxdesmd5bfです。

繰り返し回数を持つアルゴリズムでは、ユーザはiter_countパラメータを使用して繰り返し回数を指定できます。 指定する回数を高くすれば、パスワードのハッシュ化にかかる時間が長くなり、それを破るための時間も長くなります。 しかし、あまりに多くの回数を指定すると、ハッシュ計算にかかる時間は数年に渡ってしまう可能性があります。 これは実用的ではありません。 iter_countパラメータを省略した場合、デフォルトの繰り返し回数が使用されます。 iter_countで受け付けられる値はアルゴリズムに依存し、表F-19に示す通りです。

F-19. crypt()用の繰り返し回数

アルゴリズム

デフォルト

最小

最大

xdes

725

1

16777215

bf

6

4

31

xdesの場合、回数が奇数でなければならないという追加の制限があります。

適切な繰り返し回数を選択するために、元々のDES暗号は当時のハードウェアで1秒あたり4個のハッシュを持つことができるように設計されたことを考えてください。 14ハッシュより遅いと、おそらく使い勝手が悪いでしょう。 1100ハッシュより速いというのは、十中八九、あまりにも速すぎるでしょう。

ハッシュ化アルゴリズム別に相対的な速度に関する概要を表F-20にまとめました。 この表は、8文字のパスワード内のすべての文字の組合せを取るためにかかる時間を示します。 また、すべて小文字の英字のみのパスワードである場合と大文字小文字が混在した英字と数字のパスワードの場合を仮定します。 crypt-bfの項では、スラッシュの後の数値はgen_saltiter_countです。

F-20. ハッシュアルゴリズムの速度

アルゴリズム

1秒当たりのハッシュ数

[a-z]の場合

[A-Za-z0-9]の場合

crypt-bf/8

28

246

251322

crypt-bf/7

57

121

123457

crypt-bf/6

112

62

62831

crypt-bf/5

211

33

33351

crypt-md5

2681

2.6

2625

crypt-des

362837

7

19

sha1

590223

4

12

md5

2345086

1

3

注意:

·         Pentium 4 1.5GHzのマシンを使用しました。

·         crypt-desおよびcrypt-md5アルゴリズムの数値はJohn the Ripper v1.6.38-test出力から得たものです。

·         md5の数値はmdcrack 1.2のものです。

·         sha1の数値はlcrack-20031130-betaのものです。

·         crypt-bfの数は、1000個の8文字パスワードをループする単純なプログラムを使用して得たものです。 こうして、異なる回数の速度を示すことができました。 参考までに、john -testcrypt-bf/5213 loops/secでした。 (結果の差異が非常に小さいことは、pgcryptoにおけるcrypt-bf実装がJohn the Ripper(訳注:パスワード解析ツール)で使用されるものと同じであるという事実と一致します。)

"すべての組み合わせを試行する"ことは現実的行使ではありません。 通常パスワード推定は、普通の単語とその変形の両方を含む辞書を使用して行われます。 ですので、いささかなりとも言葉に似たパスワードは上で示した数値よりも速く推定されます。 また6文字の単語に似ていないパスワードは推定を免れるかもしれませんし、免れないかもしれません

 

オープンソースJava O/Rマッピングソフト一覧

最近は更新ペースがかなり落ちてしまっているのですが、今後も少しづつblogを更新していこうと思っています。本年もどうかよろしくお願いいたします。

新年一回目のエントリは、去年も年始に書いた「オープンソースJava O/Rマッピングソフト一覧」の更新版です。

- オープンソースJava O/Rマッピングソフト一覧(2013年1月版) | Unofficial DB2 BLOG (去年のエントリ)

去年と同様、リストに挙げたのはオープンソースかつJava用のO/Rマッピング機能を持つソフトウェアです。いわゆる「フルスタックフレームワーク」にはO/Rマッピング機能が含まれているものが多いですが、単体のO/Rマッピングフレームワークとして機能しないものは含めていません。今年はiciqlとJaQuを追加しました。

また、各ソフトウェアごとにプロジェクトの最終更新日(最後にソースコードをリリースした日付やリポジトリにコミットされた日時)を確認して、1年間以上更新していないプロジェクトには、名前の後ろに*マークを付けて最終更新日を付記しています。

注意点としては、あくまで新バージョンがリリースされていないことを確認しただけだということです。実際に開発やメンテナンスされていないかまで確認したのでは無いことにご注意ください。

結果として去年よりも多くのソフトウェアに*マークが付いています。一方で去年調べた際には更新が止まったと思っていたソフトウェアが更新を再開しているケースもありました。(O/R BrokerとPrevayler)

Hibernate、Touque、mybatisといった歴史とユーザベースがあるソフトウェアが継続的に更新され続けているのは去年から変わっておらず、素晴らしいですね。

リストに不足しているソフトウェアがありましたら、ぜひコメント欄、もしくはTwitterの@simosako宛に教えてください。

ActiveObjects (*2011年3月)
http://java.net/projects/activeobjects/pages/Home

amber (RESINアプリケーションサーバに含まれるJPA実装。Resin 4.0にも含まれているようです)
http://www.caucho.com/resin-application-server-2/

Ammentos (*2008年9月)
http://www.ammentos.org/

Apache Cayenne
http://cayenne.apache.org/

Apache OpenJPA (JPA 2.0)
http://openjpa.apache.org/

Apache Torque
http://db.apache.org/torque/

Athena for Java (*2011年3月)
http://www.athenasource.org/java/

beankeeper (*2010年3月)
http://code.google.com/p/beankeeper/

Butterfly Persistence (*2012年3月) (Mr Persisterの後継プロジェクト)
http://butterfly.jenkov.com/persistence/index.html

Castor (*2012年8月)
http://castor.codehaus.org/

DataNucleus (旧JPOX,JDO/JPA)
http://www.datanucleus.org/

DBFlute
http://dbflute.seasar.org/

Doma
http://doma.seasar.org/

Ebean ORM Persistence Layer
http://www.avaje.org/

EclipseLink (JPA 2.0)
http://www.eclipse.org/eclipselink/

Hermes ORM (*正確には不明ながら1年間以上は更新が無い模様)
http://freecode.com/projects/hermes-orm

Hibernate
http://www.hibernate.org/

iciql
http://iciql.com/

Java Ultra-Lite Persistence (JULP) (*2012年11月)
http://julp.sourceforge.net/

JaQu
http://h2database.com/html/jaqu.html

Jaxor (*2004年3月)
http://sourceforge.net/projects/jaxor/

JDBCPersistence (*2009年12月)
http://www.jdbcpersistence.org/

JoSQL (*2010年12月)
http://josql.sourceforge.net/

KeyAccess (*2012年7月)
http://code.google.com/p/keyaccess/

Mr Persister (*2007年9月 - この後継プロジェクトとしてButterfly Persistenceがリリースされています)
http://jenkov.com/mrpersister/index.html

mybatis (旧Apache iBatis)
http://blog.mybatis.org/p/products.html

ObJectRelationalBridge - OJB (*2011年にプロジェクト終了)
http://db.apache.org/ojb/

O/R Broker (*Java用には2011年12月が最終更新ですが、2013年5月にScala向けとして再度更新されています)
http://code.google.com/p/orbroker/

Oracle TopLink Essentials (JPA)
http://www.oracle.com/technetwork/middleware/toplink/overview/index.html

pBeans 2 Persistence Layer (*2007年4月)
http://pbeans.sourceforge.net/

Persistent Applications Toolkit (*2005年7月)
http://patsystem.sourceforge.net/

Prevayler
http://www.prevayler.org/

PriDE (*2009年11月)
http://pride.sourceforge.net/

S2DAO (*2010年3月)
http://s2dao.seasar.org/ja/

S2JDBC
http://s2container.seasar.org/2.4/ja/s2jdbc.html

SimpleJPA (JPA) (*2012年2月)
https://github.com/appoxy/simplejpa

Smyle (*ホームページが無くなっているようです)

Speedo (JDO) (*2006年5月)
http://speedo.objectweb.org/index.html

TriActive JDO (*2008年4月)
http://tjdo.sourceforge.net/

Ujorm
http://ujorm.org/

Xorm (JDO) (*2004年5月)
http://xorm.sourceforge.net/

PostgreSQL/PostgreSQLでSQLステートメントをログファイルに出力する方法

デバッグなどでアプリケーションソースコードを修正せずに操作により発行されるSQLステートメントを
確認したいと思った場合、以下に記述したようにpostgresql.confファイルを設定し再起動すればログにSQLステートメントが出力されます。
このような使い方の場面はデバッグなどで使用すると思います。
以下に設定方法を記します。
以下の手順でログにSQLステートメントを出力するようにPostgreSQLを設定します。

postgresql.confのありかを調べる
postgresql.confファイルを修正するのでpostgresql.confファイルを開きます。
もし、postgresql.confファイルのありかがわからない時や忘れてしまった場合などは、psコマンドとgrepで探せば簡単に見つかると思います。
psコマンドとgrepで検索した結果は以下の通りです。 使用したコマンド
ps auxw | grep postgres
上記では、postgresで検索しました。postmasterでした方がいい場合もあります。
また、postgresユーザ以外または、postmasterコマンド以外でPostgreSQLを起動している場合はgrepの引数であるpostgresを環境に適した文字列にし実行してください。

実行例
以下の実行結果を見ると -D /var/lib/pgsql/data と表示されているのが確認できます。
postgresql.confは/var/lib/pgsql/dataにあることが推測できます。
[sakura@centos6 ~]$ ps auxw | grep postgres | grep -v grep
postgres 2083 0.0 0.6 214100 6384 ? S 00:19 0:00 /usr/bin/postmaster -p 5432 -D /var/lib/pgsql/data
postgres 2112 0.0 0.1 177112 1408 ? Ss 00:19 0:00 postgres: logger process
postgres 2114 0.0 0.1 214100 1840 ? Ss 00:19 0:00 postgres: writer process
<snip>

ログ出力のためにlogging_collectorの設定を行う postgresql.confを開き、logging_collectorをonにします。
# This is used when logging to stderr:
logging_collector = on # Enable capturing of stderr and csvlog
# into log files. Required to be on for
# csvlogs.
# (change requires restart)

ちなみにログ出力されるディレクトリ名は、postgresql.conf内のlog_directoryの値になります。
# These are only used if logging_collector is on:
log_directory = 'pg_log' # directory where log files are written,
# can be absolute or relative to PGDATA

SQLステートメントをログファイルに出力するためにlog_statementを設定する
postgresql.conf内になるlog_statementの設定を以下のいづれかに変更します。
none 出力しない
ddl CREATE、ALTER、およびDROPといった、データ定義コマンドをログに出力します。
mod ddlとINSERT、UPDATE、DELETE、TRUNCATE、およびCOPY FROMをログに出力します。
PREPAREとEXPLAIN ANALYZEコマンドも、そこに含まれるコマンドが適切な種類であればログに出力されます。
all すべてのSQLがログに出力されます。
参考資料 : PostgreSQL 8.4.4文書 18.7. エラー報告とログ取得

本資料ではallを指定しました。
log_statement = 'all' # none, ddl, mod, all

ちなみにpostgresql.confの先頭にある#はコメントを意味します。
修正しても#を削除しないとデフォルト値が使用されるので注意してください。

PostgreSQLを再起動します。
本資料ではCentOS6のRPMパッケージによりPostgreSQLをインストールしてあるので、serviceコマンドを使用しました。
pg_ctl restart オプションでも再起動できますので、みなさんの環境にあった方法でPostgreSQLを再起動してください。
[root@centos6 ~]# service postgresql restart
postgresql サービスを停止中: [ OK ]
postgresql サービスを開始中: [ OK ]
設定した値が変更されているかpsqlコマンドで確認してみました。
-bash-4.1$ psql -c 'show log_statement'
log_statement
---------------
all
(1 行)

実際に端末からSQLを発行した時のログ出力 †
以下に端末からPostgreSQLを操作しtailコマンドでPostgreSQLのログ出力を確認した結果を記します。

端末からPostgreSQLを操作
-bash-4.1$ echo $USER
postgres
-bash-4.1$ createdb sakura
-bash-4.1$ psql sakura
psql (8.4.13)
"help" でヘルプを表示します.

sakura=# create table t1 (c1 int, c2 int);
CREATE TABLE
sakura=# insert into t1 values(1,10);
INSERT 0 1
sakura=# select * from t1;
c1 | c2
----+----
1 | 10
(1 行)

sakura=# \q
PostgreSQLのログをtailコマンドで確認
-bash-4.1$ tail -f $PGDATA/pg_log/postgresql-Mon.log
<snip>
LOG: 文: CREATE DATABASE sakura;

LOG: 文: create table t1 (c1 int, c2 int);
LOG: 文: insert into t1 values(1,10);
LOG: 文: select * from t1;
以上、PostgreSQLでSQLステートメントをログファイルに出力する方法を記しました。

DecoratinginURLconf

Thesimplestwayofdecoratingclass-basedviewsistodecoratetheresultoftheas_view()method.Theeasiest placetodothisisintheURLconfwhereyoudeployyourview: fromdjango.contrib.auth.decoratorsimportlogin_required,permission_required fromdjango.views.genericimportTemplateView from.viewsimportVoteView urlpatterns=[ url(r'^about/',login_required(TemplateView.as_view(template_name="secret.html"))), url(r'^vote/',permission_required('polls.can_vote')(VoteView.as_view())), ] Thisapproachappliesthedecoratoronaper-instancebasis.Ifyouwanteveryinstanceofaviewtobedecorated,you needtotakeadifferentapproach. Decoratingtheclass Todecorateeveryinstanceofaclass-basedview,youneedtodecoratetheclassdefinitionitself.Todothisyouapply thedecoratortothedispatch()methodoftheclass. Amethodonaclassisn'tquitethesameasastandalonefunction,soyoucan'tjustapplyafunctiondecoratortothe method–youneedtotransformitintoamethoddecoratorfirst.Themethod_decoratordecoratortransformsa functiondecoratorintoamethoddecoratorsothatitcanbeusedonaninstancemethod.Forexample: fromdjango.contrib.auth.decoratorsimportlogin_required fromdjango.utils.decoratorsimportmethod_decorator fromdjango.views.genericimportTemplateView classProtectedView(TemplateView): template_name='secret.html' @method_decorator(login_required) defdispatch(self,*args,**kwargs): returnsuper(ProtectedView,self).dispatch(*args,**kwargs) Inthisexample,everyinstanceofProtectedViewwillhaveloginprotection.

Template inheritance

The most powerful – and thus the most complex – part of Django's template engine is template inheritance. Template
inheritance allows you to build a base "skeleton" template that contains all the common elements of your site and
defines blocks that child templates can override.
It's easiest to understand template inheritance by starting with an example:
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css" />
<title>{% block title %}My amazing site{% endblock %}</title>
</head>
<body>
<div id="sidebar">
{% block sidebar %}
<ul>
<li><a href="/">Home</a></li>
<li><a href="/blog/">Blog</a></li>
</ul>
{% endblock %}
</div>
<div id="content">
{% block content %}{% endblock %}
</div>
</body>
</html>
This template, which we'll call base.html, defines a simple HTML skeleton document that you might use for a
simple two-column page. It's the job of "child" templates to fill the empty blocks with content.
In this example, the block tag defines three blocks that child templates can fill in. All the block tag does is to tell
the template engine that a child template may override those portions of the template.
A child template might look like this:
{% extends "base.html" %}
{% block title %}My amazing blog{% endblock %}
{% block content %}
{% for entry in blog_entries %}
<h2>{{ entry.title }}</h2>
<p>{{ entry.body }}</p>
{% endfor %}
{% endblock %}
The extends tag is the key here. It tells the template engine that this template "extends" another template. When
the template system evaluates this template, first it locates the parent – in this case, "base.html".
At that point, the template engine will notice the three block tags in base.html and replace those blocks with the
contents of the child template. Depending on the value of blog_entries, the output might look like:
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css" />
<title>My amazing blog</title>
</head>
<body>
<div id="sidebar">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/blog/">Blog</a></li>
</ul>
</div>
<div id="content">Content within a {% block %} tag in a parent template is always used as a fallback.
You can use as many levels of inheritance as needed. One common way of using inheritance is the following three-level
approach:
• Create a base.html template that holds the main look-and-feel of your site.
• Create a base_SECTIONNAME.html template for each "section" of your site. For example,
base_news.html, base_sports.html. These templates all extend base.html and include sectionspecific
styles/design.
• Create individual templates for each type of page, such as a news article or blog entry. These templates extend
the appropriate section template.
This approach maximizes code reuse and makes it easy to add items to shared content areas, such as section-wide
navigation.
Here are some tips for working with inheritance:
• If you use {% extends %} in a template, it must be the first template tag in that template. Template inheritance
won't work, otherwise.
• More {% block %} tags in your base templates are better. Remember, child templates don't have to define
all parent blocks, so you can fill in reasonable defaults in a number of blocks, then only define the ones you need
later. It's better to have more hooks than fewer hooks.
• If you find yourself duplicating content in a number of templates, it probably means you should move that
content to a {% block %} in a parent template.
• If you need to get the content of the block from the parent template, the {{ block.super }} variable will
do the trick. This is useful if you want to add to the contents of a parent block instead of completely overriding
it. Data inserted using {{ block.super }} will not be automatically escaped (see the next section), since
it was already escaped, if necessary, in the parent template.
• For extra readability, you can optionally give a name to your {% endblock %} tag. For example:
{% block content %}
...
{% endblock content %}
In larger templates, this technique helps you see which {% block %} tags are being closed.
Finally, note that you can't define multiple block tags with the same name in the same template. This limitation
exists because a block tag works in "both" directions. That is, a block tag doesn't just provide a hole to fill – it also
defines the content that fills the hole in the parent. If there were two similarly-named block tags in a template, that
template's parent wouldn't know which one of the blocks' content to use.
<h2>Entry one</h2>
<p>This is my first entry.</p>
<h2>Entry two</h2>
<p>This is my second entry.</p>
</div>
</body>
</html>
Note that since the child template didn't define the sidebar block, the value from the parent template is used instead.

Using class-based views

a class-based view allows you to respond to different HTTP request methods with different class instance
methods, instead of with conditionally branching code inside a single view function.
So where the code to handle HTTP GET in a view function would look something like:
from django.http import HttpResponse
def my_view(request):
if request.method == 'GET':
# <view logic>
return HttpResponse('result')
In a class-based view, this would become:
from django.http import HttpResponse
from django.views.generic import View
class MyView(View):
def get(self, request):
# <view logic>
return HttpResponse('result')
Because Django's URL resolver expects to send the request and associated arguments to a callable function, not a
class, class-based views have an as_view() class method which serves as the callable entry point to your class. The
as_view entry point creates an instance of your class and calls its dispatch() method. dispatch looks at the
request to determine whether it is a GET, POST, etc, and relays the request to a matching method if one is defined, or
raises HttpResponseNotAllowed if not:
# urls.py
from django.conf.urls import url
from myapp.views import MyView
urlpatterns = [
url(r'^about/', MyView.as_view()),
]

Building a form

Suppose you want to create a simple form on your Web site, in order to obtain the user's name. You'd need something
like this in your template:
<form action="/your-name/" method="post">
<label for="your_name">Your name: </label>
<input id="your_name" type="text" name="your_name" value="{{ current_name }}">
<input type="submit" value="OK">
</form>
This tells the browser to return the form data to the URL /your-name/, using the POST method. It will display
a text field, labeled "Your name:", and a button marked "OK". If the template context contains a current_name
variable, that will be used to pre-fill the your_name field.
You'll need a view that renders the template containing the HTML form, and that can supply the current_name
field as appropriate.
When the form is submitted, the POST request which is sent to the server will contain the form data.
Now you'll also need a view corresponding to that /your-name/ URL which will find the appropriate key/value
pairs in the request, and then process them.
This is a very simple form. In practice, a form might contain dozens or hundreds of fields, many of which might
need to be pre-populated, and we might expect the user to work through the edit-submit cycle several times before
concluding the operation.
We might require some validation to occur in the browser, even before the form is submitted; we might want to use
much more complex fields, that allow the user to do things like pick dates from a calendar and so on.
At this point it's much easier to get Django to do most of this work for us.
Building a form in Django
The Form class
We already know what we want our HTML form to look like. Our starting point for it in Django is this:
from django import forms
class NameForm(forms.Form):
your_name = forms.CharField(label='Your name', max_length=100)
This defines a Form class with a single field (your_name). We've applied a human-friendly label to the field, which
will appear in the <label> when it's rendered (although in this case, the label we specified is actually the same
one that would be generated automatically if we had omitted it).
The field's maximum allowable length is defined by max_length. This does two things. It puts a
maxlength="100" on the HTML <input> (so the browser should prevent the user from entering more than
that number of characters in the first place). It also means that when Django receives the form back from the browser,
it will validate the length of the data.
A Form instance has an is_valid() method, which runs validation routines for all its fields. When this method is
called, if all fields contain valid data, it will:
• return True
• place the form's data in its cleaned_data attribute.
The whole form, when rendered for the first time, will look like:
<label for="your_name">Your name: </label>
<input id="your_name" type="text" name="your_name" maxlength="100">
Note that it does not include the <form> tags, or a submit button. We'll have to provide those ourselves in the
template.
The view
Form data sent back to a Django Web site is processed by a view, generally the same view which published the form.
This allows us to reuse some of the same logic.
To handle the form we need to instantiate it in the view for the URL where we want it to be published:
from django.shortcuts import render
from django.http import HttpResponseRedirect
def get_name(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = NameForm(request.POST)
# check whether it's valid:
if form.is_valid():
# process the data in form.cleaned_data as required
# ...
# redirect to a new URL:
return HttpResponseRedirect('/thanks/')
# if a GET (or any other method) we'll create a blank form
else:
form = NameForm()
return render(request, 'name.html', {'form': form})
If we arrive at this view with a GET request, it will create an empty form instance and place it in the template context
to be rendered. This is what we can expect to happen the first time we visit the URL.
If the form is submitted using a POST request, the view will once again create a form instance and populate it with
data from the request: form = NameForm(request.POST) This is called "binding data to the form" (it is now
a bound form).
We call the form's is_valid() method; if it's not True, we go back to the template with the form. This time the
form is no longer empty (unbound) so the HTML form will be populated with the data previously submitted, where it
can be edited and corrected as required.
If is_valid() is True, we'll now be able to find all the validated form data in its cleaned_data attribute. We
can use this data to update the database or do other processing before sending an HTTP redirect to the browser telling
it where to go next.
The template
We don't need to do much in our name.html template. The simplest example is:
<form action="/your-name/" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit" />
</form>
All the form's fields and their attributes will be unpacked into HTML markup from that {{ form }} by Django's
template language.
Forms and Cross Site Request Forgery protection
Django ships with an easy-to-use protection against Cross Site Request Forgeries. When submitting a form via POST
with CSRF protection enabled you must use the csrf_token template tag as in the preceding example. However,
since CSRF protection is not directly tied to forms in templates, this tag is omitted from the following examples in this
document.

redirect

redirect(to[, permanent=False ], *args, **kwargs)
Returns an HttpResponseRedirect to the appropriate URL for the arguments passed.
The arguments could be:
•A model: the model's get_absolute_url() function will be called.
•A view name, possibly with arguments: urlresolvers.reverse will be used to reverse-resolve the
name.
•An absolute or relative URL, which will be used as-is for the redirect location.
By default issues a temporary redirect; pass permanent=True to issue a permanent redirect.
The ability to use relative URLs was added.
Examples
You can use the redirect() function in a number of ways.
1. By passing some object; that object's get_absolute_url() method will be called to figure out the redirect
URL:
from django.shortcuts import redirect
def my_view(request):
...
object = MyModel.objects.get(...)
return redirect(object)
2. By passing the name of a view and optionally some positional or keyword arguments; the URL will be reverse
resolved using the reverse() method:
def my_view(request):
...
return redirect('some-view-name', foo='bar')
3. By passing a hardcoded URL to redirect to:
def my_view(request):
...
return redirect('/some/url/')
This also works with full URLs:
def my_view(request):
...
return redirect('http://example.com/')
By default, redirect() returns a temporary redirect. All of the above forms accept a permanent argument; if set
to True a permanent redirect will be returned:
def my_view(request):
...
object = MyModel.objects.get(...)
return redirect(object, permanent=True)

File Uploads

When Django handles a file upload, the file data ends up placed in request.FILES

Basic file uploads
Consider a simple form containing a FileField:
# In forms.py...
from django import forms
class UploadFileForm(forms.Form):
title = forms.CharField(max_length=50)
file = forms.FileField()

A view handling this form will receive the file data in request.FILES, which is a dictionary containing a key for
each FileField (or ImageField, or other FileField subclass) in the form. So the data from the above form
would be accessible as request.FILES['file'].
Note that request.FILES will only contain data if the request method was POST and the <form> that posted the
request has the attribute enctype="multipart/form-data". Otherwise, request.FILES will be empty.
Most of the time, you'll simply pass the file data from request into the form as described in Binding uploaded files
to a form. This would look something like:
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from .forms import UploadFileForm
# Imaginary function to handle an uploaded file.
from somewhere import handle_uploaded_file
def upload_file(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
handle_uploaded_file(request.FILES['file'])
return HttpResponseRedirect('/success/url/')
else:
form = UploadFileForm()
return render_to_response('upload.html', {'form': form})
Notice that we have to pass request.FILES into the form's constructor; this is how file data gets bound into a
form.
Here's a common way you might handle an uploaded file:
def handle_uploaded_file(f):
with open('some/file/name.txt', 'wb+') as destination:
for chunk in f.chunks():
destination.write(chunk)
Looping over UploadedFile.chunks() instead of using read() ensures that large files don't overwhelm your
system's memory.
There are a few other methods and attributes available on UploadedFile objects; see UploadedFile for a
complete reference.
Handling uploaded files with a model
If you're saving a file on a Model with a FileField, using a ModelForm makes this process much easier. The file
object will be saved to the location specified by the upload_to argument of the corresponding FileField when
calling form.save():
from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import ModelFormWithFileField
def upload_file(request):
if request.method == 'POST':
form = ModelFormWithFileField(request.POST, request.FILES)
if form.is_valid():
# file is saved
form.save()

return HttpResponseRedirect('/success/url/')
else:
form = ModelFormWithFileField()
return render(request, 'upload.html', {'form': form})
If you are constructing an object manually, you can simply assign the file object from request.FILES to the file
field in the model:
from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import UploadFileForm
from .models import ModelWithFileField
def upload_file(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES)
if form.is_valid():
instance = ModelWithFileField(file_field=request.FILES['file'])
instance.save()
return HttpResponseRedirect('/success/url/')
else:
form = UploadFileForm()
return render(request, 'upload.html', {'form': form})
Upload Handlers
When a user uploads a file, Django passes off the file data to an upload handler � a small class that handles file data as
it gets uploaded. Upload handlers are initially defined in the FILE_UPLOAD_HANDLERS setting, which defaults to:
("django.core.files.uploadhandler.MemoryFileUploadHandler",
"django.core.files.uploadhandler.TemporaryFileUploadHandler",)
Together MemoryFileUploadHandler and TemporaryFileUploadHandler provide Django's default file
upload behavior of reading small files into memory and large ones onto disk.
You can write custom handlers that customize how Django handles files. You could, for example, use custom handlers
to enforce user-level quotas, compress data on the fly, render progress bars, and even send data to another storage
location directly without storing it locally. See Writing custom upload handlers for details on how you can customize
or completely replace upload behavior.
Where uploaded data is stored
Before you save uploaded files, the data needs to be stored somewhere.
By default, if an uploaded file is smaller than 2.5 megabytes, Django will hold the entire contents of the upload in
memory. This means that saving the file involves only a read from memory and a write to disk and thus is very fast.
However, if an uploaded file is too large, Django will write the uploaded file to a temporary file stored in your system's
temporary directory. On a Unix-like platform this means you can expect Django to generate a file called something
like /tmp/tmpzfp6I6.upload. If an upload is large enough, you can watch this file grow in size as Django
streams the data onto disk.

Changing upload handler behavior
There are a few settings which control Django's file upload behavior. See File Upload Settings for details.
Modifying upload handlers on the fly
Sometimes particular views require different upload behavior. In these cases, you can override upload handlers on a
per-request basis by modifying request.upload_handlers. By default, this list will contain the upload handlers
given by FILE_UPLOAD_HANDLERS, but you can modify the list as you would any other list.
For instance, suppose you've written a ProgressBarUploadHandler that provides feedback on upload progress
to some sort of AJAX widget. You'd add this handler to your upload handlers like this:
request.upload_handlers.insert(0, ProgressBarUploadHandler())
You'd probably want to use list.insert() in this case (instead of append()) because a progress bar handler
would need to run before any other handlers. Remember, the upload handlers are processed in order.
If you want to replace the upload handlers completely, you can just assign a new list:
request.upload_handlers = [ProgressBarUploadHandler()]
Note: You can only modify upload handlers before accessing request.POST or request.FILES � it
doesn't make sense to change upload handlers after upload handling has already started. If you try to modify
request.upload_handlers after reading from request.POST or request.FILES Django will throw an
error.
Thus, you should always modify uploading handlers as early in your view as possible.
Also, request.POST is accessed by CsrfViewMiddleware which is enabled by default. This means you will
need to use csrf_exempt() on your view to allow you to change the upload handlers. You will then need to use
csrf_protect() on the function that actually processes the request. Note that this means that the handlers may
start receiving the file upload before the CSRF checks have been done. Example code:
from django.views.decorators.csrf import csrf_exempt, csrf_protect
@csrf_exempt
def upload_file_view(request):
request.upload_handlers.insert(0, ProgressBarUploadHandler())
return _upload_file_view(request)
@csrf_protect
def _upload_file_view(request):
... # Process request

View decorators

Django provides several decorators that can be applied to views to support various HTTP features.
Allowed HTTP methods
The decorators in django.views.decorators.http can be used to restrict access to views based on the request
method. These decorators will return a django.http.HttpResponseNotAllowed if the conditions are not
met.
require_http_methods(request_method_list)
Decorator to require that a view only accept particular request methods. Usage:
from django.views.decorators.http import require_http_methods
@require_http_methods(["GET", "POST"])
def my_view(request):
# I can assume now that only GET or POST requests make it this far
# ...
pass
Note that request methods should be in uppercase.
require_GET()
Decorator to require that a view only accept the GET method.
require_POST()
Decorator to require that a view only accept the POST method.
require_safe()
Decorator to require that a view only accept the GET and HEAD methods. These methods are commonly
considered "safe" because they should not have the significance of taking an action other than retrieving the
requested resource.
Note: Django will automatically strip the content of responses to HEAD requests while leaving the headers unchanged,
so you may handle HEAD requests exactly like GET requests in your views. Since some software, such
as link checkers, rely on HEAD requests, you might prefer using require_safe instead of require_GET.

Reverse resolution of URLs

A common need when working on a Django project is the possibility to obtain URLs in their final forms either
for embedding in generated content (views and assets URLs, URLs shown to the user, etc.) or for handling of the
navigation flow on the server side (redirections, etc.)
It is strongly desirable not having to hard-code these URLs (a laborious, non-scalable and error-prone strategy) or
having to devise ad-hoc mechanisms for generating URLs that are parallel to the design described by the URLconf
and as such in danger of producing stale URLs at some point.
In other words, what's needed is a DRY mechanism. Among other advantages it would allow evolution of the URL
design without having to go all over the project source code to search and replace outdated URLs.
The piece of information we have available as a starting point to get a URL is an identification (e.g. the name) of the
view in charge of handling it, other pieces of information that necessarily must participate in the lookup of the right
URL are the types (positional, keyword) and values of the view arguments.
Django provides a solution such that the URL mapper is the only repository of the URL design. You feed it with your
URLconf and then it can be used in both directions:
• Starting with a URL requested by the user/browser, it calls the right Django view providing any arguments it
might need with their values as extracted from the URL.
• Starting with the identification of the corresponding Django view plus the values of arguments that would be
passed to it, obtain the associated URL.
The first one is the usage we've been discussing in the previous sections. The second one is what is known as reverse
resolution of URLs, reverse URL matching, reverse URL lookup, or simply URL reversing.
Django provides tools for performing URL reversing that match the different layers where URLs are needed:
• In templates: Using the url template tag.
• In Python code: Using the django.core.urlresolvers.reverse() function.
• In higher level code related to handling of URLs of Django model instances: The get_absolute_url()
method.
Examples
Consider again this URLconf entry:
from django.conf.urls import url
from . import views
urlpatterns = [
#...
url(r'^articles/([0-9]{4})/$', views.year_archive, name='news-year-archive'),
#...
]
According to this design, the URL for the archive corresponding to year nnnn is /articles/nnnn/.
You can obtain these in template code by using:
<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a>
{# Or with the year in a template context variable: #}
<ul>
{% for yearvar in year_list %}
<li><a href="{% url 'news-year-archive' yearvar %}">{{ yearvar }} Archive</a></li>
{% endfor %}
</ul>
Or in Python code:
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
def redirect_to_year(request):
# ...
year = 2006
# ...
return HttpResponseRedirect(reverse('news-year-archive', args=(year,)))
If, for some reason, it was decided that the URLs where content for yearly article archives are published at should be
changed then you would only need to change the entry in the URLconf.
In some scenarios where views are of a generic nature, a many-to-one relationship might exist between URLs and
views. For these cases the view name isn't a good enough identifier for it when comes the time of reversing URLs.
Read the next section to know about the solution Django provides for this.
Naming URL patterns
In order to perform URL reversing, you'll need to use named URL patterns as done in the examples above. The
string used for the URL name can contain any characters you like. You are not restricted to valid Python names.
When you name your URL patterns, make sure you use names that are unlikely to clash with any other application's
choice of names. If you call your URL pattern comment, and another application does the same thing, there's no
guarantee which URL will be inserted into your template when you use this name.
Putting a prefix on your URL names, perhaps derived from the application name, will decrease the chances of collision.
We recommend something like myapp-comment instead of comment.

Including other URLconfs

At any point, your urlpatterns can "include" other URLconf modules. This essentially "roots" a set of URLs
below other ones.
For example, here's an excerpt of the URLconf for the DjangoWeb site itself. It includes a number of other URLconfs:
from django.conf.urls import include, url
urlpatterns = [
# ... snip ...
url(r'^community/', include('django_website.aggregator.urls')),
url(r'^contact/', include('django_website.contact.urls')),
# ... snip ...
]
Note that the regular expressions in this example don't have a $ (end-of-string match character) but do include a trailing
slash. Whenever Django encounters include() (django.conf.urls.include()), it chops off whatever part
of the URL matched up to that point and sends the remaining string to the included URLconf for further processing.
Another possibility is to include additional URL patterns by using a list of url() instances. For example, consider
this URLconf:
from django.conf.urls import include, url
from apps.main import views as main_views
from credit import views as credit_views
extra_patterns = [
url(r'^reports/(?P<id>[0-9]+)/$', credit_views.report),
url(r'^charge/$', credit_views.charge),
]
urlpatterns = [
url(r'^$', main_views.homepage),
url(r'^help/', include('apps.help.urls')),
url(r'^credit/', include(extra_patterns)),
]
In this example, the /credit/reports/ URL will be handled by the credit.views.report() Django view.
This can be used to remove redundancy from URLconfs where a single pattern prefix is used repeatedly. For example,
consider this URLconf:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^(?P<page_slug>\w+)-(?P<page_id>\w+)/history/$', views.history),
url(r'^(?P<page_slug>\w+)-(?P<page_id>\w+)/edit/$', views.edit),
url(r'^(?P<page_slug>\w+)-(?P<page_id>\w+)/discuss/$', views.discuss),
url(r'^(?P<page_slug>\w+)-(?P<page_id>\w+)/permissions/$', views.permissions),
]
We can improve this by stating the common path prefix only once and grouping the suffixes that differ:
from django.conf.urls import include, url
from . import views
urlpatterns = [
url(r'^(?P<page_slug>\w+)-(?P<page_id>\w+)/', include([
url(r'^history/$', views.history),
url(r'^edit/$', views.edit),
url(r'^discuss/$', views.discuss),
url(r'^permissions/$', views.permissions),
])),
]
Captured parameters
An included URLconf receives any captured parameters from parent URLconfs, so the following example is valid:
# In settings/urls/main.py
from django.conf.urls import include, url
urlpatterns = [
url(r'^(?P<username>\w+)/blog/', include('foo.urls.blog')),
]
# In foo/urls/blog.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.blog.index),
url(r'^archive/$', views.blog.archive),
]
In the above example, the captured "username" variable is passed to the included URLconf, as expected.
Passing extra options to view functions
URLconfs have a hook that lets you pass extra arguments to your view functions, as a Python dictionary.
The django.conf.urls.url() function can take an optional third argument which should be a dictionary of
extra keyword arguments to pass to the view function.
For example:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^blog/(?P<year>[0-9]{4})/$', views.year_archive, {'foo': 'bar'}),
]
In this example, for a request to /blog/2005/, Django will call views.year_archive(request,
year='2005', foo='bar').
This technique is used in the syndication framework to pass metadata and options to views.
Dealing with conflicts
It's possible to have a URL pattern which captures named keyword arguments, and also passes arguments with the
same names in its dictionary of extra arguments. When this happens, the arguments in the dictionary will be used
instead of the arguments captured in the URL.
Passing extra options to include()
Similarly, you can pass extra options to include(). When you pass extra options to include(), each line in the
included URLconf will be passed the extra options.
For example, these two URLconf sets are functionally identical:
Set one:
# main.py
from django.conf.urls import include, url
urlpatterns = [
url(r'^blog/', include('inner'), {'blogid': 3}),
]
# inner.py
from django.conf.urls import url
from mysite import views
urlpatterns = [
url(r'^archive/$', views.archive),
url(r'^about/$', views.about),
]
Set two:
# main.py
from django.conf.urls import include, url
from mysite import views
urlpatterns = [
url(r'^blog/', include('inner')),
]
# inner.py
from django.conf.urls import url
urlpatterns = [
url(r'^archive/$', views.archive, {'blogid': 3}),
url(r'^about/$', views.about, {'blogid': 3}),
]
Note that extra options will always be passed to every line in the included URLconf, regardless of whether the line's
view actually accepts those options as valid. For this reason, this technique is only useful if you're certain that every
view in the included URLconf accepts the extra options you're passing.

How Django processes a request

When a user requests a page from your Django-powered site, this is the algorithm the system follows to determine
which Python code to execute:
1. Django determines the root URLconf module to use. Ordinarily, this is the value of the ROOT_URLCONF
setting, but if the incoming HttpRequest object has an attribute called urlconf (set by middleware request
processing), its value will be used in place of the ROOT_URLCONF setting.
2. Django loads that Python module and looks for the variable urlpatterns. This should be a Python list of
django.conf.urls.url() instances.
3. Django runs through each URL pattern, in order, and stops at the first one that matches the requested URL.
4. Once one of the regexes matches, Django imports and calls the given view, which is a simple Python function
(or a class based view). The view gets passed the following arguments:
• An instance of HttpRequest.
• If the matched regular expression returned no named groups, then the matches from the regular expression
are provided as positional arguments.
• The keyword arguments are made up of any named groups matched by the regular expression, overridden
by any arguments specified in the optional kwargs argument to django.conf.urls.url().
5. If no regex matches, or if an exception is raised during any point in this process, Django invokes an appropriate
error-handling view. See Error handling below.
Example
Here's a sample URLconf:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^articles/2003/$', views.special_case_2003),
url(r'^articles/([0-9]{4})/$', views.year_archive),
url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]
Notes:
• To capture a value from the URL, just put parenthesis around it.
• There's no need to add a leading slash, because every URL has that. For example, it's ^articles, not
^/articles.
• The 'r' in front of each regular expression string is optional but recommended. It tells Python that a string is
"raw" – that nothing in the string should be escaped. See Dive Into Python's explanation.
Example requests:
• A request to /articles/2005/03/ would match the third entry in the list. Django would call the function
views.month_archive(request, '2005', '03').
• /articles/2005/3/ would not match any URL patterns, because the third entry in the list requires two
digits for the month.
• /articles/2003/ would match the first pattern in the list, not the second one, because the patterns are
tested in order, and the first one is the first test to pass. Feel free to exploit the ordering to insert special cases
like this.
• /articles/2003 would not match any of these patterns, because each pattern requires that the URL end
with a slash.
• /articles/2003/03/03/ would match the final pattern. Django would call the function
views.article_detail(request, '2003', '03', '03').

2015年1月27日火曜日

FeliCa

学生証にはFeliCaが搭載されていたのと,ICカードリーダー(RC-S620S)が転がっていたのでさくさくと.
これはカードのIDmを使って認証を行っています.でも,これはEthernetのMACアドレスみたいなもんなのでかぶることはないんでしょうけど,登録作業が結構面倒.IDmはカードが変わればもちろん変わるので,再発行時なんかは面倒くさい.
それと同時に,あるものを依頼されたってのもあって,なんかもう一歩踏み込んだところのデータを見たい!ということで,ちょっと調査してみました.

FeliCaでは,システムコードとかエリア,サービスコード,ブロックとかいろいろ出てきますが,まあちょっとまとめてみると…間違ってたらごめんなさいね.

システムコード
カードに乗っているシステムを識別するコード.一枚のカードにいろんなシステム(SuicaとかWaonとか)を入れることができるので,その識別用.(Suicaは0x300,nanacoは0xC704だった)一つのIDmを持ち,複数のサービスを持つ.

サービスコード
システムに乗っているサービスを識別するコード.乗車履歴だとか,残高だとか各サービスに一つづつ.
アクセス属性は,このコードの下6Bitを見ることで分かる.非保護領域は最下位Bitが1.他にもランダムアクセスとか,アクセス方法についての情報もある.複数のブロックを持つ.

ブロック
実際にデータが格納される箱.プレステのメモカみたいなもんで,16Byte.この箱単位でアクセスする.
サービスごとにインデックスが0から始まる.

詳しくは,FeliCaカード ユーザーズマニュアルってのをSonyが公開してるのでそれで.



実際のインターフェイスを見ると,

1.システムコードからIDmを取得.
2.IDmとサービスコード,ブロックのインデックスで読み書き.

の2段階が必要になってくる.
保護領域はさらに認証が必要ですけど,非保護領域だったらこれだけでOK.

が,

そもそもシステムコードもサービスコードも分からないし,ましてや中身なんてどんなフォーマットで入っているか分からないのですよ.なので全検索&全読出&解・析!.

サービスコードは,Pollingコマンドを使って検索する.コードは2Byteなので全数やっても大した時間はかからないだろう.どうやら,バイトごとにワイルドカード(0xFF)が使えるようなので,0x00FF,0x01FF…0xFEFFと0xFF00,0xFF01…0xFFFEを探れば出てくるでしょう.あとは出てきたのを組み合わせれば出ますね.

システムコードは,RequestServiceコマンドを使います.サービスコードの下5Bitはアクセス属性で,16パターン.そのうち認証なしで覗けるのは半分.10Bit × 8を回せば出る.

あとは,ブロックを読めるだけ読んで表示するなり,記録するなりして解析する.

コマンドは,FeliCaのカードに送るコマンドを,カードリーダーに送るコマンドでカプセル化しなきゃいけない.
カードリーダーのコマンドは,仕様書通りに作って….


でてきたでてきたw
どうやら,学籍番号と,カードの有効期限っぽいのは見ることができました.
んじゃ,電子錠の改良と,依頼の品を作りましょうか.