Show More
@@ -0,0 +1,8 | |||
|
1 | from pylons_app.tests import * | |
|
2 | ||
|
3 | class TestAdminController(TestController): | |
|
4 | ||
|
5 | def test_index(self): | |
|
6 | ||
|
7 | response = self.app.get(url(controller='hg', action='index')) | |
|
8 | # Test response... No newline at end of file |
@@ -1,13 +1,15 | |||
|
1 | include COPYING | |
|
2 | include README.rst | |
|
1 | 3 | include pylons_app/config/deployment.ini_tmpl |
|
2 | 4 | |
|
3 | 5 | include hg_app_daemon |
|
4 | 6 | include hg_app_daemon2 |
|
5 | 7 | |
|
6 | 8 | recursive-include pylons_app/public/css * |
|
7 | 9 | recursive-include pylons_app/public/images * |
|
8 | 10 | |
|
9 | 11 | include pylons_app/public/js/yui2.js |
|
10 | 12 | include pylons_app/public/js/excanvas.min.js |
|
11 | 13 | include pylons_app/public/js/yui.flot.js |
|
12 | 14 | |
|
13 | 15 | recursive-include pylons_app/templates * No newline at end of file |
@@ -1,56 +1,57 | |||
|
1 | 1 | from sqlalchemy.interfaces import ConnectionProxy |
|
2 | 2 | import time |
|
3 | 3 | import logging |
|
4 | 4 | log = logging.getLogger('timerproxy') |
|
5 | 5 | BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = xrange(30, 38) |
|
6 | 6 | |
|
7 | 7 | def color_sql(sql): |
|
8 | 8 | COLOR_SEQ = "\033[1;%dm" |
|
9 | 9 | COLOR_SQL = YELLOW |
|
10 | 10 | normal = '\x1b[0m' |
|
11 | 11 | return COLOR_SEQ % COLOR_SQL + sql + normal |
|
12 | 12 | |
|
13 | 13 | def one_space_trim(s): |
|
14 | 14 | if s.find(" ") == -1: |
|
15 | 15 | return s |
|
16 | 16 | else: |
|
17 | 17 | s = s.replace(' ', ' ') |
|
18 | 18 | return one_space_trim(s) |
|
19 | 19 | |
|
20 | 20 | def format_sql(sql): |
|
21 | 21 | sql = color_sql(sql) |
|
22 | 22 | sql = sql.replace('\n', '') |
|
23 | 23 | sql = one_space_trim(sql) |
|
24 | 24 | sql = sql\ |
|
25 | .replace(',',',\n\t')\ | |
|
25 | 26 | .replace('SELECT', '\n\tSELECT \n\t')\ |
|
26 | 27 | .replace('UPDATE', '\n\tUPDATE \n\t')\ |
|
27 | 28 | .replace('DELETE', '\n\tDELETE \n\t')\ |
|
28 | 29 | .replace('FROM', '\n\tFROM')\ |
|
29 | 30 | .replace('ORDER BY', '\n\tORDER BY')\ |
|
30 | 31 | .replace('LIMIT', '\n\tLIMIT')\ |
|
31 | 32 | .replace('WHERE', '\n\tWHERE')\ |
|
32 | 33 | .replace('AND', '\n\tAND')\ |
|
33 | 34 | .replace('LEFT', '\n\tLEFT')\ |
|
34 | 35 | .replace('INNER', '\n\tINNER')\ |
|
35 | 36 | .replace('INSERT', '\n\tINSERT')\ |
|
36 | 37 | .replace('DELETE', '\n\tDELETE') |
|
37 | 38 | return sql |
|
38 | 39 | |
|
39 | 40 | |
|
40 | 41 | class TimerProxy(ConnectionProxy): |
|
41 | 42 | def cursor_execute(self, execute, cursor, statement, parameters, context, executemany): |
|
42 | 43 | now = time.time() |
|
43 | 44 | try: |
|
44 | 45 | log.info(">>>>> STARTING QUERY >>>>>") |
|
45 | 46 | return execute(cursor, statement, parameters, context) |
|
46 | 47 | finally: |
|
47 | 48 | total = time.time() - now |
|
48 | 49 | try: |
|
49 | 50 | log.info(format_sql("Query: %s" % statement % parameters)) |
|
50 | 51 | except TypeError: |
|
51 | 52 | log.info(format_sql("Query: %s %s" % (statement, parameters))) |
|
52 | 53 | log.info("<<<<< TOTAL TIME: %f <<<<<" % total) |
|
53 | 54 | |
|
54 | 55 | |
|
55 | 56 | |
|
56 | 57 |
@@ -1,125 +1,125 | |||
|
1 | 1 | from pylons_app.model.meta import Base |
|
2 | 2 | from sqlalchemy import * |
|
3 | 3 | from sqlalchemy.orm import relation, backref |
|
4 | 4 | from sqlalchemy.orm.session import Session |
|
5 | 5 | from vcs.utils.lazy import LazyProperty |
|
6 | 6 | import logging |
|
7 | 7 | |
|
8 | 8 | log = logging.getLogger(__name__) |
|
9 | 9 | |
|
10 | 10 | class HgAppSettings(Base): |
|
11 | 11 | __tablename__ = 'hg_app_settings' |
|
12 | 12 | __table_args__ = (UniqueConstraint('app_settings_name'), {'useexisting':True}) |
|
13 | 13 | app_settings_id = Column("app_settings_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True) |
|
14 | 14 | app_settings_name = Column("app_settings_name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) |
|
15 | 15 | app_settings_value = Column("app_settings_value", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) |
|
16 | 16 | |
|
17 | 17 | class HgAppUi(Base): |
|
18 | 18 | __tablename__ = 'hg_app_ui' |
|
19 | 19 | __table_args__ = {'useexisting':True} |
|
20 | 20 | ui_id = Column("ui_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True) |
|
21 | 21 | ui_section = Column("ui_section", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) |
|
22 | 22 | ui_key = Column("ui_key", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) |
|
23 | 23 | ui_value = Column("ui_value", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) |
|
24 | 24 | ui_active = Column("ui_active", BOOLEAN(), nullable=True, unique=None, default=True) |
|
25 | 25 | |
|
26 | 26 | |
|
27 | 27 | class User(Base): |
|
28 | 28 | __tablename__ = 'users' |
|
29 | 29 | __table_args__ = (UniqueConstraint('username'), {'useexisting':True}) |
|
30 | 30 | user_id = Column("user_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True) |
|
31 | 31 | username = Column("username", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) |
|
32 | 32 | password = Column("password", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) |
|
33 | 33 | active = Column("active", BOOLEAN(), nullable=True, unique=None, default=None) |
|
34 | 34 | admin = Column("admin", BOOLEAN(), nullable=True, unique=None, default=False) |
|
35 | 35 | name = Column("name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) |
|
36 | 36 | lastname = Column("lastname", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) |
|
37 | 37 | email = Column("email", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) |
|
38 | 38 | last_login = Column("last_login", DATETIME(timezone=False), nullable=True, unique=None, default=None) |
|
39 | 39 | |
|
40 | 40 | user_log = relation('UserLog') |
|
41 | 41 | user_perms = relation('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id") |
|
42 | 42 | |
|
43 | 43 | @LazyProperty |
|
44 | 44 | def full_contact(self): |
|
45 | 45 | return '%s %s <%s>' % (self.name, self.lastname, self.email) |
|
46 | 46 | |
|
47 | 47 | def __repr__(self): |
|
48 | 48 | return "<User('id:%s:%s')>" % (self.user_id, self.username) |
|
49 | 49 | |
|
50 | 50 | def update_lastlogin(self): |
|
51 | 51 | """Update user lastlogin""" |
|
52 | 52 | import datetime |
|
53 | 53 | |
|
54 | 54 | try: |
|
55 | 55 | session = Session.object_session(self) |
|
56 | 56 | self.last_login = datetime.datetime.now() |
|
57 | 57 | session.add(self) |
|
58 | 58 | session.commit() |
|
59 | log.debug('updated user %s lastlogin',self) | |
|
59 | log.debug('updated user %s lastlogin',self.username) | |
|
60 | 60 | except Exception: |
|
61 | 61 | session.rollback() |
|
62 | 62 | |
|
63 | 63 | |
|
64 | 64 | class UserLog(Base): |
|
65 | 65 | __tablename__ = 'user_logs' |
|
66 | 66 | __table_args__ = {'useexisting':True} |
|
67 | 67 | user_log_id = Column("user_log_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True) |
|
68 | 68 | user_id = Column("user_id", INTEGER(), ForeignKey(u'users.user_id'), nullable=False, unique=None, default=None) |
|
69 | 69 | user_ip = Column("user_ip", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) |
|
70 | 70 | repository = Column("repository", TEXT(length=None, convert_unicode=False, assert_unicode=None), ForeignKey(u'repositories.repo_name'), nullable=False, unique=None, default=None) |
|
71 | 71 | action = Column("action", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) |
|
72 | 72 | action_date = Column("action_date", DATETIME(timezone=False), nullable=True, unique=None, default=None) |
|
73 | 73 | |
|
74 | 74 | user = relation('User') |
|
75 | 75 | |
|
76 | 76 | class Repository(Base): |
|
77 | 77 | __tablename__ = 'repositories' |
|
78 | 78 | __table_args__ = (UniqueConstraint('repo_name'), {'useexisting':True},) |
|
79 | 79 | repo_id = Column("repo_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True) |
|
80 | 80 | repo_name = Column("repo_name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None) |
|
81 | 81 | user_id = Column("user_id", INTEGER(), ForeignKey(u'users.user_id'), nullable=False, unique=False, default=None) |
|
82 | 82 | private = Column("private", BOOLEAN(), nullable=True, unique=None, default=None) |
|
83 | 83 | description = Column("description", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) |
|
84 | 84 | |
|
85 | 85 | user = relation('User') |
|
86 | 86 | repo_to_perm = relation('RepoToPerm', cascade='all') |
|
87 | 87 | |
|
88 | 88 | def __repr__(self): |
|
89 | 89 | return "<Repository('id:%s:%s')>" % (self.repo_id, self.repo_name) |
|
90 | 90 | |
|
91 | 91 | class Permission(Base): |
|
92 | 92 | __tablename__ = 'permissions' |
|
93 | 93 | __table_args__ = {'useexisting':True} |
|
94 | 94 | permission_id = Column("permission_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True) |
|
95 | 95 | permission_name = Column("permission_name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) |
|
96 | 96 | permission_longname = Column("permission_longname", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None) |
|
97 | 97 | |
|
98 | 98 | def __repr__(self): |
|
99 | 99 | return "<Permission('%s:%s')>" % (self.permission_id, self.permission_name) |
|
100 | 100 | |
|
101 | 101 | class RepoToPerm(Base): |
|
102 | 102 | __tablename__ = 'repo_to_perm' |
|
103 | 103 | __table_args__ = (UniqueConstraint('user_id', 'repository_id'), {'useexisting':True}) |
|
104 | 104 | repo_to_perm_id = Column("repo_to_perm_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True) |
|
105 | 105 | user_id = Column("user_id", INTEGER(), ForeignKey(u'users.user_id'), nullable=False, unique=None, default=None) |
|
106 | 106 | permission_id = Column("permission_id", INTEGER(), ForeignKey(u'permissions.permission_id'), nullable=False, unique=None, default=None) |
|
107 | 107 | repository_id = Column("repository_id", INTEGER(), ForeignKey(u'repositories.repo_id'), nullable=False, unique=None, default=None) |
|
108 | 108 | |
|
109 | 109 | user = relation('User') |
|
110 | 110 | permission = relation('Permission') |
|
111 | 111 | repository = relation('Repository') |
|
112 | 112 | |
|
113 | 113 | class UserToPerm(Base): |
|
114 | 114 | __tablename__ = 'user_to_perm' |
|
115 | 115 | __table_args__ = (UniqueConstraint('user_id', 'permission_id'), {'useexisting':True}) |
|
116 | 116 | user_to_perm_id = Column("user_to_perm_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True) |
|
117 | 117 | user_id = Column("user_id", INTEGER(), ForeignKey(u'users.user_id'), nullable=False, unique=None, default=None) |
|
118 | 118 | permission_id = Column("permission_id", INTEGER(), ForeignKey(u'permissions.permission_id'), nullable=False, unique=None, default=None) |
|
119 | 119 | |
|
120 | 120 | user = relation('User') |
|
121 | 121 | permission = relation('Permission') |
|
122 | 122 | |
|
123 | 123 | |
|
124 | 124 | |
|
125 | 125 |
@@ -1,45 +1,51 | |||
|
1 | 1 | from pylons_app.tests import * |
|
2 | 2 | |
|
3 | 3 | class TestLoginController(TestController): |
|
4 | 4 | |
|
5 | 5 | def test_index(self): |
|
6 | 6 | response = self.app.get(url(controller='login', action='index')) |
|
7 | 7 | assert response.status == '200 OK','Wrong response from login page' |
|
8 | 8 | # Test response... |
|
9 | 9 | |
|
10 | 10 | def test_login_admin_ok(self): |
|
11 | 11 | response = self.app.post(url(controller='login', action='index'), |
|
12 | 12 | {'username':'test_admin', |
|
13 | 13 | 'password':'test'}) |
|
14 | 14 | assert response.status == '302 Found','Wrong response code from login' |
|
15 | assert response.session['hg_app_user'].username =='test_admin','wrong logged in user' | |
|
16 | response = response.follow() | |
|
17 | assert 'auto description for vcs_test' in response.body | |
|
15 | 18 | |
|
16 | 19 | def test_login_regular_ok(self): |
|
17 | 20 | response = self.app.post(url(controller='login', action='index'), |
|
18 |
{'username':'test_ |
|
|
21 | {'username':'test_regular', | |
|
19 | 22 | 'password':'test'}) |
|
20 | 23 | assert response.status == '302 Found','Wrong response code from login' |
|
21 | ||
|
24 | assert response.session['hg_app_user'].username =='test_regular','wrong logged in user' | |
|
25 | response = response.follow() | |
|
26 | assert 'auto description for vcs_test' in response.body | |
|
27 | assert '<a title="Admin" href="/_admin">' not in response.body | |
|
22 | 28 | |
|
23 | 29 | def test_login_ok_came_from(self): |
|
24 | 30 | test_came_from = '/_admin/users' |
|
25 | 31 | response = self.app.post(url(controller='login', action='index',came_from=test_came_from), |
|
26 | 32 | {'username':'test_admin', |
|
27 | 33 | 'password':'test'}) |
|
28 | 34 | assert response.status == '302 Found','Wrong response code from came from redirection' |
|
29 | 35 | response = response.follow() |
|
30 | 36 | |
|
31 | 37 | assert response.status == '200 OK','Wrong response from login page' |
|
32 | 38 | assert 'Users administration' in response.body,'No proper title in response' |
|
33 | 39 | |
|
34 | 40 | |
|
35 | 41 | def test_login_wrong(self): |
|
36 | 42 | response = self.app.post(url(controller='login', action='index'), |
|
37 | 43 | {'username':'error', |
|
38 | 44 | 'password':'test'}) |
|
39 | 45 | assert response.status == '200 OK','Wrong response from login page' |
|
40 | 46 | |
|
41 | 47 | assert 'invalid user name' in response.body,'No error username message in response' |
|
42 | 48 | assert 'invalid password' in response.body,'No error password message in response' |
|
43 | 49 | |
|
44 | 50 | |
|
45 | 51 | No newline at end of file |
General Comments 0
You need to be logged in to leave comments.
Login now