Show More
@@ -1,97 +1,128 b'' | |||||
1 | import logging |
|
1 | import logging | |
2 |
|
2 | |||
3 | from pylons import request, response, session, tmpl_context as c, url, app_globals as g |
|
3 | from pylons import request, response, session, tmpl_context as c, url, app_globals as g | |
4 | from pylons.controllers.util import abort, redirect |
|
4 | from pylons.controllers.util import abort, redirect | |
5 |
|
5 | |||
6 | from pylons_app.lib.base import BaseController, render |
|
6 | from pylons_app.lib.base import BaseController, render | |
7 | import os |
|
7 | import os | |
8 | from mercurial import ui, hg |
|
8 | from mercurial import ui, hg | |
9 | from mercurial.error import RepoError |
|
9 | from mercurial.error import RepoError | |
10 | from ConfigParser import ConfigParser |
|
10 | from ConfigParser import ConfigParser | |
11 | from pylons_app.lib import auth |
|
11 | from pylons_app.lib import auth | |
|
12 | from pylons_app.model.forms import LoginForm | |||
|
13 | import formencode | |||
|
14 | import formencode.htmlfill as htmlfill | |||
12 | log = logging.getLogger(__name__) |
|
15 | log = logging.getLogger(__name__) | |
13 |
|
16 | |||
14 | class AdminController(BaseController): |
|
17 | class AdminController(BaseController): | |
15 |
|
18 | |||
16 |
|
19 | |||
17 | def __before__(self): |
|
20 | def __before__(self): | |
18 | c.staticurl = g.statics |
|
21 | c.staticurl = g.statics | |
19 |
c.admin_user = |
|
22 | c.admin_user = session.get('admin_user') | |
|
23 | c.admin_username = session.get('admin_username') | |||
20 |
|
24 | |||
21 | def index(self): |
|
25 | def index(self): | |
22 | # Return a rendered template |
|
26 | # Return a rendered template | |
|
27 | if request.POST: | |||
|
28 | #import Login Form validator class | |||
|
29 | login_form = LoginForm() | |||
|
30 | ||||
|
31 | try: | |||
|
32 | c.form_result = login_form.to_python(dict(request.params)) | |||
|
33 | if auth.authfunc(None, c.form_result['username'], c.form_result['password']) and\ | |||
|
34 | c.form_result['username'] == 'admin': | |||
|
35 | session['admin_user'] = True | |||
|
36 | session['admin_username'] = c.form_result['username'] | |||
|
37 | session.save() | |||
|
38 | return redirect(url('admin_home')) | |||
|
39 | else: | |||
|
40 | raise formencode.Invalid('Login Error', None, None, | |||
|
41 | error_dict={'username':'invalid login', | |||
|
42 | 'password':'invalid password'}) | |||
|
43 | ||||
|
44 | except formencode.Invalid, error: | |||
|
45 | c.form_result = error.value | |||
|
46 | c.form_errors = error.error_dict or {} | |||
|
47 | html = render('/admin.html') | |||
|
48 | ||||
|
49 | return htmlfill.render( | |||
|
50 | html, | |||
|
51 | defaults=c.form_result, | |||
|
52 | encoding="UTF-8" | |||
|
53 | ) | |||
23 | return render('/admin.html') |
|
54 | return render('/admin.html') | |
24 |
|
55 | |||
25 | def repos_manage(self): |
|
56 | def repos_manage(self): | |
26 | return render('/repos_manage.html') |
|
57 | return render('/repos_manage.html') | |
27 |
|
58 | |||
28 | def users_manage(self): |
|
59 | def users_manage(self): | |
29 | conn, cur = auth.get_sqlite_conn_cur() |
|
60 | conn, cur = auth.get_sqlite_conn_cur() | |
30 | cur.execute('SELECT * FROM users') |
|
61 | cur.execute('SELECT * FROM users') | |
31 | c.users_list = cur.fetchall() |
|
62 | c.users_list = cur.fetchall() | |
32 | return render('/users_manage.html') |
|
63 | return render('/users_manage.html') | |
33 |
|
64 | |||
34 | def manage_hgrc(self): |
|
65 | def manage_hgrc(self): | |
35 | pass |
|
66 | pass | |
36 |
|
67 | |||
37 | def hgrc(self, dirname): |
|
68 | def hgrc(self, dirname): | |
38 | filename = os.path.join(dirname, '.hg', 'hgrc') |
|
69 | filename = os.path.join(dirname, '.hg', 'hgrc') | |
39 | return filename |
|
70 | return filename | |
40 |
|
71 | |||
41 | def add_repo(self, new_repo): |
|
72 | def add_repo(self, new_repo): | |
42 |
|
73 | |||
43 |
|
74 | |||
44 | #extra check it can be add since it's the command |
|
75 | #extra check it can be add since it's the command | |
45 | if new_repo == '_admin': |
|
76 | if new_repo == '_admin': | |
46 | c.msg = 'DENIED' |
|
77 | c.msg = 'DENIED' | |
47 | c.new_repo = '' |
|
78 | c.new_repo = '' | |
48 | return render('add.html') |
|
79 | return render('add.html') | |
49 |
|
80 | |||
50 | new_repo = new_repo.replace(" ", "_") |
|
81 | new_repo = new_repo.replace(" ", "_") | |
51 | new_repo = new_repo.replace("-", "_") |
|
82 | new_repo = new_repo.replace("-", "_") | |
52 |
|
83 | |||
53 | try: |
|
84 | try: | |
54 | self._create_repo(new_repo) |
|
85 | self._create_repo(new_repo) | |
55 | c.new_repo = new_repo |
|
86 | c.new_repo = new_repo | |
56 | c.msg = 'added repo' |
|
87 | c.msg = 'added repo' | |
57 | except Exception as e: |
|
88 | except Exception as e: | |
58 | c.new_repo = 'Exception when adding: %s' % new_repo |
|
89 | c.new_repo = 'Exception when adding: %s' % new_repo | |
59 | c.msg = str(e) |
|
90 | c.msg = str(e) | |
60 |
|
91 | |||
61 | return render('add.html') |
|
92 | return render('add.html') | |
62 |
|
93 | |||
63 | def _check_repo(self, repo_name): |
|
94 | def _check_repo(self, repo_name): | |
64 | p = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) |
|
95 | p = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) | |
65 | config_path = os.path.join(p, 'hgwebdir.config') |
|
96 | config_path = os.path.join(p, 'hgwebdir.config') | |
66 |
|
97 | |||
67 | cp = ConfigParser() |
|
98 | cp = ConfigParser() | |
68 |
|
99 | |||
69 | cp.read(config_path) |
|
100 | cp.read(config_path) | |
70 | repos_path = cp.get('paths', '/').replace("**", '') |
|
101 | repos_path = cp.get('paths', '/').replace("**", '') | |
71 |
|
102 | |||
72 | if not repos_path: |
|
103 | if not repos_path: | |
73 | raise Exception('Could not read config !') |
|
104 | raise Exception('Could not read config !') | |
74 |
|
105 | |||
75 | self.repo_path = os.path.join(repos_path, repo_name) |
|
106 | self.repo_path = os.path.join(repos_path, repo_name) | |
76 |
|
107 | |||
77 | try: |
|
108 | try: | |
78 | r = hg.repository(ui.ui(), self.repo_path) |
|
109 | r = hg.repository(ui.ui(), self.repo_path) | |
79 | hg.verify(r) |
|
110 | hg.verify(r) | |
80 | #here we hnow that repo exists it was verified |
|
111 | #here we hnow that repo exists it was verified | |
81 | log.info('%s repo is already created', repo_name) |
|
112 | log.info('%s repo is already created', repo_name) | |
82 | raise Exception('Repo exists') |
|
113 | raise Exception('Repo exists') | |
83 | except RepoError: |
|
114 | except RepoError: | |
84 | log.info('%s repo is free for creation', repo_name) |
|
115 | log.info('%s repo is free for creation', repo_name) | |
85 | #it means that there is no valid repo there... |
|
116 | #it means that there is no valid repo there... | |
86 | return True |
|
117 | return True | |
87 |
|
118 | |||
88 |
|
119 | |||
89 | def _create_repo(self, repo_name): |
|
120 | def _create_repo(self, repo_name): | |
90 | if repo_name in [None, '', 'add']: |
|
121 | if repo_name in [None, '', 'add']: | |
91 | raise Exception('undefined repo_name of repo') |
|
122 | raise Exception('undefined repo_name of repo') | |
92 |
|
123 | |||
93 | if self._check_repo(repo_name): |
|
124 | if self._check_repo(repo_name): | |
94 | log.info('creating repo %s in %s', repo_name, self.repo_path) |
|
125 | log.info('creating repo %s in %s', repo_name, self.repo_path) | |
95 | cmd = """mkdir %s && hg init %s""" \ |
|
126 | cmd = """mkdir %s && hg init %s""" \ | |
96 | % (self.repo_path, self.repo_path) |
|
127 | % (self.repo_path, self.repo_path) | |
97 | os.popen(cmd) |
|
128 | os.popen(cmd) |
@@ -1,110 +1,108 b'' | |||||
1 | import sqlite3 |
|
1 | import sqlite3 | |
2 | import os |
|
2 | import os | |
3 | import logging |
|
3 | import logging | |
4 | from os.path import dirname as dn |
|
4 | from os.path import dirname as dn | |
5 | from datetime import datetime |
|
5 | from datetime import datetime | |
6 | import crypt |
|
6 | import crypt | |
7 |
|
7 | |||
8 | log = logging.getLogger(__name__) |
|
8 | log = logging.getLogger(__name__) | |
9 | ROOT = dn(dn(dn(os.path.realpath(__file__)))) |
|
9 | ROOT = dn(dn(dn(os.path.realpath(__file__)))) | |
10 |
|
10 | |||
11 | def get_sqlite_conn_cur(): |
|
11 | def get_sqlite_conn_cur(): | |
12 | conn = sqlite3.connect(os.path.join(ROOT, 'auth.sqlite')) |
|
12 | conn = sqlite3.connect(os.path.join(ROOT, 'auth.sqlite')) | |
13 | cur = conn.cursor() |
|
13 | cur = conn.cursor() | |
14 | return conn, cur |
|
14 | return conn, cur | |
15 |
|
15 | |||
16 | def authfunc(environ, username, password): |
|
16 | def authfunc(environ, username, password): | |
17 | conn, cur = get_sqlite_conn_cur() |
|
17 | conn, cur = get_sqlite_conn_cur() | |
18 | password_crypt = crypt.crypt(password, '6a') |
|
18 | password_crypt = crypt.crypt(password, '6a') | |
19 |
|
19 | |||
20 | try: |
|
20 | try: | |
21 | cur.execute("SELECT * FROM users WHERE username=?", (username,)) |
|
21 | cur.execute("SELECT * FROM users WHERE username=?", (username,)) | |
22 | data = cur.fetchone() |
|
22 | data = cur.fetchone() | |
23 | except sqlite3.OperationalError as e: |
|
23 | except sqlite3.OperationalError as e: | |
24 | data = None |
|
24 | data = None | |
25 | log.error(e) |
|
25 | log.error(e) | |
26 |
|
||||
27 | if data: |
|
26 | if data: | |
28 | if data[3]: |
|
27 | if data[3]: | |
29 | if data[1] == username and data[2] == password_crypt: |
|
28 | if data[1] == username and data[2] == password_crypt: | |
30 | log.info('user %s authenticated correctly', username) |
|
29 | log.info('user %s authenticated correctly', username) | |
31 |
|
30 | if environ: | ||
32 | http_accept = environ.get('HTTP_ACCEPT') |
|
31 | http_accept = environ.get('HTTP_ACCEPT') | |
33 |
|
32 | |||
34 | if http_accept.startswith('application/mercurial') or \ |
|
33 | if http_accept.startswith('application/mercurial') or \ | |
35 | environ['PATH_INFO'].find('raw-file') != -1: |
|
34 | environ['PATH_INFO'].find('raw-file') != -1: | |
36 | cmd = environ['PATH_INFO'] |
|
35 | cmd = environ['PATH_INFO'] | |
37 | for qry in environ['QUERY_STRING'].split('&'): |
|
36 | for qry in environ['QUERY_STRING'].split('&'): | |
38 | if qry.startswith('cmd'): |
|
37 | if qry.startswith('cmd'): | |
39 | cmd += "|" + qry |
|
38 | cmd += "|" + qry | |
40 |
|
||||
41 | try: |
|
|||
42 | cur.execute('''INSERT INTO |
|
|||
43 | user_logs |
|
|||
44 | VALUES(?,?,?,?)''', |
|
|||
45 | (None, data[0], cmd, datetime.now())) |
|
|||
46 | conn.commit() |
|
|||
47 | except Exception as e: |
|
|||
48 | conn.rollback() |
|
|||
49 | log.error(e) |
|
|||
50 |
|
||||
51 |
|
39 | |||
|
40 | try: | |||
|
41 | cur.execute('''INSERT INTO | |||
|
42 | user_logs | |||
|
43 | VALUES(?,?,?,?)''', | |||
|
44 | (None, data[0], cmd, datetime.now())) | |||
|
45 | conn.commit() | |||
|
46 | except Exception as e: | |||
|
47 | conn.rollback() | |||
|
48 | log.error(e) | |||
|
49 | ||||
52 | return True |
|
50 | return True | |
53 | else: |
|
51 | else: | |
54 | log.error('user %s is disabled', username) |
|
52 | log.error('user %s is disabled', username) | |
55 |
|
53 | |||
56 | return False |
|
54 | return False | |
57 |
|
55 | |||
58 | def create_user_table(): |
|
56 | def create_user_table(): | |
59 | ''' |
|
57 | ''' | |
60 | Create a auth database |
|
58 | Create a auth database | |
61 | ''' |
|
59 | ''' | |
62 | conn, cur = get_sqlite_conn_cur() |
|
60 | conn, cur = get_sqlite_conn_cur() | |
63 | try: |
|
61 | try: | |
64 | log.info('creating table %s', 'users') |
|
62 | log.info('creating table %s', 'users') | |
65 | cur.execute('''DROP TABLE IF EXISTS users ''') |
|
63 | cur.execute('''DROP TABLE IF EXISTS users ''') | |
66 | cur.execute('''CREATE TABLE users |
|
64 | cur.execute('''CREATE TABLE users | |
67 | (id INTEGER PRIMARY KEY AUTOINCREMENT, |
|
65 | (id INTEGER PRIMARY KEY AUTOINCREMENT, | |
68 | username TEXT, |
|
66 | username TEXT, | |
69 | password TEXT, |
|
67 | password TEXT, | |
70 | active INTEGER)''') |
|
68 | active INTEGER)''') | |
71 | log.info('creating table %s', 'user_logs') |
|
69 | log.info('creating table %s', 'user_logs') | |
72 | cur.execute('''DROP TABLE IF EXISTS user_logs ''') |
|
70 | cur.execute('''DROP TABLE IF EXISTS user_logs ''') | |
73 | cur.execute('''CREATE TABLE user_logs |
|
71 | cur.execute('''CREATE TABLE user_logs | |
74 | (id INTEGER PRIMARY KEY AUTOINCREMENT, |
|
72 | (id INTEGER PRIMARY KEY AUTOINCREMENT, | |
75 | user_id INTEGER, |
|
73 | user_id INTEGER, | |
76 | last_action TEXT, |
|
74 | last_action TEXT, | |
77 | last_action_date DATETIME)''') |
|
75 | last_action_date DATETIME)''') | |
78 | conn.commit() |
|
76 | conn.commit() | |
79 | except: |
|
77 | except: | |
80 | conn.rollback() |
|
78 | conn.rollback() | |
81 | raise |
|
79 | raise | |
82 |
|
80 | |||
83 | cur.close() |
|
81 | cur.close() | |
84 |
|
82 | |||
85 | def create_user(username, password): |
|
83 | def create_user(username, password): | |
86 | conn, cur = get_sqlite_conn_cur() |
|
84 | conn, cur = get_sqlite_conn_cur() | |
87 | password_crypt = crypt.crypt(password, '6a') |
|
85 | password_crypt = crypt.crypt(password, '6a') | |
88 | cur_date = datetime.now() |
|
86 | cur_date = datetime.now() | |
89 | log.info('creating user %s', username) |
|
87 | log.info('creating user %s', username) | |
90 | try: |
|
88 | try: | |
91 | cur.execute('''INSERT INTO users values (?,?,?,?) ''', |
|
89 | cur.execute('''INSERT INTO users values (?,?,?,?) ''', | |
92 | (None, username, password_crypt, 1,)) |
|
90 | (None, username, password_crypt, 1,)) | |
93 | conn.commit() |
|
91 | conn.commit() | |
94 | except: |
|
92 | except: | |
95 | conn.rollback() |
|
93 | conn.rollback() | |
96 | raise |
|
94 | raise | |
97 |
|
95 | |||
98 | if __name__ == "__main__": |
|
96 | if __name__ == "__main__": | |
99 | create_user_table() |
|
97 | create_user_table() | |
100 | create_user('marcink', 'qweqwe') |
|
98 | create_user('marcink', 'qweqwe') | |
101 | create_user('lukaszd', 'qweqwe') |
|
99 | create_user('lukaszd', 'qweqwe') | |
102 | create_user('adriand', 'qweqwe') |
|
100 | create_user('adriand', 'qweqwe') | |
103 | create_user('radek', 'qweqwe') |
|
101 | create_user('radek', 'qweqwe') | |
104 | create_user('skrzeka', 'qweqwe') |
|
102 | create_user('skrzeka', 'qweqwe') | |
105 | create_user('bart', 'qweqwe') |
|
103 | create_user('bart', 'qweqwe') | |
106 | create_user('maho', 'qweqwe') |
|
104 | create_user('maho', 'qweqwe') | |
107 | create_user('michalg', 'qweqwe') |
|
105 | create_user('michalg', 'qweqwe') | |
108 | create_user('admin', 'qwe123qwe') |
|
106 | create_user('admin', 'qwe123qwe') | |
109 |
|
107 | |||
110 | #authfunc('', 'marcink', 'qweqwe') |
|
108 | #authfunc('', 'marcink', 'qweqwe') |
@@ -1,48 +1,48 b'' | |||||
1 | """Helper functions |
|
1 | """Helper functions | |
2 |
|
2 | |||
3 | Consists of functions to typically be used within templates, but also |
|
3 | Consists of functions to typically be used within templates, but also | |
4 | available to Controllers. This module is available to both as 'h'. |
|
4 | available to Controllers. This module is available to both as 'h'. | |
5 | """ |
|
5 | """ | |
6 | from pylons import url |
|
6 | from pylons import url | |
7 | from webhelpers.html import (literal, HTML, escape) |
|
7 | from webhelpers.html import (literal, HTML, escape) | |
8 | from webhelpers.html.tools import (auto_link, button_to, highlight, js_obfuscate |
|
8 | from webhelpers.html.tools import (auto_link, button_to, highlight, js_obfuscate | |
9 | , mail_to, strip_links, strip_tags, tag_re) |
|
9 | , mail_to, strip_links, strip_tags, tag_re) | |
10 | from webhelpers.html.tags import (auto_discovery_link, checkbox, css_classes, |
|
10 | from webhelpers.html.tags import (auto_discovery_link, checkbox, css_classes, | |
11 | end_form, file, form, hidden, image, |
|
11 | end_form, file, form, hidden, image, | |
12 | javascript_link, link_to, link_to_if, |
|
12 | javascript_link, link_to, link_to_if, | |
13 | link_to_unless, ol, required_legend, |
|
13 | link_to_unless, ol, required_legend, | |
14 | select, stylesheet_link, |
|
14 | select, stylesheet_link, | |
15 | submit, text, textarea, title, ul, xml_declaration) |
|
15 | submit, text, password, textarea, title, ul, xml_declaration) | |
16 | from webhelpers.text import (chop_at, collapse, convert_accented_entities, |
|
16 | from webhelpers.text import (chop_at, collapse, convert_accented_entities, | |
17 | convert_misc_characters, convert_misc_entities, |
|
17 | convert_misc_characters, convert_misc_entities, | |
18 | lchop, plural, rchop, remove_formatting, replace_whitespace, |
|
18 | lchop, plural, rchop, remove_formatting, replace_whitespace, | |
19 | urlify) |
|
19 | urlify) | |
20 |
|
20 | |||
21 | from webhelpers.pylonslib import Flash as _Flash |
|
21 | from webhelpers.pylonslib import Flash as _Flash | |
22 | from webhelpers.pylonslib.secure_form import secure_form |
|
22 | from webhelpers.pylonslib.secure_form import secure_form | |
23 |
|
23 | |||
24 | #Custom helper here :) |
|
24 | #Custom helper here :) | |
25 | class _Link(object): |
|
25 | class _Link(object): | |
26 | ''' |
|
26 | ''' | |
27 | Make a url based on label and url with help of url_for |
|
27 | Make a url based on label and url with help of url_for | |
28 | @param label:name of link if not defined url is used |
|
28 | @param label:name of link if not defined url is used | |
29 | @param url: the url for link |
|
29 | @param url: the url for link | |
30 | ''' |
|
30 | ''' | |
31 |
|
31 | |||
32 | def __call__(self, label='', *url_, **urlargs): |
|
32 | def __call__(self, label='', *url_, **urlargs): | |
33 | if label is None or '': |
|
33 | if label is None or '': | |
34 | label = url |
|
34 | label = url | |
35 | link_fn = link_to(label, url(*url_, **urlargs)) |
|
35 | link_fn = link_to(label, url(*url_, **urlargs)) | |
36 | return link_fn |
|
36 | return link_fn | |
37 |
|
37 | |||
38 |
|
38 | |||
39 | class _GetError(object): |
|
39 | class _GetError(object): | |
40 |
|
40 | |||
41 | def __call__(self, field_name, form_errors): |
|
41 | def __call__(self, field_name, form_errors): | |
42 | tmpl = """<span class="error_msg">%s</span>""" |
|
42 | tmpl = """<span class="error_msg">%s</span>""" | |
43 | if form_errors and form_errors.has_key(field_name): |
|
43 | if form_errors and form_errors.has_key(field_name): | |
44 | return literal(tmpl % form_errors.get(field_name)) |
|
44 | return literal(tmpl % form_errors.get(field_name)) | |
45 |
|
45 | |||
46 | link = _Link() |
|
46 | link = _Link() | |
47 | flash = _Flash() |
|
47 | flash = _Flash() | |
48 | get_error = _GetError() |
|
48 | get_error = _GetError() |
@@ -1,63 +1,58 b'' | |||||
1 | """ this is forms validation classes |
|
1 | """ this is forms validation classes | |
2 | http://formencode.org/module-formencode.validators.html |
|
2 | http://formencode.org/module-formencode.validators.html | |
3 | for list off all availible validators |
|
3 | for list off all availible validators | |
4 |
|
4 | |||
5 | we can create our own validators |
|
5 | we can create our own validators | |
6 |
|
6 | |||
7 | The table below outlines the options which can be used in a schema in addition to the validators themselves |
|
7 | The table below outlines the options which can be used in a schema in addition to the validators themselves | |
8 | pre_validators [] These validators will be applied before the schema |
|
8 | pre_validators [] These validators will be applied before the schema | |
9 | chained_validators [] These validators will be applied after the schema |
|
9 | chained_validators [] These validators will be applied after the schema | |
10 | allow_extra_fields False If True, then it is not an error when keys that aren't associated with a validator are present |
|
10 | allow_extra_fields False If True, then it is not an error when keys that aren't associated with a validator are present | |
11 | filter_extra_fields False If True, then keys that aren't associated with a validator are removed |
|
11 | filter_extra_fields False If True, then keys that aren't associated with a validator are removed | |
12 | if_key_missing NoDefault If this is given, then any keys that aren't available but are expected will be replaced with this value (and then validated). This does not override a present .if_missing attribute on validators. NoDefault is a special FormEncode class to mean that no default values has been specified and therefore missing keys shouldn't take a default value. |
|
12 | if_key_missing NoDefault If this is given, then any keys that aren't available but are expected will be replaced with this value (and then validated). This does not override a present .if_missing attribute on validators. NoDefault is a special FormEncode class to mean that no default values has been specified and therefore missing keys shouldn't take a default value. | |
13 | ignore_key_missing False If True, then missing keys will be missing in the result, if the validator doesn't have .if_missing on it already |
|
13 | ignore_key_missing False If True, then missing keys will be missing in the result, if the validator doesn't have .if_missing on it already | |
14 |
|
14 | |||
15 |
|
15 | |||
16 | <name> = formencode.validators.<name of validator> |
|
16 | <name> = formencode.validators.<name of validator> | |
17 | <name> must equal form name |
|
17 | <name> must equal form name | |
18 | list=[1,2,3,4,5] |
|
18 | list=[1,2,3,4,5] | |
19 | for select use formencode.All(OneOf(list), Int()) |
|
19 | for select use formencode.All(OneOf(list), Int()) | |
20 |
|
20 | |||
21 | """ |
|
21 | """ | |
22 |
|
22 | |||
23 | import formencode |
|
23 | import formencode | |
24 | from formencode.validators import UnicodeString, OneOf, Int, Number, Regex |
|
24 | from formencode.validators import UnicodeString, OneOf, Int, Number, Regex | |
25 | from pylons.i18n.translation import _ |
|
25 | from pylons.i18n.translation import _ | |
26 | from webhelpers.pylonslib.secure_form import authentication_token |
|
26 | from webhelpers.pylonslib.secure_form import authentication_token | |
27 |
|
27 | |||
28 | class ValidAuthToken(formencode.validators.FancyValidator): |
|
28 | class ValidAuthToken(formencode.validators.FancyValidator): | |
29 | messages = {'invalid_token':_('Token mismatch')} |
|
29 | messages = {'invalid_token':_('Token mismatch')} | |
30 |
|
30 | |||
31 | def validate_python(self, value, state): |
|
31 | def validate_python(self, value, state): | |
32 |
|
32 | |||
33 | if value != authentication_token(): |
|
33 | if value != authentication_token(): | |
34 |
raise formencode.Invalid(self.message('invalid_token', state, search_number |
|
34 | raise formencode.Invalid(self.message('invalid_token', state, search_number=value), value, state) | |
35 |
|
35 | |||
36 |
|
36 | |||
37 | class WireTransferForm(object): |
|
37 | class LoginForm(formencode.Schema): | |
38 | ''' |
|
38 | allow_extra_fields = True | |
39 | A factory wrapper class. It might return the instance of class for a validation, but also it can |
|
39 | filter_extra_fields = True | |
40 | return the list for select fields values. |
|
40 | username = UnicodeString( | |
41 | @param ret_type: type to return defaut: 'class' |
|
41 | strip=True, | |
42 | ''' |
|
42 | min=3, | |
43 | #class attributes here |
|
43 | not_empty=True, | |
44 | #it might be fetched from db,from models and so on |
|
44 | messages={ | |
45 | recipients_list = [ |
|
45 | 'empty':_('Please enter a login'), | |
46 | (1, 'a'), |
|
46 | 'tooShort':_('Enter a value %(min)i characters long or more')} | |
47 |
|
|
47 | ) | |
48 | ] |
|
|||
49 |
|
48 | |||
50 | def _form(self): |
|
49 | password = UnicodeString( | |
51 | class _WireTransferForm(formencode.Schema): |
|
50 | strip=True, | |
52 | allow_extra_fields = True |
|
51 | min=3, | |
53 | _authentication_token = ValidAuthToken() |
|
52 | not_empty=True, | |
54 | account_number = Regex(r'[0-9]{26}', not_empty = True, messages = { |
|
53 | messages={ | |
55 | 'invalid': _("Account number is invalid, it must be 26 digits")}) |
|
54 | 'empty':_('Please enter a password'), | |
56 | title = UnicodeString(not_empty = True, min = 3, strip = True) |
|
55 | 'tooShort':_('Enter a value %(min)i characters long or more')} | |
57 | recipient = formencode.All(OneOf([i[0] for i in WireTransferForm.recipients_list], |
|
56 | ) | |
58 | testValueList = True, hideList = True), Int()) |
|
|||
59 | recipient_address = UnicodeString(not_empty = True, strip = True) |
|
|||
60 | amount = Number(not_empty = True, min = 1) |
|
|||
61 |
|
57 | |||
62 | return _WireTransferForm() |
|
|||
63 |
|
58 |
@@ -1,53 +1,64 b'' | |||||
1 | ## -*- coding: utf-8 -*- |
|
1 | ## -*- coding: utf-8 -*- | |
2 | <%inherit file="base/base.html"/> |
|
2 | <%inherit file="base/base.html"/> | |
|
3 | <%def name="get_form_error(element)"> | |||
|
4 | %if type(c.form_errors) == dict: | |||
|
5 | %if c.form_errors.get(element,False): | |||
|
6 | <span class="error-message"> | |||
|
7 | ${c.form_errors.get(element,'')} | |||
|
8 | </span> | |||
|
9 | %endif | |||
|
10 | %endif | |||
|
11 | </%def> | |||
3 | <%def name="title()"> |
|
12 | <%def name="title()"> | |
4 | ${_('Repository managment')} |
|
13 | ${_('Repository managment')} | |
5 | </%def> |
|
14 | </%def> | |
6 | <%def name="breadcrumbs()"> |
|
15 | <%def name="breadcrumbs()"> | |
7 | ${h.link_to(u'Home',h.url('/'))} |
|
16 | ${h.link_to(u'Home',h.url('/'))} | |
8 | / |
|
17 | / | |
9 | ${h.link_to(u'Admin',h.url('admin_home'))} |
|
18 | ${h.link_to(u'Admin',h.url('admin_home'))} | |
10 | </%def> |
|
19 | </%def> | |
11 | <%def name="page_nav()"> |
|
20 | <%def name="page_nav()"> | |
12 | <li>${h.link_to(u'Home',h.url('/'))}</li> |
|
21 | <li>${h.link_to(u'Home',h.url('/'))}</li> | |
13 | <li class="current">${_('Admin')}</li> |
|
22 | <li class="current">${_('Admin')}</li> | |
14 | </%def> |
|
23 | </%def> | |
15 | <%def name="main()"> |
|
24 | <%def name="main()"> | |
16 | %if c.admin_user: |
|
25 | %if c.admin_user: | |
17 | <ul class="submenu"> |
|
26 | <ul class="submenu"> | |
18 | <li> |
|
27 | <li> | |
19 | ${h.link_to(u'Repos managment',h.url('admin_repos_manage'))} |
|
28 | ${h.link_to(u'Repos managment',h.url('admin_repos_manage'))} | |
20 | </li> |
|
29 | </li> | |
21 | <li> |
|
30 | <li> | |
22 | ${h.link_to(u'Users managment',h.url('admin_users_manage'))} |
|
31 | ${h.link_to(u'Users managment',h.url('admin_users_manage'))} | |
23 | </li> |
|
32 | </li> | |
24 | </ul> |
|
33 | </ul> | |
25 | <br/> |
|
34 | <br/> | |
26 | <div> |
|
35 | <div> | |
27 |
|
36 | |||
28 | <h2>Hi !</h2> |
|
37 | <h2>Hi !</h2> | |
29 | </div> |
|
38 | </div> | |
30 | %else: |
|
39 | %else: | |
31 | <div> |
|
40 | <div> | |
32 | <br /> |
|
41 | <br /> | |
33 | <h2>${_('Login')}</h2> |
|
42 | <h2>${_('Login')}</h2> | |
34 | ${h.form(h.url.current())} |
|
43 | ${h.form(h.url.current())} | |
35 | <table> |
|
44 | <table> | |
36 | <tr> |
|
45 | <tr> | |
37 | <td>${_('Username')}</td> |
|
46 | <td>${_('Username')}</td> | |
38 | <td>${h.text('username')}</td> |
|
47 | <td>${h.text('username')}</td> | |
|
48 | <td>${get_form_error('username')} </td> | |||
39 | </tr> |
|
49 | </tr> | |
40 | <tr> |
|
50 | <tr> | |
41 | <td>${_('Password')}</td> |
|
51 | <td>${_('Password')}</td> | |
42 |
<td>${h. |
|
52 | <td>${h.password('password')}</td> | |
|
53 | <td>${get_form_error('password')}</td> | |||
43 | </tr> |
|
54 | </tr> | |
44 | <tr> |
|
55 | <tr> | |
45 | <td></td> |
|
56 | <td></td> | |
46 | <td>${h.submit('login','login')}</td> |
|
57 | <td>${h.submit('login','login')}</td> | |
47 | </tr> |
|
58 | </tr> | |
48 | </table> |
|
59 | </table> | |
49 | ${h.end_form()} |
|
60 | ${h.end_form()} | |
50 | </div> |
|
61 | </div> | |
51 | %endif |
|
62 | %endif | |
52 |
|
63 | |||
53 | </%def> No newline at end of file |
|
64 | </%def> |
@@ -1,42 +1,42 b'' | |||||
1 | ## -*- coding: utf-8 -*- |
|
1 | ## -*- coding: utf-8 -*- | |
2 | {header} |
|
2 | {header} | |
3 | <title>{repo|escape}: Mercurial repositories index</title> |
|
3 | <title>{repo|escape}: Mercurial repositories index</title> | |
4 | </head> |
|
4 | </head> | |
5 |
|
5 | |||
6 | <body> |
|
6 | <body> | |
7 | <div id="container"> |
|
7 | <div id="container"> | |
8 | <div class="page-header"> |
|
8 | <div class="page-header"> | |
9 | <h1>${c.repos_prefix} Mercurial Repositories</h1> |
|
9 | <h1>${c.repos_prefix} Mercurial Repositories</h1> | |
10 | <ul class="page-nav"> |
|
10 | <ul class="page-nav"> | |
11 | <li class="current">Home</li> |
|
11 | <li class="current">Home</li> | |
12 | <li>${h.link_to(u'Admin',h.url('admin_home'))}</li> |
|
12 | <li><a href="/_admin/">Admin</a></li> | |
13 | </ul> |
|
13 | </ul> | |
14 | </div> |
|
14 | </div> | |
15 |
|
15 | |||
16 | <table cellspacing="0"> |
|
16 | <table cellspacing="0"> | |
17 | <tr> |
|
17 | <tr> | |
18 | <td><a href="?sort={sort_name}">Name</a></td> |
|
18 | <td><a href="?sort={sort_name}">Name</a></td> | |
19 | <td><a href="?sort={sort_description}">Description</a></td> |
|
19 | <td><a href="?sort={sort_description}">Description</a></td> | |
20 | <td><a href="?sort={sort_contact}">Contact</a></td> |
|
20 | <td><a href="?sort={sort_contact}">Contact</a></td> | |
21 | <td><a href="?sort={sort_lastchange}">Last change</a></td> |
|
21 | <td><a href="?sort={sort_lastchange}">Last change</a></td> | |
22 | <td> </td> |
|
22 | <td> </td> | |
23 | <td> </td> |
|
23 | <td> </td> | |
24 | </tr> |
|
24 | </tr> | |
25 | {entries%indexentry} |
|
25 | {entries%indexentry} | |
26 | </table> |
|
26 | </table> | |
27 | <div class="page-footer"> |
|
27 | <div class="page-footer"> | |
28 | {motd} |
|
28 | {motd} | |
29 | </div> |
|
29 | </div> | |
30 |
|
30 | |||
31 | <div id="powered-by"> |
|
31 | <div id="powered-by"> | |
32 | <p><a href="http://mercurial.selenic.com/" title="Mercurial"><img src="{staticurl}hglogo.png" width="75" height="90" alt="mercurial"/></a></p> |
|
32 | <p><a href="http://mercurial.selenic.com/" title="Mercurial"><img src="{staticurl}hglogo.png" width="75" height="90" alt="mercurial"/></a></p> | |
33 | </div> |
|
33 | </div> | |
34 |
|
34 | |||
35 | <div id="corner-top-left"></div> |
|
35 | <div id="corner-top-left"></div> | |
36 | <div id="corner-top-right"></div> |
|
36 | <div id="corner-top-right"></div> | |
37 | <div id="corner-bottom-left"></div> |
|
37 | <div id="corner-bottom-left"></div> | |
38 | <div id="corner-bottom-right"></div> |
|
38 | <div id="corner-bottom-right"></div> | |
39 |
|
39 | |||
40 | </div> |
|
40 | </div> | |
41 | </body> |
|
41 | </body> | |
42 | </html> |
|
42 | </html> |
General Comments 0
You need to be logged in to leave comments.
Login now