Ejemplo n.º 1
0
    def verify(self, conn, email, raw_password):
        if not email or not raw_password:
            raise ValidationError('ERR_LOGIN')

        result = db_utils.select(conn,
                                 "users",
                                 columns=("id", "password", "salt",
                                          "hash_iteration_count",
                                          "hash_algorithm"),
                                 where={'email': email.lower()},
                                 limit=1)
        if not result or len(result) == 0:
            raise ValidationError('ERR_LOGIN')

        users_id, password, salt, hash_iteration_count, hash_algorithm = result[
            0]
        auth_token = get_preimage(hash_algorithm, hash_iteration_count, salt,
                                  raw_password)
        if password != get_authenticator(hash_algorithm, auth_token):
            raise ValidationError('ERR_LOGIN')

        if (hash_algorithm != settings.DEFAULT_PASSWORD_HASH_ALGORITHM
                or hash_iteration_count < settings.HASH_MIN_ITERATIONS):
            auth_token = self.auth_update(conn, users_id, raw_password)
        return users_id, auth_token
Ejemplo n.º 2
0
    def add_card(self, conn, data):
        # validation
        for param in ['id_user', 'pan', 'cvc', 'expiration_date']:
            if not data.get(param):
                raise ValidationError('Missing param %s' % param)

        id_user = data['id_user']
        cardholder_name = data.get('cardholder_name', '')
        pan = data['pan']
        cvc = data['cvc']
        expire = data['expiration_date']
        repeat = data.get('repeat')
        if not is_valid_cc_num(pan):
            raise ValidationError('Invalid param pan')
        if not is_valid_cvc(cvc):
            raise ValidationError('Invalid param cvc')
        try:
            datetime.strptime(expire, '%m%y')
        except:
            raise ValidationError('Invalid param expiration_date')

        results = db_utils.select(conn,
                                  'credit_card',
                                  where={
                                      'id_user': id_user,
                                      'cc_num': mask_cc_num(pan),
                                      'expiration_date': expire,
                                      'valid': True,
                                  })
        if results:
            raise ValidationError('Duplicated Card')

        values = {
            'id_user': id_user,
            'cardholder_name': cardholder_name,
            'cc_num': mask_cc_num(pan),
            'expiration_date': expire,
            'repeat': bool(repeat),
            'valid': False,
        }
        id_card = db_utils.insert(conn,
                                  'credit_card',
                                  values=values,
                                  returning='id')[0]

        cli = Paybox()
        token = cli.register_card(id_card,
                                  id_user,
                                  pan,
                                  cvc,
                                  expire,
                                  repeat=bool(repeat))
        db_utils.update(conn,
                        'credit_card',
                        values={
                            'paybox_token': token,
                            'valid': True
                        },
                        where={'id': id_card})
        return id_card
Ejemplo n.º 3
0
    def _on_post(self, req, resp, conn, **kwargs):
        ticket_id = req.get_param('ticket_id')
        priority = req.get_param('priority')
        escalation = req.get_param('escalation')

        update_values = {}
        if priority:
            if priority.isdigit() and int(
                    priority) not in TICKET_PRIORITY.toDict().values():
                raise ValidationError('INVALID_PARAM_PRIORITY')
            update_values.update({'priority': priority})

        if escalation:
            escalation = req.get_param('escalation') in ('True', 'true')
            update_values.update({'escalation': escalation})
            if escalation:
                update_values.update({'escalation_time': datetime.utcnow()})

        rows = db_utils.select(self.conn,
                               'ticket',
                               columns=('id', ),
                               where={'id': ticket_id},
                               limit=1)
        if not rows or len(rows) == 0:
            raise ValidationError('INVALID_PARAM_TICKET_ID')

        db_utils.update(conn,
                        "ticket",
                        values=update_values,
                        where={'id': ticket_id})

        return {"res": RESP_RESULT.S, "err": ""}
Ejemplo n.º 4
0
 def _on_get(self, req, resp, **kwargs):
     basket_key, basket_data = get_basket(req, resp)
     for quantity in basket_data.itervalues():
         try:
             if int(quantity) <= 0:
                 raise ValidationError('ERR_QUANTITY')
         except:
             raise ValidationError('ERR_QUANTITY')
     return {}
Ejemplo n.º 5
0
    def _update_address(self, conn, req, users_id):
        addr_dict = {}
        for p in req._params:
            if p.startswith('country_code_'):
                addr_dict[p.replace('country_code_', '')] = {}
        columns = ('addr_type', 'address', 'city', 'postal_code',
                   'country_code', 'province_code', 'address_desp', 'address2',
                   'full_name')
        for addr_id in addr_dict:
            addr_dict[addr_id]['users_id'] = users_id
            for c in columns:
                p = req.get_param('%s_%s' % (c, addr_id)) or ''
                if c == 'addr_type' and p.isdigit() \
                        and int(p) not in ADDR_TYPE.toDict().values():
                    raise ValidationError('INVALID_ADDR_TYPE')
                if c == 'address' and not re.match(addr_reexp, p):
                    raise ValidationError('INVALID_ADDRESS')
                if c == 'city' and not re.match(city_reexp, p):
                    raise ValidationError('INVALID_CITY')
                if c == 'postal_code' and not re.match(postal_code_reexp, p):
                    raise ValidationError('INVALID_POSTAL_CODE')
                addr_dict[addr_id][c] = p

            if int(addr_id) > 0 and \
                    int(addr_dict[addr_id]['addr_type']) == ADDR_TYPE.Both:
                raise ValidationError('INVALID_ADDR_TYPE')

            addr_changed = self._item_changed(conn, users_id, columns,
                                              "users_address", addr_id,
                                              addr_dict[addr_id])
            if addr_changed:
                addr_referenced = self._is_filed_referenced(
                    conn, users_id, 'id_shipaddr', 'users_address', addr_id) \
                               or self._is_filed_referenced(
                    conn, users_id, 'id_billaddr', 'users_address', addr_id)
            else:
                addr_referenced = False

            if (addr_id.isdigit() and int(addr_id) == 0 and int(
                    addr_dict[addr_id]['addr_type']) == ADDR_TYPE.Both):
                # insert two address records if add type is ADDR_TYPE.Both
                for t in (ADDR_TYPE.Shipping, ADDR_TYPE.Billing):
                    addr_dict[addr_id]['addr_type'] = t
                    db_utils.insert(conn,
                                    "users_address",
                                    values=addr_dict[addr_id])

            elif (addr_id.isdigit() and int(addr_id) == 0
                  or addr_changed and addr_referenced):
                db_utils.insert(conn,
                                "users_address",
                                values=addr_dict[addr_id])
            else:
                db_utils.update(conn,
                                "users_address",
                                values=addr_dict[addr_id],
                                where={'id': addr_id})
Ejemplo n.º 6
0
def cookie_verify(conn, req, resp):
    """ Verify cookie to check if user is in login status, update csrf
    token if pass cookie verification.
    Checked:
      * MAC
      * Auth, IP, request headers, csrf(for post request)

    conn: database connection.
    req: request.
    resp: response will send to client.
    """
    cookie = get_cookie(req)
    if not cookie:
        raise ValidationError('LOGIN_REQUIRED_ERR_UNSET_COOKIE')

    # 'USER_AUTH' should be in the cookie.
    required_fields = [USER_AUTH_COOKIE_NAME]
    for field in required_fields:
        if not cookie.has_key(field):
            raise ValidationError('LOGIN_REQUIRED_ERR_EMPTY_COOKIE')

    # authenticated information should be contained in 'USER_AUTH'
    auth_fields = ['exp', 'csrf', 'auth', 'digest', 'users_id']
    user_auth = cookie.get(USER_AUTH_COOKIE_NAME).value
    user_auth = _parse_auth_cookie(user_auth)
    for field in auth_fields:
        if not user_auth.has_key(field):
            raise ValidationError('LOGIN_REQUIRED_ERR_MISSING_DATA: %s' %
                                  field)

    # check if the cookie has been tampered with before going any further
    _hmac_verify(user_auth)

    users_id = user_auth['users_id']
    ip = get_client_ip(req)
    headers = get_hashed_headers(req)

    login_id = _user_verify(conn, users_id, user_auth, ip, headers)

    if req.method == 'POST':
        # set new csrf to cookie and database.
        csrf_token = gen_csrf_token()
        auth_cookie = make_auth_cookie(user_auth['exp'], csrf_token,
                                       user_auth['auth'], users_id)
        db_utils.update(conn,
                        'users_logins',
                        values={'csrf_token': csrf_token},
                        where={'id': login_id})
        conn.commit()
        set_cookie(resp,
                   USER_AUTH_COOKIE_NAME,
                   auth_cookie,
                   expiry=user_auth['exp'])
    return users_id
Ejemplo n.º 7
0
 def _sort(self, req, sql, params):
     sort = req.get_param('sort') or '-time'
     if sort:
         if sort[1:] == 'time':
             sql.append(" order by created ")
         elif sort[1:] == 'prio':
             sql.append(" order by priority ")
         else:
             raise ValidationError('INVALID_PARAM_SORT')
         if sort[0] not in ('+', '-'):
             raise ValidationError('INVALID_PARAM_SORT')
         sql.append(("desc" if sort[0] == '-' else "asc"))
Ejemplo n.º 8
0
def _user_verify(conn, users_id, user_auth, ip, headers):
    """ Verify user information for the request.

    conn: database connection.
    users_id: user's id.
    user_auth: pre-image for user's password.
    ip: IP address for the request.
    headers: request header information.
    """

    # XXX enforce expiry time
    expiry = datetime.datetime.strptime(user_auth['exp'], EXPIRY_FORMAT)
    if expiry < datetime.datetime.utcnow():
        raise ValidationError('LOGIN_REQUIRED_ERR_EXPIRED_AUTH')

    columns = ('password', 'hash_algorithm', 'csrf_token', 'users_logins.id')
    where = {
        'users.id': users_id,
        'users_logins.headers': headers,
        'users_logins.ip_address': ip,
        'users_logins.cookie_expiry__gt': datetime.datetime.utcnow()
    }
    result = db_utils.join(conn, ('users', 'users_logins'),
                           columns=columns,
                           on=[('users.id', 'users_logins.users_id')],
                           where=where,
                           limit=1)
    if not result or len(result) == 0:
        raise ValidationError('LOGIN_REQUIRED_ERR_INVALID_USER')

    exp_auth, hash_algo, exp_csrf, login_id = result[0]
    try:
        # XXX use the hash algorithm specified in the user account
        cur_auth = get_authenticator(hash_algo, user_auth['auth'])
        if cur_auth != exp_auth:
            raise ValidationError('LOGIN_REQUIRED_ERR_INVALID_AUTH')

        # XXX always verify the CSRF token
        if user_auth['csrf'] != exp_csrf:
            logging.error("Invalid csrf: cur: %s, exp: %s" %
                          (user_auth['csrf'], exp_csrf))
            raise ValidationError('LOGIN_REQUIRED_ERR_INVALID_CSRF')
    except ValidationError, e:
        # XXX delete the compromised session and propagate the exception
        # TODO: Maybe log the attacker informations somewhere?
        # That would be useful to display some Gmail-like warnings:
        # Somebody from <somewhere> tried to access your account on <datetime>
        logging.error('Delete compromised session for id %s '
                      'with error:%s' % (login_id, str(e)))

        db_utils.delete(conn, 'users_logins', where={'id': login_id})
        raise e
Ejemplo n.º 9
0
    def get_email(self, req, conn, users_id=None):
        email = req.get_param('email')
        if email is None or not is_valid_email(email):
            raise ValidationError('ERR_EMAIL')

        result = db_utils.select(conn,
                                 "users",
                                 columns=("id", ),
                                 where={'email': email.lower()},
                                 limit=1)
        if result and (users_id is None or str(users_id) != str(result[0][0])):
            raise ValidationError('EXISTING_EMAIL')
        return email.lower()
Ejemplo n.º 10
0
def login(req, resp):
    email = req.get_param('email')
    password = req.get_param('password')
    if not email:
        raise ValidationError('ERR_EMAIL')
    if not password:
        raise ValidationError('ERR_PASSWORD')

    remote_resp = data_access(REMOTE_API_NAME.LOGIN,
                              req, resp,
                              email=email,
                              password=password)
    return remote_resp
Ejemplo n.º 11
0
def api_key_verify(conn, email, api_key):
    result = db_utils.select(conn,
                             "users",
                             columns=("id", "salt", "hash_iteration_count"),
                             where={'email': email.lower()},
                             limit=1)
    if len(result) == 0:
        raise ValidationError('ERR_EMAIL')

    users_id, salt, hash_count = result[0]
    if api_key != get_api_key(email, salt, hash_count):
        raise ValidationError('ERR_API_KEY')
    return users_id
Ejemplo n.º 12
0
    def _check_ticket(self, id_ticket):
        if not id_ticket:
            raise ValidationError('INVALID_REQUEST')
        rows = db_utils.select(self.conn,
                               'ticket',
                               columns=('fo_author', 'fo_recipient'),
                               where={'id': id_ticket},
                               limit=1)
        if not rows or len(rows) == 0:
            raise ValidationError('INVALID_REQUEST')

        fo_author, fo_recipient = rows[0]
        if int(self.users_id) not in (fo_author, fo_recipient):
            raise ValidationError('INVALID_REQUEST')
Ejemplo n.º 13
0
    def coupon_update(self, req, resp, conn):
        id_brand = req.get_param('id_issuer')
        if not id_brand:
            raise ValidationError('COUPON_ERR_INVALID_ID_BRAND')

        id_coupon = req.get_param('id_coupon')
        coupons = db_utils.select(
            conn, 'coupons', where={'id': id_coupon})
        if not coupons:
            raise ValidationError('COUPON_ERR_INVALID_ID_COUPON')
        if coupons[0]['id_brand'] != int(id_brand):
            raise ValidationError('COUPON_ERR_INVALID_COUPON_FOR_BRAND')

        return self.coupon_create(req, resp, conn, id_coupon=id_coupon)
Ejemplo n.º 14
0
    def _on_get(self, req, resp, conn, **kwargs):
        brand_id = req.get_param('brand_id', None)
        if brand_id is None:
            raise ValidationError('INVALID_REQUEST')

        limit = req.get_param('limit')
        page = req.get_param('page') or '0'
        if not limit or not limit.isdigit() or not page or not page.isdigit():
            raise ValidationError('INVALID_REQUEST')

        offset = int(page) * int(limit)
        limit = int(limit) + 1
        orders = get_orders_list(conn, brand_id, [], self.users_id, limit,
                                 offset)
        return orders
Ejemplo n.º 15
0
def register(req, resp):
    email = req.get_param('email')
    password = req.get_param('password')
    password2 = req.get_param('password2')
    if not email:
        raise ValidationError('ERR_EMAIL')
    if not password or password != password2:
        raise ValidationError('ERR_PASSWORD')

    remote_resp = data_access(REMOTE_API_NAME.REGISTER,
                              req, resp,
                              action="create",
                              email=email,
                              password=password)
    return remote_resp
Ejemplo n.º 16
0
 def _on_get(self, req, resp, conn, **kwargs):
     res_name = req.get_param('get')
     if res_name not in self.get_res_func_map:
         raise ValidationError('INVALID_REQUEST')
     func = getattr(self, self.get_res_func_map[res_name], None)
     assert hasattr(func, '__call__')
     return func(req, resp, conn)
Ejemplo n.º 17
0
    def _get_valid_args(self, req, resp, conn, **kwargs):
        search_by = req.get_param('search_by')
        q = req.get_param('q')
        if search_by not in ('name', 'imo', 'mmsi', 'cs') or not q:
            raise ValidationError('INVALID_REQUEST')

        return {"search_by": search_by, "q": q}
Ejemplo n.º 18
0
 def _get_coupon_reward_currency(self, req):
     store_credit_amount = req.get_param('store_credit_amount')
     assert store_credit_amount, 'store_credit_amount'
     try:
         store_credit_amount = float(store_credit_amount)
     except ValueError, e:
         raise ValidationError('COUPON_ERR_INVALID_PARAM_store_credit_amount')
Ejemplo n.º 19
0
    def _get_valid_args(self, req, resp, conn, **kwargs):
        imo = req.get_param('imo')
        mmsi = req.get_param('mmsi')
        if not imo and not mmsi:
            raise ValidationError('INVALID_REQUEST')

        return {"mmsi": mmsi, "imo": imo}
Ejemplo n.º 20
0
    def _get_valid_args(self, req, resp, conn, **kwargs):
        search_by = req.get_param('search_by')
        q = req.get_param('q')
        if search_by not in ('container', 'bill_of_landing') or not q:
            raise ValidationError('INVALID_REQUEST')

        return {"search_by": search_by, "q": q}
Ejemplo n.º 21
0
 def _on_post(self, req, resp, conn, **kwargs):
     action = req.get_param('action')
     if action is None or action not in self.post_action_func_map:
         raise ValidationError('ERR_ACTION')
     func = getattr(self, self.post_action_func_map[action], None)
     assert hasattr(func, '__call__')
     return func(req, resp, conn)
Ejemplo n.º 22
0
    def _update_phone_num(self, conn, req, users_id):
        number_dict = {}
        for p in req._params:
            if p.startswith('country_num_'):
                number_dict[p.replace('country_num_', '')] = {}
        columns = ('country_num', 'phone_num', 'phone_num_desp')
        for num_id in number_dict:
            number_dict[num_id]['users_id'] = users_id
            for c in columns:
                p = req.get_param('%s_%s' % (c, num_id)) or ''
                if c == 'phone_num' and not re.match(phone_num_reexp, p):
                    raise ValidationError('INVALID_PHONE_NUMBER')
                number_dict[num_id][c] = p

            num_changed = self._item_changed(conn, users_id, columns,
                                             "users_phone_num", num_id,
                                             number_dict[num_id])
            if num_changed:
                num_referenced = self._is_filed_referenced(
                    conn, users_id, 'id_phone', 'users_phone_num', num_id)
            else:
                num_referenced = False
            if num_id.isdigit() and int(num_id) == 0 \
                    or num_changed and num_referenced:
                db_utils.insert(conn,
                                "users_phone_num",
                                values=number_dict[num_id])
            else:
                db_utils.update(conn,
                                "users_phone_num",
                                values=number_dict[num_id],
                                where={'id': num_id})
Ejemplo n.º 23
0
    def _on_post(self, req, resp, **kwargs):
        # combine birthday fields
        if req.get_param('birthday0'):
            req._params['birthday'] = '%s-%02d-%02d' % (
                req.get_param('birthday0'), int(req.get_param('birthday1') or 1),
                int(req.get_param('birthday2') or 1))

        # check country
        white_countries = allowed_countries()
        if white_countries:
            for p in req._params:
                if p.startswith('country_code_') \
                        or p.startswith('country_num_'):
                    if req.get_param(p) not in white_countries:
                        raise ValidationError('ERR_EU_COUNTRY')

        remote_resp = data_access(REMOTE_API_NAME.SET_USERINFO,
                                  req, resp,
                                  action="modify",
                                  **req._params)
        resp_dict = {}
        resp_dict.update(remote_resp)

        if resp_dict.get('res') == RESP_RESULT.F:
            resp_dict['err'] = _(resp_dict['err'])
        else:
            if req.get_param('first_time') == 'True':
                # send email
                email_data = {'name': req.get_param('first_name')}
                email_data.update(common_email_data)
                gevent.spawn(send_new_user_email, req.get_param('email'), email_data)

        return resp_dict
Ejemplo n.º 24
0
    def _get_valid_args(self, req, resp, conn, **kwargs):
        if req.method == 'GET':
            return {"id_user": self.users_id}

        action = req.get_param('action')
        imo = req.get_param('imo')
        mmsi = req.get_param('mmsi')
        if action not in ('add', 'delete'):
            raise ValidationError('INVALID_REQUEST')
        if not imo or not mmsi:
            raise ValidationError('INVALID_REQUEST')
        return {
            "action": action,
            "id_user": self.users_id,
            "mmsi": mmsi,
            "imo": imo,
        }
Ejemplo n.º 25
0
def get_event_configs(event_name):
    xml_eventlist = remote_xml_eventlist()
    eventlist = xmltodict.parse(xml_eventlist)
    actor_events = ActorEvents(data=eventlist['events'])
    for actor_event in actor_events.events:
        if actor_event.name == event_name:
            return actor_event
    raise ValidationError('EVENT_NOT_FOUND')
Ejemplo n.º 26
0
def _hmac_verify(user_auth):
    """ MAC verification.
    """
    secret_key = hmac_secret_key()
    text = ";".join([user_auth['exp'], user_auth['csrf'], user_auth['auth']])
    expected_digest = get_hmac(secret_key, text)
    if user_auth['digest'] != expected_digest:
        raise ValidationError('LOGIN_REQUIRED_ERR_INVALID_HMAC')
Ejemplo n.º 27
0
def get_trans_by_id(conn, id_trans):
    sql = """
    SELECT *
    FROM transactions
    WHERE id = %(id)s AND status != %(status)s ;
    """ % ({
        "id": str(id_trans),
        "status": str(TRANS_STATUS.TRANS_FAIL),
    })
    r = query(conn, sql)

    if len(r) != 1:
        raise ValidationError("ERR_TRANSACTION_ID")
    if r[0]['status'] == TRANS_STATUS.TRANS_PAID:
        raise ValidationError("ERR_TRANSACTION_ALREADY_PAID")

    return r
Ejemplo n.º 28
0
    def _on_get(self, req, resp, **kwargs):
        order_id = kwargs.get('id_order')
        if not order_id:
            raise ValidationError('ERR_ID')

        remote_resp = data_access(REMOTE_API_NAME.GET_INVOICES, req, resp,
                                  order=order_id, brand=settings.BRAND_ID)
        return {'obj': remote_resp, 'order_id': order_id}
Ejemplo n.º 29
0
 def _on_post(self, req, resp, conn, **kwargs):
     action = req.get_param('action')
     if action is None or action not in self.post_action_func_map:
         logging.error('Invalid Coupon post: %s', req.query_string)
         raise ValidationError('COUPON_ERR_INVALID_ACTION')
     func = getattr(self, self.post_action_func_map[action], None)
     assert hasattr(func, '__call__')
     return func(req, resp, conn)
Ejemplo n.º 30
0
    def _on_get(self, req, resp, conn, **kwargs):
        order_id = req.get_param('id')
        brand_id = req.get_param('brand_id', None)
        if not order_id or brand_id is None \
                or not user_accessable_order(conn, order_id, self.users_id):
            raise ValidationError('INVALID_REQUEST')

        order_detail = get_order_detail(conn, order_id, brand_id, None)
        return order_detail