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
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
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": ""}
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 {}
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})
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
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"))
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
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()
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
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
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')
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)
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
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
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)
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}
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')
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}
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}
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)
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})
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
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, }
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')
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')
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
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}
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)
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