1 #!/usr/bin/python2.5 |
|
2 # |
|
3 # Copyright 2008 the Melange authors. |
|
4 # |
|
5 # Licensed under the Apache License, Version 2.0 (the "License"); |
|
6 # you may not use this file except in compliance with the License. |
|
7 # You may obtain a copy of the License at |
|
8 # |
|
9 # http://www.apache.org/licenses/LICENSE-2.0 |
|
10 # |
|
11 # Unless required by applicable law or agreed to in writing, software |
|
12 # distributed under the License is distributed on an "AS IS" BASIS, |
|
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
14 # See the License for the specific language governing permissions and |
|
15 # limitations under the License. |
|
16 |
|
17 """Basic ID (Google Account) and User (Model) query functions. |
|
18 """ |
|
19 |
|
20 __authors__ = [ |
|
21 '"Chen Lunpeng" <forever.clp@gmail.com>', |
|
22 '"Todd Larsen" <tlarsen@google.com>', |
|
23 ] |
|
24 |
|
25 |
|
26 from google.appengine.api import users |
|
27 |
|
28 from soc.logic import model |
|
29 from soc.logic import models |
|
30 from soc.logic import out_of_band |
|
31 |
|
32 import soc.models.user |
|
33 |
|
34 |
|
35 def findNearestUsersOffset(width, id=None, link_name=None): |
|
36 """Finds offset of beginning of a range of Users around the nearest User. |
|
37 |
|
38 Args: |
|
39 width: the width of the "found" window around the nearest User found |
|
40 id: a Google Account (users.User) object, or None |
|
41 link_name: link name input in the Lookup form or None if not supplied. |
|
42 |
|
43 Returns: |
|
44 an offset into the list of Users that is width/2 less than the |
|
45 offset of the first User returned by getNearestUsers(), or zero if |
|
46 that offset would be less than zero |
|
47 OR |
|
48 None if there are no nearest Users or the offset of the beginning of |
|
49 the range cannot be found for some reason |
|
50 """ |
|
51 return model.findNearestEntitiesOffset( |
|
52 width, soc.models.user.User, [('id', id), ('link_name', link_name)]) |
|
53 |
|
54 |
|
55 def isIdDeveloper(id=None): |
|
56 """Returns True if a Google Account is a Developer with special privileges. |
|
57 |
|
58 Since it only works on the current logged-in user, if id matches the |
|
59 current logged-in Google Account, the App Engine Users API function |
|
60 user.is_current_user_admin() is checked. If that returns False, or |
|
61 id is not the currently logged-in user, the is_developer property of |
|
62 the User entity corresponding to the id Google Account is checked next. |
|
63 |
|
64 This solves the "chicken-and-egg" problem of no User entity having its |
|
65 is_developer property set, but no one being able to set it. |
|
66 |
|
67 Args: |
|
68 id: a Google Account (users.User) object; if id is not supplied, |
|
69 the current logged-in user is checked |
|
70 """ |
|
71 |
|
72 # Get the currently logged in user |
|
73 current_id = users.get_current_user() |
|
74 |
|
75 if not (id or current_id): |
|
76 # no Google Account was supplied or is logged in, so an unspecified |
|
77 # User is definitely *not* a Developer |
|
78 return False |
|
79 |
|
80 if ((not id) or (id == current_id)) and users.is_current_user_admin(): |
|
81 # no id supplied, or current logged-in user, and that user is in the |
|
82 # Administration->Developers list in the App Engine console |
|
83 return True |
|
84 |
|
85 if not id: |
|
86 id = current_id |
|
87 |
|
88 user = models.user.logic.getForFields({'id': id}, unique=True) |
|
89 |
|
90 if not user: |
|
91 # no User entity for this Google Account, and id is not the currently |
|
92 # logged-in user, so there is no conclusive way to check the |
|
93 # Administration->Developers list in the App Engine console |
|
94 return False |
|
95 |
|
96 return user.is_developer |
|
97 |
|
98 |
|
99 def isIdAvailable(new_id, existing_user=None, existing_key_name=None): |
|
100 """Returns True if Google Account is available for use by existing User. |
|
101 |
|
102 Args: |
|
103 new_id: a Google Account (users.User) object with a (possibly) new email |
|
104 existing_user: an existing User entity; default is None, in which case |
|
105 existing_key_name is used to look up the User entity |
|
106 existing_key_name: the key_name of an existing User entity, used |
|
107 when existing_user is not supplied; default is None |
|
108 """ |
|
109 if not existing_user: |
|
110 existing_user = models.user.logic.getFromKeyName(existing_key_name) |
|
111 |
|
112 if existing_user: |
|
113 old_email = existing_user.id.email() |
|
114 else: |
|
115 old_email = None |
|
116 |
|
117 if new_id.email().lower() == old_email.lower(): |
|
118 # "new" email is same as existing User wanting it, so it is "available" |
|
119 return True |
|
120 # else: "new" email truly is new to the existing User, so keep checking |
|
121 |
|
122 if not models.user.logic.getForFields({'id': new_id}, unique=True): |
|
123 # new email address also does not belong to any other User, |
|
124 # so it is available |
|
125 return True |
|
126 |
|
127 # email does not already belong to this User, but to some other User |
|
128 return False |
|
129 |
|
130 |
|
131 def getUserFromLinkName(link_name): |
|
132 """Returns User entity for link_name or None if not found. |
|
133 |
|
134 Args: |
|
135 link_name: link name used in URLs to identify user |
|
136 """ |
|
137 return soc.models.user.User.gql('WHERE link_name = :1', link_name).get() |
|
138 |
|
139 |
|
140 def getUserFromLinkNameOr404(link_name): |
|
141 """Like getUserFromLinkName but expects to find a user |
|
142 |
|
143 Raises: |
|
144 out_of_band.ErrorResponse if no User entity is found |
|
145 """ |
|
146 |
|
147 user = getUserFromLinkName(link_name) |
|
148 |
|
149 if user: |
|
150 return user |
|
151 |
|
152 raise out_of_band.ErrorResponse( |
|
153 'There is no user with a "link name" of "%s".' % link_name, status=404) |
|
154 |
|
155 |
|
156 def doesLinkNameBelongToId(link_name, id): |
|
157 """Returns True if supplied link name belongs to supplied Google Account. |
|
158 |
|
159 Args: |
|
160 link_name: link name used in URLs to identify user |
|
161 id: a Google Account object |
|
162 """ |
|
163 |
|
164 if not id: |
|
165 # link name cannot belong to an unspecified User |
|
166 return False |
|
167 |
|
168 user = models.user.logic.getForFields({'id': id}, unique=True) |
|
169 |
|
170 if not user: |
|
171 # no User corresponding to id Google Account, so no link name at all |
|
172 return False |
|
173 |
|
174 return user.link_name == link_name |
|