Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 128 lines (98 sloc) 5.1 kb
168124b @jiangxin add DOCTYPE, so quanta can detect file type automatically
jiangxin authored
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!--
3 <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
4 "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
5 -->
6
cfecb0c @jiangxin initial
jiangxin authored
7 <!-- =================================================================== -->
8 <sect1 id="psm.security">
102242c @jiangxin spelling check
jiangxin authored
9 <title>pySvnManager 本身的认证和授权</title>
cfecb0c @jiangxin initial
jiangxin authored
10
102242c @jiangxin spelling check
jiangxin authored
11 <para>pySvnManager 作为 Subversion 授权管理的软件,如果本身没有认证和授权机制,
12 就会成为系统最大的漏洞。为此我们迫切需要为我们的应用增加认证和授权。还好,
13 这实现起来并不是很困难。</para>
14
cfecb0c @jiangxin initial
jiangxin authored
15 <!-- ================================================================= -->
16 <sect2 id="psm.security.initial">
102242c @jiangxin spelling check
jiangxin authored
17 <title>为 BaseController 增加 __before__ 方法</title>
cfecb0c @jiangxin initial
jiangxin authored
18
102242c @jiangxin spelling check
jiangxin authored
19 <para>__before__ 是 WSGIController 特有的方法,在 Action 执行之前执行,
cfecb0c @jiangxin initial
jiangxin authored
20 可以用于初始化变量,以及做权限控制。</para>
21
102242c @jiangxin spelling check
jiangxin authored
22 <para>BaseController 是所有控制器的基类,在该基类增加授权功能,
23 会自动为其他控制器所使用。BaseController 的代码在文件 <filename>lib/base.py</filename> 中。</para>
cfecb0c @jiangxin initial
jiangxin authored
24
5ee683c @jiangxin screen -> programlisting
jiangxin authored
25 <programlisting>
cfecb0c @jiangxin initial
jiangxin authored
26 class BaseController(WSGIController):
27 requires_auth = []
28
29 def __before__(self, action):
30 if isinstance(self.requires_auth, bool) and not self.requires_auth:
31 pass
32 elif isinstance(self.requires_auth, (list, tuple)) and \
33 not action in self.requires_auth:
34 pass
35 else:
36 if 'user' not in session:
37 session['path_before_login'] = request.path_info
38 session.save()
39 return redirect_to(h.url_for(controller='security'))
5ee683c @jiangxin screen -> programlisting
jiangxin authored
40 </programlisting>
cfecb0c @jiangxin initial
jiangxin authored
41
102242c @jiangxin spelling check
jiangxin authored
42 <para>从BaseController 继承的类,可以设置 requires_auth 来增加授权。
43 requires_auth 可以为 True 或者是一个包含要进行授权的动作列表。如果需要授权,
44 会检查 session 中是否包含登录信息否则跳转到登录页面(security控制器)。</para>
cfecb0c @jiangxin initial
jiangxin authored
45
46 </sect2>
47
48 <!-- ================================================================= -->
49 <sect2 id="psm.security.enable">
50 <title>为控制器中增加授权</title>
51
52 <para>在需要增加授权的控制器中增加requires_auth的属性。</para>
53
5ee683c @jiangxin screen -> programlisting
jiangxin authored
54 <programlisting>
cfecb0c @jiangxin initial
jiangxin authored
55 class CheckController(BaseController):
56 requires_auth = True
5ee683c @jiangxin screen -> programlisting
jiangxin authored
57 </programlisting>
cfecb0c @jiangxin initial
jiangxin authored
58
59 </sect2>
60
61 <!-- ================================================================= -->
62 <sect2 id="psm.security.controller">
102242c @jiangxin spelling check
jiangxin authored
63 <title>Security 控制器实现</title>
cfecb0c @jiangxin initial
jiangxin authored
64
65 <para>Security控制器用于实现用户的登录和退出。要为Security控制器增加
102242c @jiangxin spelling check
jiangxin authored
66 login 和 logout方法,并且增加登录视图模板。流程见:<xref linkend="psm.security.controller.fig1"/></para>
c98a088 @jiangxin add image link
jiangxin authored
67
68 <sidebar>
69 <figure id="psm.security.controller.fig1">
70 <title>控制器check的MVC框架示意图</title>
71 <graphic fileref="images/security_controller.png"/>
72 </figure>
73 </sidebar>
cfecb0c @jiangxin initial
jiangxin authored
74
75 <para>具体实现参见代码。</para>
76
77 </sect2>
78
79 <!-- ================================================================= -->
80 <sect2 id="psm.security.authz">
102242c @jiangxin spelling check
jiangxin authored
81 <title>pySvnManager 授权</title>
cfecb0c @jiangxin initial
jiangxin authored
82
102242c @jiangxin spelling check
jiangxin authored
83 <para>在 SvnAuthz 类的实现中,在 svnauthz 文件中为版本库增加了管理员设置,
84 来进行管理员的身份验证。我们就利用同样的代码对 pySvnManager 进行授权验证。</para>
85
86 <para>具体实现参见代码。</para>
cfecb0c @jiangxin initial
jiangxin authored
87
88 </sect2>
89
90 <!-- ================================================================= -->
91 <sect2 id="psm.security.unittest">
92 <title>添加认证后的单元测试</title>
93
94 <para>添加授权后,执行nosetests,会发现控制器的单元测试报错。
95 因为没有经过授权所有页面的输出都是“尚未授权”。实际上,
96 只要在每一个测试用例运行之前,访问 security控制器的login方法,
97 以实现登录,设置正确的session,则后续访问会自动带上cookie,
98 得到正确的授权页面。</para>
99
100 <para>在控制器的测试用例基类TestController中加上login方法,以简化登录调用:</para>
101
5ee683c @jiangxin screen -> programlisting
jiangxin authored
102 <programlisting><![CDATA[
cfecb0c @jiangxin initial
jiangxin authored
103 class TestController(TestCase):
104 ...
105 def login(self, username, password=""):
106 res = self.app.get(url_for(controller='security'))
107 form = res.forms[0]
108 form['username'] = username
109 if not password:
110 d = eval(config.get('test_users', {}))
111 password = d.get(username,'')
112 form['password'] = password
113 form.submit()
5ee683c @jiangxin screen -> programlisting
jiangxin authored
114 ]]></programlisting>
cfecb0c @jiangxin initial
jiangxin authored
115
116 <para>在测试用例中调用login方法:</para>
117
5ee683c @jiangxin screen -> programlisting
jiangxin authored
118 <programlisting><![CDATA[
cfecb0c @jiangxin initial
jiangxin authored
119 self.login('root')
120 res = self.app.get(url_for(controller='check'))
121 assert res.status == 200
122 assert '''<input type="submit" name="submit" value='Check Permissions'>''' in res.body
123 assert res.c.reposlist == ['/', u'repos1', u'repos2', u'repos3', u'document']
5ee683c @jiangxin screen -> programlisting
jiangxin authored
124 ]]></programlisting>
cfecb0c @jiangxin initial
jiangxin authored
125
126 </sect2>
127
128 </sect1>
Something went wrong with that request. Please try again.