Mercurial > public > src > rhodecode
annotate pylons_app/lib/auth.py @ 190:d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Sat, 22 May 2010 01:43:42 +0200 |
parents | f24b9a2934cf |
children | 3d1dd13887f9 |
rev | line source |
---|---|
41
71ffa932799d
Added app basic auth.
Marcin Kuzminski <marcin@python-blog.com>
parents:
diff
changeset
|
1 from datetime import datetime |
190
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
2 from decorator import decorator |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
3 from functools import wraps |
52 | 4 from pylons import session, url |
5 from pylons.controllers.util import abort, redirect | |
64
08707974eae4
Changed auth lib for sqlalchemy
Marcin Kuzminski <marcin@python-blog.com>
parents:
52
diff
changeset
|
6 from pylons_app.model import meta |
08707974eae4
Changed auth lib for sqlalchemy
Marcin Kuzminski <marcin@python-blog.com>
parents:
52
diff
changeset
|
7 from pylons_app.model.db import Users, UserLogs |
190
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
8 from sqlalchemy.exc import OperationalError |
64
08707974eae4
Changed auth lib for sqlalchemy
Marcin Kuzminski <marcin@python-blog.com>
parents:
52
diff
changeset
|
9 from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound |
190
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
10 import crypt |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
11 import logging |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
12 log = logging.getLogger(__name__) |
41
71ffa932799d
Added app basic auth.
Marcin Kuzminski <marcin@python-blog.com>
parents:
diff
changeset
|
13 |
64
08707974eae4
Changed auth lib for sqlalchemy
Marcin Kuzminski <marcin@python-blog.com>
parents:
52
diff
changeset
|
14 def get_crypt_password(password): |
190
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
15 """ |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
16 Cryptographic function used for password hashing |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
17 @param password: password to hash |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
18 """ |
64
08707974eae4
Changed auth lib for sqlalchemy
Marcin Kuzminski <marcin@python-blog.com>
parents:
52
diff
changeset
|
19 return crypt.crypt(password, '6a') |
46
9db7782727b3
Static files for production fixed
Marcin Kuzminski <marcin@python-blog.com>
parents:
45
diff
changeset
|
20 |
41
71ffa932799d
Added app basic auth.
Marcin Kuzminski <marcin@python-blog.com>
parents:
diff
changeset
|
21 def authfunc(environ, username, password): |
64
08707974eae4
Changed auth lib for sqlalchemy
Marcin Kuzminski <marcin@python-blog.com>
parents:
52
diff
changeset
|
22 sa = meta.Session |
08707974eae4
Changed auth lib for sqlalchemy
Marcin Kuzminski <marcin@python-blog.com>
parents:
52
diff
changeset
|
23 password_crypt = get_crypt_password(password) |
42 | 24 try: |
64
08707974eae4
Changed auth lib for sqlalchemy
Marcin Kuzminski <marcin@python-blog.com>
parents:
52
diff
changeset
|
25 user = sa.query(Users).filter(Users.username == username).one() |
08707974eae4
Changed auth lib for sqlalchemy
Marcin Kuzminski <marcin@python-blog.com>
parents:
52
diff
changeset
|
26 except (NoResultFound, MultipleResultsFound, OperationalError) as e: |
42 | 27 log.error(e) |
64
08707974eae4
Changed auth lib for sqlalchemy
Marcin Kuzminski <marcin@python-blog.com>
parents:
52
diff
changeset
|
28 user = None |
08707974eae4
Changed auth lib for sqlalchemy
Marcin Kuzminski <marcin@python-blog.com>
parents:
52
diff
changeset
|
29 |
08707974eae4
Changed auth lib for sqlalchemy
Marcin Kuzminski <marcin@python-blog.com>
parents:
52
diff
changeset
|
30 if user: |
08707974eae4
Changed auth lib for sqlalchemy
Marcin Kuzminski <marcin@python-blog.com>
parents:
52
diff
changeset
|
31 if user.active: |
08707974eae4
Changed auth lib for sqlalchemy
Marcin Kuzminski <marcin@python-blog.com>
parents:
52
diff
changeset
|
32 if user.username == username and user.password == password_crypt: |
41
71ffa932799d
Added app basic auth.
Marcin Kuzminski <marcin@python-blog.com>
parents:
diff
changeset
|
33 log.info('user %s authenticated correctly', username) |
45 | 34 if environ: |
35 http_accept = environ.get('HTTP_ACCEPT') | |
36 | |
37 if http_accept.startswith('application/mercurial') or \ | |
38 environ['PATH_INFO'].find('raw-file') != -1: | |
64
08707974eae4
Changed auth lib for sqlalchemy
Marcin Kuzminski <marcin@python-blog.com>
parents:
52
diff
changeset
|
39 repo = environ['PATH_INFO'] |
45 | 40 for qry in environ['QUERY_STRING'].split('&'): |
41 if qry.startswith('cmd'): | |
41
71ffa932799d
Added app basic auth.
Marcin Kuzminski <marcin@python-blog.com>
parents:
diff
changeset
|
42 |
45 | 43 try: |
64
08707974eae4
Changed auth lib for sqlalchemy
Marcin Kuzminski <marcin@python-blog.com>
parents:
52
diff
changeset
|
44 user_log = UserLogs() |
08707974eae4
Changed auth lib for sqlalchemy
Marcin Kuzminski <marcin@python-blog.com>
parents:
52
diff
changeset
|
45 user_log.user_id = user.user_id |
08707974eae4
Changed auth lib for sqlalchemy
Marcin Kuzminski <marcin@python-blog.com>
parents:
52
diff
changeset
|
46 user_log.action = qry |
08707974eae4
Changed auth lib for sqlalchemy
Marcin Kuzminski <marcin@python-blog.com>
parents:
52
diff
changeset
|
47 user_log.repository = repo |
08707974eae4
Changed auth lib for sqlalchemy
Marcin Kuzminski <marcin@python-blog.com>
parents:
52
diff
changeset
|
48 user_log.action_date = datetime.now() |
08707974eae4
Changed auth lib for sqlalchemy
Marcin Kuzminski <marcin@python-blog.com>
parents:
52
diff
changeset
|
49 sa.add(user_log) |
08707974eae4
Changed auth lib for sqlalchemy
Marcin Kuzminski <marcin@python-blog.com>
parents:
52
diff
changeset
|
50 sa.commit() |
08707974eae4
Changed auth lib for sqlalchemy
Marcin Kuzminski <marcin@python-blog.com>
parents:
52
diff
changeset
|
51 log.info('Adding user %s, action %s', username, qry) |
45 | 52 except Exception as e: |
64
08707974eae4
Changed auth lib for sqlalchemy
Marcin Kuzminski <marcin@python-blog.com>
parents:
52
diff
changeset
|
53 sa.rollback() |
45 | 54 log.error(e) |
55 | |
41
71ffa932799d
Added app basic auth.
Marcin Kuzminski <marcin@python-blog.com>
parents:
diff
changeset
|
56 return True |
71ffa932799d
Added app basic auth.
Marcin Kuzminski <marcin@python-blog.com>
parents:
diff
changeset
|
57 else: |
71ffa932799d
Added app basic auth.
Marcin Kuzminski <marcin@python-blog.com>
parents:
diff
changeset
|
58 log.error('user %s is disabled', username) |
71ffa932799d
Added app basic auth.
Marcin Kuzminski <marcin@python-blog.com>
parents:
diff
changeset
|
59 |
71ffa932799d
Added app basic auth.
Marcin Kuzminski <marcin@python-blog.com>
parents:
diff
changeset
|
60 return False |
71ffa932799d
Added app basic auth.
Marcin Kuzminski <marcin@python-blog.com>
parents:
diff
changeset
|
61 |
190
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
62 class AuthUser(object): |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
63 """ |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
64 A simple object that handles a mercurial username for authentication |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
65 """ |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
66 username = 'Empty' |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
67 is_authenticated = False |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
68 is_admin = False |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
69 permissions = set() |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
70 group = set() |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
71 |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
72 def __init__(self): |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
73 pass |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
74 |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
75 #=============================================================================== |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
76 # DECORATORS |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
77 #=============================================================================== |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
78 class LoginRequired(object): |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
79 """ |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
80 Must be logged in to execute this function else redirect to login page |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
81 """ |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
82 def __init__(self): |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
83 pass |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
84 |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
85 def __call__(self, func): |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
86 log.info('Checking login required') |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
87 |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
88 @wraps(func) |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
89 def _wrapper(*fargs, **fkwargs): |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
90 user = session.get('hg_app_user', AuthUser()) |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
91 if user.is_authenticated: |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
92 log.info('user %s is authenticated', user.username) |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
93 func(*fargs) |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
94 else: |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
95 logging.info('user %s not authenticated', user.username) |
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
96 return redirect(url('login_home')) |
52 | 97 |
190
d8eb7ee27b4c
Added LoginRequired decorator, empty User data container, hash functions
Marcin Kuzminski <marcin@python-works.com>
parents:
96
diff
changeset
|
98 return _wrapper |