OSDN Git Service

cookie escape
[pybbs/pybbs.git] / index.py
1
2 import os.path
3 import tornado.auth
4 import tornado.escape
5 import tornado.web
6 from tinydb import TinyDB,Query,where
7 from tinydb.operations import delete
8 from datetime import datetime
9
10 class BaseHandler(tornado.web.RequestHandler):
11     def get_current_user(self):
12         user = self.get_secure_cookie('admin_user')
13         return tornado.escape.utf8(user)
14     
15     def set_current_user(self,username):
16         self.set_secure_cookie('admin_user',username)
17         
18     def clear_current_user(self):
19         self.clear_cookie('admin_user')
20
21 class IndexHandler(BaseHandler):
22     def get(self,dbname,page='0'):
23         params = self.application.db.get(where('kinds') == 'conf')
24         if params['mentenance'] == True:
25             self.render('mentenance.htm',title=params['title'],db=dbname)
26         if self.application.collection(dbname) == False:
27             if self.current_user == b'admin':
28                 self.application.db.table(dbname)
29             else:
30                 self.render('regist.htm',content='urlが見つかりません')
31         i = params['count']      
32         na = tornado.escape.url_unescape(self.get_cookie('username'))
33         pos = self.application.gpos(dbname,page)
34         table = self.application.db.table(dbname)
35         start = (pos-1)*i
36         if start < 0:
37             start = len(table)-i
38             if start < 0:
39                 start = 0
40         rec = sorted(table.all(),key=lambda x: x['number'])[start:start+i]
41         if len(table) >= 10*i:
42             self.render('modules/full.htm',position=pos,records=rec,data=params,db=dbname)  
43         self.render('modules/index.htm',position=pos,records=rec,data=params,username=na,db=dbname)
44         
45 class LoginHandler(BaseHandler):
46     def get(self):
47         self.render('login.htm')
48         
49     def post(self):
50         pw = self.application.db.get(where('kinds') == 'conf')
51         if self.get_argument('password') == pw['password']:
52             self.set_current_user('admin')
53         dbname = self.get_argument('record')
54         self.redirect('/'+dbname+'/admin/0/')
55         
56 class LogoutHandler(BaseHandler):
57     def get(self):
58         self.clear_current_user()
59         self.redirect('/login')
60         
61 class NaviHandler(tornado.web.RequestHandler):
62     def get(self):
63         self.render('top.htm',coll=sorted(self.name()),full=self.full)
64         
65     def name(self):
66         for x in self.application.db.tables():
67             if x != '_default':
68                 yield x
69                 
70     def full(self,dbname):
71         if dbname in self.application.db.tables():
72             i = 10*self.application.db.get(where('kinds') == 'conf')['count']
73             table = self.application.db.table(dbname)
74             if len(table) >= i:
75                 return True
76         return False
77
78 class TitleHandler(NaviHandler):
79     def get(self):
80         self.render('title.htm',coll=self.name(),full=self.full,
81                     count=self.count,title=self.title,update=self.update)            
82
83     def count(self,dbname):
84         if dbname in self.application.db.tables():
85             return len(self.application.db.table(dbname))
86         else:
87             return ''
88
89     def title(self,dbname):
90         if dbname in self.application.db.tables():
91             table = self.application.db.table(dbname)
92             if table.contains(where('number') == 1) == True:
93                 dic = table.get(where('number') == 1)
94                 return dic['title']
95             else:
96                 return ''
97             
98     def update(self,dbname):
99         if dbname in self.application.db.tables():
100             table = self.application.db.table(dbname)
101             i = len(table)
102             if i == 0:
103                 return ''
104             else:
105                 rec = sorted(table.all(),key=lambda x: x['number'])
106                 return rec[i-1]['date']
107         
108 class RegistHandler(tornado.web.RequestHandler):
109     def post(self,dbname):
110         if self.application.collection(dbname) == False:
111             self.render('regist.htm',content='urlが存在しません')
112         words = ['<link','<script','<style','<img']
113         out = ['ばか','死ね','あほ']
114         na = self.get_argument('name')
115         sub = self.get_argument('title')
116         com = self.get_argument('comment')
117         text = ''
118         i = 0
119         error = ''
120         for line in com.splitlines(True):
121             for word in words:
122                 if word in line:
123                     error = error + u'タグ違反.('+word+')'       
124             text = text+'<p>'+line
125             i += len(line)
126         for word in out:
127             if word in text:
128                 error = error + u'禁止ワード.'
129                 break
130         pw = self.get_argument('password')
131         if na == '':
132             na = u'誰かさん'
133         if sub == '':
134             sub = u'タイトルなし.'
135         if i == 0:
136             error = error + u'本文がありません.'
137         elif i > 1000:
138             error = error +u'文字数が1,000をこえました.'
139         article = self.application.db.table(dbname)
140         if len(article) == 0:
141             no = 1
142         else:
143             item = article.all()[len(article)-1]
144             no = item['number']+1
145         if error == '':
146             reg = {'number':no,'name':na,'title':sub,'comment':text,'password':pw,'date':datetime.now().strftime('%Y/%D:%M')}
147             article.insert(reg)
148             self.set_cookie('username',tornado.escape.url_escape(na))
149             self.redirect('/'+dbname+'#article')
150         else:
151             self.render('regist.htm',content=error)
152
153 class AdminHandler(BaseHandler):
154     @tornado.web.authenticated               
155     def get(self,dbname,page='0'):
156         if dbname == '':
157             dbname = self.get_argument('record','')
158         if self.application.collection(dbname) == False:
159             self.render('regist.htm',content='urlが見つかりません')
160         table = self.application.db.table(dbname) 
161         rec = sorted(table.all(),key=lambda x: x['number'])                   
162         mente = self.application.db.get(where('kinds') == 'conf')
163         if mente['mentenance'] == True:
164             check = 'checked=checked'
165         else:
166             check = ''
167         pos = self.application.gpos(dbname,page)
168         self.render('modules/admin.htm',position=pos,records=rec,mente=check,password=mente['password'],db=dbname)
169
170 class AdminConfHandler(BaseHandler):
171     @tornado.web.authenticated
172     def post(self,dbname,func):
173         if func == 'set':
174             if self.get_argument('mente','') == 'on':
175                 mente = True
176             else:
177                 mente = False  
178             word = self.get_argument('pass','')
179             if word == '':
180                 self.render('regist.htm',content='パスワードを設定してください')
181             else:
182                 self.application.db.update({'mentenance':mente,'password':word},where('kinds') == 'conf')     
183         elif func == 'del':
184             table = self.application.db.table(dbname)
185             for x in self.get_arguments('item'):
186                 table.remove(where('number') == int(x))
187         self.redirect('/'+dbname+'/admin/0/')
188           
189 class UserHandler(tornado.web.RequestHandler):
190     def post(self,dbname):
191         num = int(self.get_argument('number'))
192         pas = self.get_argument('password')
193         table = self.application.db.table(dbname)
194         qwr = Query()
195         obj = table.get(qwr.number == num)
196         if obj and(obj['password'] == pas):
197             table.remove(qwr.number == num)
198         self.redirect('/'+dbname)
199       
200 class SearchHandler(tornado.web.RequestHandler):       
201     def post(self,dbname):
202         word = self.get_argument('word1')
203         radiobox = self.get_argument('filter')
204         self.set_cookie('search',word)
205         table = self.application.db.table(dbname)            
206         self.render('modules/search.htm',records=table.search(where(radiobox).matches(word)),word1=word,db=dbname)
207     
208     def get(self,dbname):
209         word = self.get_cookie('search')
210         self.render('modules/search.htm',records={},word1=word,db=dbname)
211         
212 class FooterModule(tornado.web.UIModule):
213     def render(self,number,url,link):
214         return self.render_string('modules/footer.htm',index=number,url=url,link=link)
215     
216 class Application(tornado.web.Application):    
217     def __init__(self):
218         self.db = TinyDB('static/db/db.json')
219         handlers = [(r'/',NaviHandler),(r'/login',LoginHandler),(r'/logout',LogoutHandler),(r'/title',TitleHandler),
220                     (r'/([a-zA-Z0-9_]+)',IndexHandler),(r'/([a-zA-Z0-9_]+)/([0-9]+)/',IndexHandler),
221                     (r'/([a-zA-Z0-9_]+)/admin/([0-9]+)/',AdminHandler),(r'/([a-zA-Z0-9_]+)/admin/([a-z]+)/',AdminConfHandler),(r'/([a-zA-Z0-9_]+)/userdel',UserHandler),
222                     (r'/([a-zA-Z0-9_]+)/search',SearchHandler),(r'/([a-zA-Z0-9_]+)/regist',RegistHandler)]
223         settings = {'template_path':os.path.join(os.path.dirname(__file__),'pybbs'),
224                         'static_path':os.path.join(os.path.dirname(__file__),'static'),
225                         'ui_modules':{'Footer':FooterModule},
226                         'cookie_secret':'bZJc2sWbQLKos6GkHn/VB9oXwQt8SOROkRvJ5/xJ89E=',
227                         'xsrf_cookies':True,
228                         #'debug':True,
229                         'login_url':'/login'
230                         }
231         tornado.web.Application.__init__(self,handlers,**settings)
232  
233     def gpos(self,dbname,page):
234         params = self.db.get(where('kinds') == 'conf')
235         pos = int(page)
236         if pos <= 0:
237             pos = 0
238         elif (pos-1)*params['count'] >= len(self.db.table(dbname)):
239             pos = 0
240         return pos
241     
242     def collection(self,name):
243         for x in self.db.tables():
244             if x == name:
245                 return True
246         else:
247             return False
248         
249 app = Application()
250