def yield_all_perms(): def valid_timezone(timezone):
    try:
        pytz.timezone(timezone)
    except UnknownTimeZoneError:
        return False
    return True def exists_by_expr(t, expr):
    # TODO: use exists instead of count
    q = select([func.count("*").label("c")], from_obj=t).where(expr)
    r = meta.DBSession.execute(q).fetchone()
    if r.c > 0:
        return True
    else:
        return False def update_connection():
    session = meta.DBSession() if callable(meta.DBSession) else meta.DBSession
    mark_changed(session)
    return session class APIError(Exception):
    def __init__(self, code, status, message):
        self.code = code
        self.status = status
        self.message = message class FormularEvaluationException(Exception):
    def __init__(self, message):
        self.message = message def get_default_token_valid_time():
    def password(self):
    def password(self,new_pw):
    def verify_password(self, pw):
    def check_password_strength(cls, password):
    def get_or_create_token(self):
    def may_increase(cls, variable_row, request, subject_id):
    def generate_token():
    def extend(self):
    def __unicode__(self, *args, **kwargs):
    def __unicode__(self, *args, **kwargs):
    def __unicode__(self, *args, **kwargs):
    def __unicode__(self, *args, **kwargs):
    def add_or_update_device(cls, subject_id, device_id, push_id, device_os, app_version):
    def __unicode__(self, *args, **kwargs):
    def __init__(self, *args, **kw):
    def get_subject(cls,subject_id):
    def get_subjects(cls, subject_ids):
    def set_relations(cls, subject_id, relation_ids):
    def set_parent_subjects(cls, subject_id, parent_subject_ids):
    def set_infos(cls, subject_id, lat, lng, timezone, language_id, additional_public_data):
    def delete_subject(cls,subject_id):
    def basic_output(cls, subject):
    def full_output(cls, subject_id):
    def get_ancestor_subjects(cls, subject_id, of_type_id, from_date, to_date, whole_time_required):
    def get_descendent_subjects(cls, subject_id, of_type_id, from_date, to_date, whole_time_required):
    def join_subject(cls,
                     subject_id,
                     part_of_id,
                     join_date):
    def leave_subject(cls,
                      subject_id,
                      part_of_id,
                      leave_date):
    def __unicode__(self, *args, **kwargs):
    def basic_output(cls, subjecttype):
    def __unicode__(self, *args, **kwargs):
    def get_variable_by_name(cls,name):
    def map_variables_to_rules(cls):
    def increase_value(cls, variable_name, subject_id, value, key, at_datetime, populate_to_ancestors=True, override_agent_id=None):
    def get_achievementcategory(cls, achievementcategory_id):
    def __unicode__(self, *args, **kwargs):
    def __init__(self, from_date, to_date):
    def __repr__(self):
    def __str__(self):
    def __json__(self, *args, **kw):
    def __lt__(self, other):
    def db_format(cls, instance):
    def compute(cls, evaluation_timezone, evaluation_type, evaluation_shift, context_datetime):
    def __unicode__(self, *args, **kwargs):
    def is_leaderboard(cls, achievement):
    def get_achievement(cls,achievement_id):
    def get_achievements_by_subject_for_today(cls,subject):
        def generate_achievements_by_subject_for_today():
    def get_achievements_by_location(cls, latlng):
    def get_achievements_by_date(cls, date):
    def get_relevant_contexts(cls, subject_id, achievement, from_date, to_date, whole_time_required):
    def get_relevant_subjects_by_achievement_and_subject(cls, achievement, subject, context_subject_id, from_date, to_date):
    def get_level(cls, subject_id, achievement_id, achievement_date, context_subject_id):
        def generate():
    def get_level_int(cls, subject_id, achievement_id, achievement_date, context_subject_id):
    def basic_output(cls, achievement, include_levels=True, max_level_included=None):
    def evaluate(cls, compared_subject, achievement_id, achievement_date, context_subject_id, execute_triggers=True, generate_output=True, skip_trigger_action=False):
        def generate():
    def get_rewards(cls, achievement_id, level):
    def get_achievement_properties(cls, achievement_id, level):
    def compute_progress(cls, achievement, subject, achievement_date):
        def generate_statement_cache():
    def select_and_execute_triggers(cls, achievement, achievement_date, subject, level, current_goal, value, previous_goal, context_subject_id, skip_trigger_action=False):
    def get_leaderboard(cls, achievement, achievement_date, subject_ids, context_subject_id):
    def __unicode__(self, *args, **kwargs):
    def __unicode__(self, *args, **kwargs):
    def get_achievement_reward(cls, achievement_reward_id):
    def __unicode__(self, *args, **kwargs):
    def __unicode__(self, *args, **kwargs):
    def __unicode__(self, *args, **kwargs):
    def trs(cls, translation_id, params={}):
    def get_translation_variable(cls, translation_id):
    def get_languages(cls):
    def __unicode__(self, *args, **kwargs):
    def get_text(cls, row):
    def text(self):
    def deliver(cls, message):
    def __unicode__(self, *args, **kwargs):
    def __unicode__(self, *args, **kwargs):
    def execute(cls, trigger_step, subject, current_percentage, value, achievement_goal, level, properties, achievement_date, context_subject_id, suppress_actions=False):
    def __unicode__(self, *args, **kwargs):
    def __unicode__(self, *args, **kwargs):
def insert_trigger_step_executions_after_step_upsert(mapper,connection,target):
def backref(*args,**kw):
def relationship(*args,**kw):
class AuthUser(ABase):
class AuthToken(ABase):
class AuthRole(ABase):
class AuthRolePermission(ABase):
class SubjectDevice(ABase):
class Subject(ABase):
class SubjectType(ABase):
class Variable(ABase):
class Value(ABase):
class AchievementCategory(ABase):
class AchievementDate:
class Achievement(ABase):
class AchievementProperty(ABase):
class AchievementAchievementProperty(ABase):
class Reward(ABase):
class AchievementReward(ABase):
class Evaluation(ABase):
class Progress(ABase):
class Language(ABase):
class TranslationVariable(ABase):
class Translation(ABase):
class SubjectMessage(ABase):
class AchievementTrigger(ABase):
class AchievementTriggerStep(ABase):
class Task(ABase):
class TaskExecution(ABase): def get_settings():
    global _settings
    return _settings def dt_now():
    return datetime.datetime.utcnow().replace(tzinfo=pytz.utc) class MySession(Session):
    def commit(self,*args,**kw):
    def rollback(self, *args, **kw):
def get_sessionmaker(bind=None):
def init_session(override_session=None, replace=False):
def init_declarative_base(override_base=None):
def init_db(engine): class HTTPSProxied(object):
    def __init__(self, app):
        self.app = app

    def __call__(self, environ, start_response):
        if force_https:
            environ['wsgi.url_scheme'] = "https"
        return self.app(environ, start_response)
import traceback
import binascii
import base64
import copy
import datetime
import json
import pytz
from http.cookies import SimpleCookie
from dateutil import relativedelta
from pyramid.request import Request
from pyramid.response import Response
from pyramid.settings import asbool
from sqlalchemy.sql.expression import select, and_
from gengine.app.permissions import perm_own_update_subject_infos, perm_global_manage_subjects, perm_global_delete_subject, perm_own_delete_subject, \
    perm_global_access_admin_ui, perm_global_register_device, perm_own_register_device, perm_global_read_messages, \
    perm_own_read_messages
from gengine.base.model import valid_timezone, exists_by_expr, update_connection
from gengine.base.errors import APIError
from pyramid.exceptions import NotFound
from pyramid.renderers import render
from pyramid.view import view_config
from pyramid.wsgi import wsgiapp2
from werkzeug import DebuggedApplication
from gengine.app.formular import FormularEvaluationException
from gengine.app.model import (
    Subject,
    Achievement,
    Value,
    Variable,
    AuthUser, AuthToken, t_subjects, t_auth_users, t_auth_users_roles, t_auth_roles, t_auth_roles_permissions,
    SubjectDevice,
    t_subject_device, t_subject_messages, SubjectMessage, AchievementDate)
from gengine.base.settings import get_settings
from gengine.base.util import dt_now
from gengine.metadata import DBSession
from gengine.wsgiutil import HTTPSProxied
    from gengine.app.admin import adminapp
        raise APIError(401, "change_password.email_or_old_password_invalid", "Either the email address or the old password is wrong.")

    if not user.active:
        raise APIError(400, "user_is_not_activated", "Your user is not activated.")

    if new_password == old_password:
        raise APIError(400, "change_password.may_not_be_the_same", "The new password may not be the same as the old one.")

    if not AuthUser.check_password_strength(new_password):
        raise APIError(400, "change_password.invalid_new_password", "The new password is too weak. Minimum length is 8 characters.")

    user.password = new_password
    user.force_password_change = False
    DBSession.add(user)

    token = AuthToken.generate_token()
    tokenObj = AuthToken(
        auth_user_id=user.id,
        token=token
    )
    DBSession.add(tokenObj)

    DBSession.flush()

    return {
        "token": token,
        "subject": Subject.full_output(user.subject_id),
    }


@view_config(route_name='register_device', renderer='json', request_method="POST")
def register_device(request):
    try:
        doc = request.json_body
    except:
        raise APIError(400, "invalid_json", "no valid json body")

    subject_id = int(request.matchdict["subject_id"])

    device_id = doc.get("device_id")
    push_id = doc.get("push_id")
    device_os = doc.get("device_os")
    app_version = doc.get("app_version")

    if not device_id \
            or not push_id \
            or not subject_id \
            or not device_os \
            or not app_version:
        raise APIError(400, "register_device.required_fields",
                       "Required fields: device_id, push_id, device_os, app_version")

    if asbool(get_settings().get("enable_user_authentication", False)):
        may_register = request.has_perm(perm_global_register_device) or request.has_perm(
            perm_own_register_device) and str(request.subject.id) == str(subject_id)
        if not may_register:
            raise APIError(403, "forbidden", "You may not register devices for this subject.")

    if not exists_by_expr(t_subjects, t_subjects.c.id==subject_id):
        raise APIError(404, "register_device.subject_not_found",
                       "There is no subject with this id.")

    SubjectDevice.add_or_update_device(subject_id = subject_id, device_id = device_id, push_id = push_id, device_os = device_os, app_version = app_version)

    return {
        "status" : "ok"
    }

@view_config(route_name='get_messages', renderer='json', request_method="GET")
def get_messages(request):
    try:
        subject_id = int(request.matchdict["subject_id"])
    except:
        subject_id = None

    try:
        offset = int(request.GET.get("offset",0))
    except:
        offset = 0

    limit = 100

    if asbool(get_settings().get("enable_user_authentication", False)):
        may_read_messages = request.has_perm(perm_global_read_messages) or request.has_perm(
            perm_own_read_messages) and str(request.subject.id) == str(subject_id)
        if not may_read_messages:
            raise APIError(403, "forbidden", "You may not read the messages of this subject.")

    if not exists_by_expr(t_subjects, t_subjects.c.id == subject_id):
        raise APIError(404, "get_messages.subject_not_found",
                       "There is no subject with this id.")

    q = t_subject_messages.select().where(t_subject_messages.c.subject_id==subject_id).order_by(t_subject_messages.c.created_at.desc()).limit(limit).offset(offset)
    rows = DBSession.execute(q).fetchall()

    return {
        "messages" : [{
            "id" : message["id"],
            "text" : SubjectMessage.get_text(message),
            "is_read" : message["is_read"],
            "created_at" : message["created_at"]
        } for message in rows]
    }


@view_config(route_name='read_messages', renderer='json', request_method="POST")
def set_messages_read(request):
    try:
        doc = request.json_body
    except:
        raise APIError(400, "invalid_json", "no valid json body")

    subject_id = int(request.matchdict["subject_id"])

    if asbool(get_settings().get("enable_user_authentication", False)):
        may_read_messages = request.has_perm(perm_global_read_messages) or request.has_perm(
            perm_own_read_messages) and str(request.subject.id) == str(subject_id)
        if not may_read_messages:
            raise APIError(403, "forbidden", "You may not read the messages of this subject.")


    if not exists_by_expr(t_subjects, t_subjects.c.id == subject_id):