app/soc/logic/site/id_user.py
changeset 481 94834a1e6c01
parent 480 9b07ddeb1412
child 482 839740b061ad
equal deleted inserted replaced
480:9b07ddeb1412 481:94834a1e6c01
     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