예제 #1
0
파일: user.py 프로젝트: m3rryqold/sagefy
def log_in_route(request):
    """
    Log in user.
    """

    db_conn = request['db_conn']
    name = request['params'].get('name') or ''
    name = name.lower().strip()

    user = get_user({'name': name}, db_conn)
    if not user:
        user = get_user({'email': request['params'].get('name')}, db_conn)
    if not user:
        return 404, {
            'errors': [{
                'name': 'name',
                'message': c('no_user'),
            }],
            'ref': 'FYIPOI8g2nzrIEcJYSDAfmti'
        }
    real_encrypted_password = user['password']
    given_password = request['params'].get('password')
    if not is_password_valid(real_encrypted_password, given_password):
        return 400, {
            'errors': [{
                'name': 'password',
                'message': c('no_match'),
            }],
            'ref': 'UwCRydZ7Agi7LYKv9c1y07ft'
        }
    return _log_in(user)
예제 #2
0
def log_in_route(request):
    """
    Log in user.
    """

    name = request['params'].get('name') or ''
    name = name.lower()

    user = User.get(name=name)
    if not user:
        user = User.get(email=request['params'].get('name'))
    if not user:
        return 404, {
            'errors': [{
                'name': 'name',
                'message': c('no_user'),
            }],
            'ref': 'FYIPOI8g2nzrIEcJYSDAfmti'
        }
    if not user.is_password_valid(request['params'].get('password')):
        return 400, {
            'errors': [{
                'name': 'password',
                'message': c('no_match'),
            }],
            'ref': 'UwCRydZ7Agi7LYKv9c1y07ft'
        }
    return _log_in(user)
예제 #3
0
def log_in_route(request):
  """
  Log in user.
  """

  db_conn = request['db_conn']
  name = request['params'].get('name') or ''
  name = name.lower().strip()
  user = get_user(db_conn, {'name': name})
  if not user:
    user = get_user(db_conn, {'email': name})
  if not user:
    return 404, {
      'errors': [{
        'name': 'name',
        'message': c('no_user'),
        'ref': 'dfhMHDFbT42CmRRmN14gdA',
      }],
    }
  real_encrypted_password = user['password']
  given_password = request['params'].get('password')
  if not is_password_valid(real_encrypted_password, given_password):
    return 400, {
      'errors': [{
        'name': 'password',
        'message': c('no_match'),
        'ref': 'DTarUzzsSLKarq-uIsXkFQ',
      }],
    }
  return _log_in(user)
예제 #4
0
파일: user.py 프로젝트: Folashade/sagefy
def log_in_route(request):
    """
    Log in user.
    """

    name = request['params'].get('name') or ''
    name = name.lower()

    user = User.get(name=name)
    if not user:
        user = User.get(email=request['params'].get('name'))
    if not user:
        return 404, {
            'errors': [{
                'name': 'name',
                'message': c('no_user'),
            }],
            'ref': 'FYIPOI8g2nzrIEcJYSDAfmti'
        }
    if not user.is_password_valid(request['params'].get('password')):
        return 400, {
            'errors': [{
                'name': 'password',
                'message': c('no_match'),
            }],
            'ref': 'UwCRydZ7Agi7LYKv9c1y07ft'
        }
    return _log_in(user)
예제 #5
0
def is_required(value):
    """
  Ensure the value is present.
  """

    if value is None:
        return c('required')
    if isinstance(value, str) and value == '':
        return c('required')
예제 #6
0
def is_list_of_strings(value):
    """
    Ensure the number is a list of strings.
    """

    if value is None:
        return

    if not isinstance(value, list):
        return c('list')

    for v in value:
        if not isinstance(v, str):
            return c('string')
예제 #7
0
def is_list_of_uuids(value):
    """
  Ensure the value is a list of UUIDs.
  """

    if value is None:
        return

    if not isinstance(value, list):
        return c('list')

    for entry in value:
        if not isinstance(entry, uuid.UUID):
            return c('uuid')
예제 #8
0
def is_list_of_strings(value):
    """
  Ensure the number is a list of strings.
  """

    if value is None:
        return

    if not isinstance(value, list):
        return c('list')

    for entry in value:
        if not isinstance(entry, str):
            return c('string')
예제 #9
0
def is_required(value):
    """
    Ensure the value is present.
    """

    if value is None:
        return c('required')
예제 #10
0
def is_required(value):
    """
    Ensure the value is present.
    """

    if value is None:
        return c('required')
예제 #11
0
def has_min_length(value, ln):
    """
    Ensure the given value is a minimum length.
    """
    if value is None:
        return

    if not value or len(value) < ln:
        return c('minlength').replace('{length}', str(ln))
예제 #12
0
def has_min_length(value, leng):
    """
  Ensure the given value is a minimum length.
  """
    if value is None:
        return

    if not value or len(value) < leng:
        return c('minlength').replace('{length}', str(leng))
예제 #13
0
def is_email(value):
    """
  Ensure the given value is formatted as an email.
  """

    if value is None:
        return

    if not re.match(r'\S+@\S+\.\S+', value):
        return c('email')
예제 #14
0
def is_url(value):
    """
  Ensure the given value is formatted as an URL.
  """

    if value is None:
        return

    if not re.match(r'^(http(s)?:)?//[^.]+\..+$', value):
        return c('url')
예제 #15
0
def is_list(value):
    """
  Ensure the given value is a list.
  """

    if value is None:
        return

    if not isinstance(value, list):
        return c('list')
예제 #16
0
def is_dict(value):
    """
  Ensure the given value is a dict.
  """

    if value is None:
        return

    if not isinstance(value, dict):
        return c('dict')
예제 #17
0
def is_email(value):
    """
    Ensure the given value is formatted as an email.
    """

    if value is None:
        return

    if not re.match(r'\S+@\S+\.\S+', value):
        return c('email')
예제 #18
0
def is_language(value):
    """
    Entity must be ISO 639-1 code.
    """

    if value is None:
        return

    if not isinstance(value, str) or len(value) != 2:
        return c('language')
예제 #19
0
def is_boolean(value):
    """
    Ensure the given value is a boolean.
    """

    if value is None:
        return

    if not isinstance(value, bool):
        return c('boolean')
예제 #20
0
def is_url(value):
    """
    Ensure the given value is formatted as an URL.
    """

    if value is None:
        return

    if not re.match(r'^(http(s)?:)?//[^.]+\..+$', value):
        return c('url')
예제 #21
0
def is_list(value):
    """
    Ensure the given value is a list.
    """

    if value is None:
        return

    if not isinstance(value, list):
        return c('list')
예제 #22
0
def is_dict(value):
    """
    Ensure the given value is a dict.
    """

    if value is None:
        return

    if not isinstance(value, dict):
        return c('dict')
예제 #23
0
def is_language(value):
    """
    Entity must be ISO 639-1 code.
    """

    if value is None:
        return

    if not isinstance(value, str) or len(value) != 2:
        return c('language')
예제 #24
0
def is_string_or_number(value):
    """
    Ensure the given value is a string or number.
    """

    if value is None:
        return

    if not isinstance(value, (str, int, float, complex)):
        return c('string_or_number')
예제 #25
0
def is_one_of(value, *options):
    """
  Ensure the value is within an enumerated set.
  """
    if value is None:
        return

    if value not in options:
        str_options = [str(o) for o in options]
        return (c('options').replace('{options}', ', '.join(str_options)))
예제 #26
0
def is_string(value):
    """
    Ensure the given value is a string.
    """

    if value is None:
        return

    if not isinstance(value, str):
        return c('string')
예제 #27
0
def is_number(value):
    """
    Ensure the given value is a number.
    """

    if value is None:
        return

    if not isinstance(value, (int, float)):
        return c('number')
예제 #28
0
def is_boolean(value):
    """
  Ensure the given value is a boolean.
  """

    if value is None:
        return

    if not isinstance(value, bool):
        return c('boolean')
예제 #29
0
def is_integer(value):
    """
    Ensure the given value is a integer.
    """

    if value is None:
        return

    if not isinstance(value, int):
        return c('integer')
예제 #30
0
def has_max_length(value, ln):
    """
    Ensure the given value is a maximum length.
    """

    if value is None:
        return

    if not value or len(value) > ln:
        return c('maxlength').replace('{length}', str(ln))
예제 #31
0
def is_datetime(value):
    """
  Ensure the given value is a datetime.
  """

    if value is None:
        return

    if not isinstance(value, datetime):
        return c('datetime')
예제 #32
0
def is_string_or_number(value):
    """
  Ensure the given value is a string or number.
  """

    if value is None:
        return

    if not isinstance(value, (str, int, float, complex)):
        return c('string_or_number')
예제 #33
0
def log_in_route(request):
    """
    Log in user.
    """

    db_conn = request["db_conn"]
    name = request["params"].get("name") or ""
    name = name.lower().strip()

    user = get_user({"name": name}, db_conn)
    if not user:
        user = get_user({"email": request["params"].get("name")}, db_conn)
    if not user:
        return 404, {"errors": [{"name": "name", "message": c("no_user")}], "ref": "FYIPOI8g2nzrIEcJYSDAfmti"}
    real_encrypted_password = user["password"]
    given_password = request["params"].get("password")
    if not is_password_valid(real_encrypted_password, given_password):
        return 400, {"errors": [{"name": "password", "message": c("no_match")}], "ref": "UwCRydZ7Agi7LYKv9c1y07ft"}
    return _log_in(user)
예제 #34
0
def is_uuid(value):
    """
  Ensure the given value is a UUID.
  """

    if value is None:
        return

    if not isinstance(value, uuid.UUID):
        return c('uuid')
예제 #35
0
def is_integer(value):
    """
  Ensure the given value is a integer.
  """

    if value is None:
        return

    if not isinstance(value, int):
        return c('integer')
예제 #36
0
def is_number(value):
    """
  Ensure the given value is a number.
  """

    if value is None:
        return

    if not isinstance(value, (int, float)):
        return c('number')
예제 #37
0
def is_string(value):
    """
  Ensure the given value is a string.
  """

    if value is None:
        return

    if not isinstance(value, str):
        return c('string')
예제 #38
0
def has_correct_options(options):
    """
  Ensure the list of options has at least one correct option.
  """

    has_correct = False
    for option in options:
        if option.get('correct') is True:
            has_correct = True
    if not has_correct:
        return c('error_need_correct')
예제 #39
0
def is_one_of(value, *options):
    """
    Ensure the value is within an enumerated set.
    """
    if value is None:
        return

    if value not in options:
        str_options = [str(o) for o in options]
        return (c('options')
                .replace('{options}', ', '.join(str_options)))
예제 #40
0
def is_language(value):
    """
  Entity must be BPC 47 code.
  https://tools.ietf.org/rfc/bcp/bcp47.txt
  """

    if value is None:
        return

    if not isinstance(value, str) or len(value) != 2:
        return c('language')
예제 #41
0
파일: util.py 프로젝트: wincax88/sagefy
 def _(data, field_name, field_schema, prefix):
     if ('unique' not in field_schema or
             data.get(field_name) is None):
         return
     query = (r.table(schema['tablename'])
               .filter(r.row[field_name] == data.get(field_name))
               .filter(r.row['id'] != data['id']))
     if len(list(query.run(db_conn))) > 0:
         errors.append({
             'name': prefix + field_name,
             'message': c('unique'),
         })
예제 #42
0
def has_correct_options(options):
    """
    Ensure the list of options has at least one correct option.
    """

    has_correct = False

    for option in options:
        if option.get('correct') is True:
            has_correct = True

    if not has_correct:
        return c('error_need_correct')
예제 #43
0
def get_topic_route(request, topic_id):
    """
  Get a topic
  """

    db_conn = request['db_conn']
    topic = get_topic(db_conn, {'id': topic_id})
    if not topic:
        return 404, {
            'errors': [{
                'name': 'topic_id',
                'message': c('no_topic'),
            }],
            'ref': 'o5V4uBFXQC6WNeyKrhn5kA',
        }
    return 200, {'topic': deliver_topic(topic)}
예제 #44
0
파일: user.py 프로젝트: m3rryqold/sagefy
def get_email_token(user, send_email=True):
    """
    Create an email token for the user to reset their password.
    """

    token = uniqid()
    redis.setex(
        'user_password_token_{id}'.format(id=user['id']),  # key
        60 * 10,  # time
        bcrypt.encrypt(user['id'] + token)  # value
    )
    if send_email:
        send_mail(subject='Sagefy - Reset Password',
                  recipient=user['email'],
                  body=c('change_password_url').replace(
                      '{url}', '%spassword?id=%s&token=%s' %
                      ('https://sagefy.org/', user['id'], token)))
    return token
예제 #45
0
파일: user.py 프로젝트: Folashade/sagefy
    def get_email_token(self, send_email=True):
        """
        Create an email token for the user to reset their password.
        """

        token = uniqid()
        redis.setex(
            "user_password_token_{id}".format(id=self["id"]),  # key
            60 * 10,  # time
            bcrypt.encrypt(self["id"] + token),  # value
        )
        if send_email:
            send_mail(
                subject="Sagefy - Reset Password",
                recipient=self["email"],
                body=c("change_password_url").replace(
                    "{url}", "%spassword?id=%s&token=%s" % ("https://sagefy.org/", self["id"], token)
                ),
            )
        return token
예제 #46
0
def get_email_token(user, send_email=True):
    """
    Create an email token for the user to reset their password.
    """

    token = uniqid()
    redis.setex(
        'user_password_token_{id}'.format(id=user['id']),  # key
        60 * 10,  # time
        bcrypt.encrypt(user['id'] + token)  # value
    )
    if send_email:
        send_mail(
            subject='Sagefy - Reset Password',
            recipient=user['email'],
            body=c('change_password_url').replace(
                '{url}',
                '%spassword?id=%s&token=%s' %
                ('https://sagefy.org/', user['id'], token)
            )
        )
    return token
예제 #47
0
파일: notice.py 프로젝트: Folashade/sagefy
    def get_body(self):
        """
        Get the copy associated with this notice.
        """

        return c('notice_' + self['kind']).format(**self['data'])
예제 #48
0
def create_post_route(request, topic_id):
    """
    Create a new post on a given topic.
    Proposal: must include entity (card, unit, or set) information.
    Vote: must refer to a valid proposal.
    """

    db_conn = request['db_conn']

    current_user = get_current_user(request)
    if not current_user:
        return abort(401)

    topic = get_topic({'id': topic_id}, db_conn)
    if not topic:
        return 404, {
            'errors': [{
                'name': 'topic_id',
                'message': c('no_topic'),
            }],
            'ref': 'PCSFCxsJtnlP0x9WzbPoKcwM',
        }

    # ## STEP 1) Create post (and entity) instances
    post_data = request['params'].get('post')
    if not post_data:
        return 400, {
            'errors': [{
                'name': 'post',
                'message': 'Missing post data.',
            }],
            'ref': 'ykQpZwJKq54MTCxgkx0p6baW'
        }
    post_data = omit(post_data, (
        'id',
        'created',
        'modified',
    ))
    post_data['user_id'] = current_user['id']
    post_data['topic_id'] = topic_id
    post_ = instance_post_facade(post_data)
    post_kind = post_['kind']
    if post_kind == 'proposal':
        entity = instance_new_entity(request['params'])
        entity_kind = get_kind(request['params'])
        post_['entity_version'] = {
            'id': entity['id'],
            'kind': entity_kind,
        }

    # ## STEP 2) Validate post (and entity) instances
    errors = prefix_error_names('post.', post_.validate(db_conn))
    if post_kind == 'proposal':
        errors = (errors +
                  prefix_error_names('entity.', entity.validate(db_conn)))
    if len(errors):
        return 400, {'errors': errors, 'ref': 'tux33ztgFj9ittSpS7WKIkq7'}

    # ## STEP 3) Save post (and entity)
    post_.save(db_conn)
    if post_kind == 'proposal':
        entity.save(db_conn)

    # ## STEP 4) Add author as a follower
    insert_follow(
        {
            'user_id': current_user['id'],
            'entity': {
                'id': topic['id'],
                'kind': 'topic',
            }
        }, db_conn)
    # TODO-2 also follow the entity

    # ## STEP 5) Make updates based on proposal / vote status
    if post_kind == 'proposal':
        update_entity_status(db_conn, post_)
    if post_kind == 'vote':
        proposal = Proposal.get(db_conn, id=post_['replies_to_id'])
        update_entity_status(db_conn, proposal)

    # ## STEP 6) Send notices
    if post_kind == 'proposal':
        send_notices(db_conn,
                     entity_id=topic['entity']['id'],
                     entity_kind=topic['entity']['kind'],
                     notice_kind='create_proposal',
                     notice_data={
                         'user_name': current_user['name'],
                         'topic_name': topic['name'],
                         'entity_kind': topic['entity']['kind'],
                         'entity_name': topic['entity']['id'],
                     })

    # ## STEP 7) Return response
    return 200, {'post': post_.deliver()}
예제 #49
0
def get_posts_route(request, topic_id):
    """
    Get a reverse chronological listing of posts for given topic.
    Includes topic meta data and posts (or proposals or votes).
    Paginates.
    """

    db_conn = request['db_conn']

    # Is the topic valid?
    topic = get_topic({'id': topic_id}, db_conn)
    if not topic:
        return 404, {
            'errors': [{
                'name': 'topic_id',
                'message': c('no_topic'),
            }],
            'ref': 'pgnNbqSP1VUWkOYq8MVGPrSS',
        }

    # Pull the entity
    entity_kind = topic['entity']['kind']
    entity = get_latest_accepted(db_conn, entity_kind, topic['entity']['id'])

    # Pull all kinds of posts
    posts = get_posts_facade(db_conn,
                             limit=request['params'].get('limit') or 10,
                             skip=request['params'].get('skip') or 0,
                             topic_id=topic_id)

    # For proposals, pull up the proposal entity version
    # ...then pull up the previous version
    # ...make a diff between the previous and the proposal entity version
    diffs = {}
    entity_versions = {}
    for post_ in posts:
        if post_['kind'] == 'proposal':
            entity_version = entity_versions[post_['id']] = get_version(
                db_conn, post_['entity_version']['kind'],
                post_['entity_version']['id'])
            previous_version = get_version(db_conn,
                                           post_['entity_version']['kind'],
                                           entity_version['previous_id'])
            if previous_version:
                diffs[post_['id']] = object_diff(previous_version.deliver(),
                                                 entity_version.deliver())

    # TODO-2 SPLITUP create new endpoint for this instead
    users = {}
    for post_ in posts:
        user_id = post_['user_id']
        if user_id not in users:
            user = get_user({'id': user_id}, db_conn)
            if user:
                users[user_id] = {
                    'name': user['name'],
                    'avatar': get_avatar(user['email'], 48),
                }

    # TODO-2 SPLITUP create new endpoints for these instead
    output = {
        'topic': deliver_topic(topic),
        'posts': [p.deliver() for p in posts],
        'entity_versions':
        {p: ev.deliver('view')
         for p, ev in entity_versions.items()},
        # 'diffs': diffs,  TODO-2 this causes a circular dependency
        'users': users,
    }
    if entity:
        output[entity_kind] = entity.deliver()
    return 200, output
예제 #50
0
파일: topic.py 프로젝트: Folashade/sagefy
def create_post_route(request, topic_id):
    """
    Create a new post on a given topic.
    Proposal: must include entity (card, unit, or set) information.
    Vote: must refer to a valid proposal.
    """

    current_user = get_current_user(request)
    if not current_user:
        return abort(401)

    topic = Topic.get(id=topic_id)
    if not topic:
        return 404, {
            'errors': [{
                'name': 'topic_id',
                'message': c('no_topic'),
            }],
            'ref': 'PCSFCxsJtnlP0x9WzbPoKcwM',
        }

    # ## STEP 1) Create post (and entity) instances
    post_data = request['params'].get('post')
    if not post_data:
        return 400, {
            'errors': [{
                'name': 'post',
                'message': 'Missing post data.',
            }],
            'ref': 'ykQpZwJKq54MTCxgkx0p6baW'
        }
    post_data = omit(post_data, ('id', 'created', 'modified',))
    post_data['user_id'] = current_user['id']
    post_data['topic_id'] = topic_id
    post_ = instance_post_facade(post_data)
    post_kind = post_['kind']
    if post_kind == 'proposal':
        entity = instance_new_entity(request['params'])
        entity_kind = get_kind(request['params'])
        post_['entity_version'] = {
            'id': entity['id'],
            'kind': entity_kind,
        }

    # ## STEP 2) Validate post (and entity) instances
    errors = prefix_error_names('post.', post_.validate())
    if post_kind == 'proposal':
        errors = errors + prefix_error_names('entity.', entity.validate())
    if len(errors):
        return 400, {
            'errors': errors,
            'ref': 'tux33ztgFj9ittSpS7WKIkq7'
        }

    # ## STEP 3) Save post (and entity)
    post_.save()
    if post_kind == 'proposal':
        entity.save()

    # ## STEP 4) Add author as a follower
    Follow.insert({
        'user_id': current_user['id'],
        'entity': {
            'id': topic['id'],
            'kind': 'topic',
        }
    })
    # TODO-2 also follow the entity

    # ## STEP 5) Make updates based on proposal / vote status
    if post_kind == 'proposal':
        update_entity_status(post_)
    if post_kind == 'vote':
        proposal = Proposal.get(id=post_['replies_to_id'])
        update_entity_status(proposal)

    # ## STEP 6) Return response
    return 200, {'post': post_.deliver()}
예제 #51
0
파일: topic.py 프로젝트: Folashade/sagefy
def get_posts_route(request, topic_id):
    """
    Get a reverse chronological listing of posts for given topic.
    Includes topic meta data and posts (or proposals or votes).
    Paginates.
    """

    # Is the topic valid?
    topic = Topic.get(id=topic_id)
    if not topic:
        return 404, {
            'errors': [{
                'name': 'topic_id',
                'message': c('no_topic'),
            }],
            'ref': 'pgnNbqSP1VUWkOYq8MVGPrSS',
        }

    # Pull the entity
    entity_kind = topic['entity']['kind']
    entity = get_latest_accepted(entity_kind,
                                 topic['entity']['id'])

    # Pull all kinds of posts
    posts = get_posts_facade(
        limit=request['params'].get('limit') or 10,
        skip=request['params'].get('skip') or 0,
        topic_id=topic_id
    )

    # For proposals, pull up the proposal entity version
    # ...then pull up the previous version
    # ...make a diff between the previous and the proposal entity version
    diffs = {}
    entity_versions = {}
    for post_ in posts:
        if post_['kind'] == 'proposal':
            entity_version = entity_versions[post_['id']] = get_version(
                post_['entity_version']['kind'],
                post_['entity_version']['id']
            )
            previous_version = get_version(
                post_['entity_version']['kind'],
                entity_version['previous_id']
            )
            if previous_version:
                diffs[post_['id']] = object_diff(previous_version.deliver(),
                                                 entity_version.deliver())

    # TODO-2 SPLITUP create new endpoint for this instead
    users = {}
    for post_ in posts:
        user_id = post_['user_id']
        if user_id not in users:
            user = User.get(id=user_id)
            if user:
                users[user_id] = {
                    'name': user['name'],
                    'avatar': user.get_avatar(48)
                }

    # TODO-2 SPLITUP create new endpoints for these instead
    output = {
        'topic': topic.deliver(),
        'posts': [p.deliver() for p in posts],
        'entity_versions': {
            p: ev.deliver()
            for p, ev in entity_versions.items()
        },
        # 'diffs': diffs,  TODO-2 this causes a circular dependency
        'users': users,
    }
    if entity:
        output[entity_kind] = entity.deliver()
    return 200, output
예제 #52
0
파일: public.py 프로젝트: wincax88/sagefy
def index_route(request):
    """
    View a documentation page.
    """

    return 200, {'message': c('welcome')}
예제 #53
0
def get_notice_body(notice):
    """
    Get the copy associated with this notice.
    """

    return c('notice_' + notice['kind']).format(**notice['data'])
예제 #54
0
def is_score(val):
    if val > 1 or val < 0:
        return c('number')