allura
修訂 | 0e4a3d40e3defc5454c2658c55c778b44b63c4e8 (tree) |
---|---|
時間 | 2010-05-20 02:05:46 |
作者 | Rick Copeland <rcopeland@geek...> |
Commiter | Rick Copeland |
[#414] - Update user API so that it works if the user exists in SFX but not allura
@@ -87,7 +87,7 @@ class SVNCommit(Commit): | ||
87 | 87 | result = cls(id=entry.revision.number, repo=repo) |
88 | 88 | result.__dict__['_impl'] = entry |
89 | 89 | result.author_username=entry.author |
90 | - result.author=User.query.get(username=entry.author) | |
90 | + result.author=User.by_username(entry.author) | |
91 | 91 | result.datetime=datetime.utcfromtimestamp(entry.date) |
92 | 92 | return result |
93 | 93 |
@@ -448,7 +448,7 @@ class PageController(object): | ||
448 | 448 | if u['id'] == 'all': |
449 | 449 | self.page.viewable_by.remove('all') |
450 | 450 | else: |
451 | - user = User.query.get(username=str(u['id'])) | |
451 | + user = User.by_username(str(u['id'])) | |
452 | 452 | if user: |
453 | 453 | self.page.viewable_by.remove(user.username) |
454 | 454 | redirect('.') |
@@ -86,7 +86,7 @@ class AuthController(object): | ||
86 | 86 | def save_new(self,display_name=None,open_ids=None,email_addresses=None, |
87 | 87 | username=None,password=None): |
88 | 88 | username = username.lower() |
89 | - if M.User.query.get(username=username): | |
89 | + if M.User.by_username(username): | |
90 | 90 | flash('That username is already taken. Please choose another.', |
91 | 91 | 'error') |
92 | 92 | redirect('create_account') |
@@ -130,7 +130,7 @@ class AuthController(object): | ||
130 | 130 | |
131 | 131 | @expose() |
132 | 132 | def do_setup_openid_user(self, username=None, display_name=None): |
133 | - if M.User.query.get(username=username) and username != c.user.username: | |
133 | + if M.User.by_username(username) and username != c.user.username: | |
134 | 134 | flash('That username is already taken. Please choose another.', |
135 | 135 | 'error') |
136 | 136 | redirect('setup_openid_user') |
@@ -173,7 +173,7 @@ class AuthController(object): | ||
173 | 173 | |
174 | 174 | @expose() |
175 | 175 | def do_login(self, username, password, came_from=None): |
176 | - user = M.User.query.get(username=username) | |
176 | + user = M.User.by_username(username) | |
177 | 177 | if user is None: |
178 | 178 | session['userid'] = None |
179 | 179 | session.save() |
@@ -408,7 +408,7 @@ class NeighborhoodAdminController(object): | ||
408 | 408 | else: |
409 | 409 | self.neighborhood.acl[permission].remove(None) |
410 | 410 | if new.get('add'): |
411 | - u = M.User.query.get(username=new['username']) | |
411 | + u = M.User.by_username(new['username']) | |
412 | 412 | self.neighborhood.acl[permission].append(u._id) |
413 | 413 | redirect('permissions') |
414 | 414 |
@@ -90,7 +90,7 @@ class TestController(BaseController, ProjectController): | ||
90 | 90 | def __call__(self, environ, start_response): |
91 | 91 | c.app = None |
92 | 92 | c.project = M.Project.query.get(shortname='test') |
93 | - c.user = M.User.query.get(username=environ.get('username', 'test_admin')) | |
93 | + c.user = M.User.by_username(environ.get('username', 'test_admin')) | |
94 | 94 | return BaseController.__call__(self, environ, start_response) |
95 | 95 | |
96 | 96 | class DispatchTest(object): |
@@ -296,7 +296,7 @@ class ProjectAdminController(object): | ||
296 | 296 | if new['id']: |
297 | 297 | c.project.acl[permission].append(ObjectId(str(new['id']))) |
298 | 298 | else: |
299 | - user = M.User.query.get(username=new['username']) | |
299 | + user = M.User.by_username(new['username']) | |
300 | 300 | if user is None: |
301 | 301 | flash('No user %s' % new['username'], 'error') |
302 | 302 | redirect('.') |
@@ -334,7 +334,7 @@ class ProjectAdminController(object): | ||
334 | 334 | if role is None: role = [] |
335 | 335 | for r in role: |
336 | 336 | if r.get('new', {}).get('add'): |
337 | - user = M.User.query.find({'username':str(r['new']['id'])}).first() | |
337 | + user = M.User.by_username(str(r['new']['id'])) | |
338 | 338 | if user: |
339 | 339 | ur = user.project_role() |
340 | 340 | if ObjectId(str(r['id'])) not in ur.roles: |
@@ -1,12 +1,54 @@ | ||
1 | 1 | import json |
2 | 2 | import httplib |
3 | +import urllib2 | |
3 | 4 | from contextlib import closing |
4 | 5 | |
5 | 6 | from tg import config |
6 | 7 | from pylons import c, request |
7 | 8 | |
9 | +from pyforge import model as M | |
8 | 10 | from pyforge.lib.security import roles_with_project_access |
9 | 11 | |
12 | +class SFXUserApi(object): | |
13 | + | |
14 | + def __init__(self): | |
15 | + self.project_host = config.get('sfx.api.host', None) | |
16 | + self.project_path = config.get('sfx.api.project_path', '/api/user') | |
17 | + | |
18 | + def _username_api_url(self, username): | |
19 | + return 'http://%s/api/user/username/%s/json' % ( | |
20 | + self.project_host or request.host, | |
21 | + username) | |
22 | + | |
23 | + def _userid_api_url(self, id): | |
24 | + return 'http://%s/api/user/id/%s/json' % ( | |
25 | + self.project_host or request.host, | |
26 | + id) | |
27 | + | |
28 | + def user_data(self, username, timeout=2): | |
29 | + """ | |
30 | + given a sfnet hostname and userid, returns a dict of user data | |
31 | + """ | |
32 | + try: | |
33 | + url = self._userid_api_url(int(username)) | |
34 | + except TypeError: | |
35 | + url = self._username_api_url(username) | |
36 | + url_handle = urllib2.urlopen(url, timeout=timeout) | |
37 | + return json.load(url_handle)['User'] | |
38 | + | |
39 | + def upsert_user(self, username, user_data=None): | |
40 | + if user_data is None: | |
41 | + user_data = self.user_data(username) | |
42 | + u = M.User.query.get(username=username) | |
43 | + if u is None: | |
44 | + u = M.User(username=username) | |
45 | + n = M.Neighborhood.query.get(name='Users') | |
46 | + n.register_project('u/' + u.username, u, user_project=True) | |
47 | + if u.display_name != user_data['name']: | |
48 | + u.display_name = user_data.name | |
49 | + if u.sfx_userid != user_data['id']: | |
50 | + u.sfx_userid = user_data['id'] | |
51 | + | |
10 | 52 | class SFXProjectApi(object): |
11 | 53 | |
12 | 54 | def __init__(self): |
@@ -71,13 +71,13 @@ class UserProfileController(object): | ||
71 | 71 | @expose('pyforge.ext.user_profile.templates.user_index') |
72 | 72 | def index(self): |
73 | 73 | username = c.project.shortname.split('/')[1] |
74 | - user = User.query.find({'username':username}).first() | |
74 | + user = User.by_username(username) | |
75 | 75 | return dict(user=user) |
76 | 76 | |
77 | 77 | @expose('pyforge.ext.user_profile.templates.user_dashboard_configuration') |
78 | 78 | def configuration(self): |
79 | 79 | username = c.project.shortname.split('/')[1] |
80 | - user = User.query.find({'username':username}).first() | |
80 | + user = User.by_username(username) | |
81 | 81 | return dict(user=user) |
82 | 82 | |
83 | 83 | @h.vardec |
@@ -132,7 +132,7 @@ class UserProfileController(object): | ||
132 | 132 | """ |
133 | 133 | |
134 | 134 | username = c.project.shortname.split('/')[1] |
135 | - user = User.query.get(username=username) | |
135 | + user = User.by_username(username) | |
136 | 136 | parts = [p for p in repo_path.split(os.path.sep) if p] |
137 | 137 | project_path = '/' + '/'.join(parts[1:]) |
138 | 138 | project, rest = h.find_project(project_path) |
@@ -88,18 +88,8 @@ class SfxLoginMiddleware(object): | ||
88 | 88 | if sfx_user_id: |
89 | 89 | server_name = request.environ['HTTP_HOST'] |
90 | 90 | user_data = mgr.user_data(server_name, sfx_user_id) |
91 | - user = M.User.query.get(username=user_data['username']) | |
92 | - if not user: | |
93 | - with fake_pylons_context(request): | |
94 | - user = M.User(username=user_data['username'], | |
95 | - display_name=user_data['name']) | |
96 | - n = M.Neighborhood.query.get(name='Users') | |
97 | - n.register_project('u/' + user.username, user, user_project=True) | |
98 | - if user.display_name != user_data['name']: | |
99 | - user.display_name = user_data['name'] | |
100 | - sfx_user_id_num = int(sfx_user_id.split(':')[-1]) | |
101 | - if user.sfx_userid != sfx_user_id_num: | |
102 | - user.sfx_userid = sfx_user_id_num | |
91 | + with fake_pylons_context(request): | |
92 | + user = M.User.by_username(user_data['username'], user_data) | |
103 | 93 | session['sfx-sessid'] = request.cookies[cookie_name] |
104 | 94 | session['userid'] = user._id |
105 | 95 | session.save() |
@@ -170,11 +170,20 @@ class User(MappedClass): | ||
170 | 170 | return '/u/' + self.username + '/' |
171 | 171 | |
172 | 172 | @classmethod |
173 | - def by_email_address(self, addr): | |
173 | + def by_email_address(cls, addr): | |
174 | 174 | ea = EmailAddress.query.get(_id=addr) |
175 | 175 | if ea is None: return None |
176 | 176 | return ea.claimed_by_user() |
177 | 177 | |
178 | + @classmethod | |
179 | + def by_username(cls, name, extra=None): | |
180 | + u = cls.query.get(username=name) | |
181 | + if u is None and config.get('auth.method', 'local') == 'sfx': | |
182 | + from pyforge.ext.sfx.lib import sfx_api | |
183 | + api = sfx_api.SFXUserApi() | |
184 | + u = api.upsert_user(name, extra) | |
185 | + return u | |
186 | + | |
178 | 187 | def address_object(self, addr): |
179 | 188 | return EmailAddress.query.get(_id=addr, claimed_by_user_id=self._id) |
180 | 189 |