blob: f766cbf3998eddd5b322f4dc524d732c55519fc2 [file] [log] [blame]
# Copyright 2013 the Melange authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Logic for users."""
from google.appengine.api import users as users_api
from google.appengine.ext import ndb
from django.utils import translation
from melange.models import user as user_model
from melange.utils import rich_bool
_ACCOUNT_NOT_LOGGED_IN = translation.ugettext(
'User may be registered only for a user logged in with Google Account.')
_USER_EXISTS_FOR_USERNAME = translation.ugettext(
'User already exists for username %s.')
def createUser(username, host_for=None):
"""Creates a new User entity for the specified username for the currently
logged in account.
Please note that there should be one-one relationship between Google Accounts
and User entities. This function, however, does not check if User entity does
not exist for the account. Therefore, the callers should try to make sure that
this function will not create a duplicate User entity.
This function will raise an error, if it is not called from within
a transaction.
Args:
username: A string containing username.
host_for: A list of program keys for which the user has a program
administrator role.
Returns:
RichBool whose value is set to True if user has been successfully created.
In that case, extra part points to the newly created user entity. Otherwise,
RichBool whose value is set to False and extra part is a string that
represents the reason why the action could not be completed.
"""
if not ndb.in_transaction():
raise RuntimeError('This function must be called from within a transaction')
account = users_api.get_current_user()
if not account:
return rich_bool.RichBool(False, _ACCOUNT_NOT_LOGGED_IN)
elif user_model.User.get_by_id(username):
# there is already a user with the specified username
return rich_bool.RichBool(False, _USER_EXISTS_FOR_USERNAME % username)
else:
host_for = host_for or []
user = user_model.User(
id=username, account_id=account.user_id(), host_for=host_for)
user.put()
return rich_bool.RichBool(True, user)
def getByCurrentAccount():
"""Returns user_model.User entity associated with Google account of
the current user.
Please note that this function executes a non-ancestor query, so it cannot
be safely used within transactions.
Returns:
user_model.User entity for the current account or None, if no entity has
ever been created for this user.
"""
account = users_api.get_current_user()
return None if not account else user_model.User.query(
user_model.User.account_id == account.user_id()).get()
def isHostForProgram(user, program_key):
"""Tells whether the specified user is a host for the specified program.
If no user entity is supplied, it is considered as not a program host.
Args:
user: User entity.
program_key: Program key.
Returns:
True if the specified user is a host for the specified program.
False, otherwise.
"""
return user and ndb.Key.from_old_key(program_key) in user.host_for
def getHostsForProgram(program_key):
"""Returns all users who are hosts for the specified program.
Args:
program_key: Program key.
Returns:
A list of user entities representing program administrators.
"""
query = user_model.User.query(
user_model.User.host_for == ndb.Key.from_old_key(program_key))
return query.fetch(1000)