def to_string(val): '''Decode string to string to_string :: String -> Result e String >>> from pydecoder.primitives import to_string Retrun result with decoded string >>> to_string('Foo Bar Baz') Result(status='Ok', value='Foo Bar Baz') if value isn't string returns error. >>> to_string(1234) Result(status='Error', value="'1234' isn't string.") ''' if val is None: return error(u'Can\'t be null') if not isinstance(val, string_types): return error(u'\'{0!r}\' isn\'t string.'.format(val)) return ok(val) if isinstance(val, text_type) else ok( text_type(val, 'utf-8'))
def to_bool(val): '''Decode string/value to boolean''' if isinstance(val, string_types): # pylint: disable=no-else-return lowered_string = val.lower() if lowered_string == 'true': # pylint: disable=no-else-return return ok(True) elif lowered_string == 'false': return ok(False) else: return error(u('String %s is invalid boolean value.' % val)) elif isinstance(val, bool): return ok(val) else: return error(u('Value can\'t be decoded'))
def array(factory, vals): '''Decode string/value as list array :: (a -> Result e b) -> List a -> Result e (List b) >>> from pydecoder.primitives import to_int >>> array(to_int, [1, 2, 3]) Result(status='Ok', value=[1, 2, 3]) >>> array(to_int, None) Result(status='Error', value="'None' isn't list or tuple.") ''' if not isinstance(vals, (list, tuple)): return error(u('\'{}\' isn\'t list or tuple.').format(vals)) result = [] for val in vals: rv = factory(val) if is_error(rv): return rv result.append(value(rv)) return ok(result)
def _to_val(iterator_or_value): if isinstance(iterator_or_value, Iterator): try: return func(first(iterator_or_value)) except StopIteration: return error(u('Value is empty.')) return func(iterator_or_value)
def getter(json, keys): # pylint: disable=redefined-outer-name '''Get data from json''' try: return ok(get_in(_to_key_list(keys), json, no_default=True)) except KeyError: return error( u'Value is empty or path/key {0!r} not found...'.format(keys))
def verify(token, key): ''' Check the supplied token and it's expiration. :param token: A token to verify :param key: decryption key :returns: result with data **Examples** returns data if token is valid >>> from flask_chip.tokens import generate, verify >>> key = "y):'QGE8M-b+MEKl@k4e<;*9.BqL=@~B" >>> data = {'foo': 1234} >>> token = generate(data, key=key) >>> verify(token, key=key) Result(status='Ok', value={'foo': 1234}) returns expiration error when token expire >>> from time import sleep >>> key = "y):'QGE8M-b+MEKl@k4e<;*9.BqL=@~B" >>> data = {'foo': 1234} >>> token = generate(data, key=key, exp=0) >>> sleep(1) # wait for token expiration >>> verify(token, key=key) Result(status='Error', value='Token expired.') returns time travele error >>> from time import time >>> iat = time() + 3600 >>> key = "y):'QGE8M-b+MEKl@k4e<;*9.BqL=@~B" >>> data = {'foo': 1234} >>> token = generate(data, key=key, iat=iat) >>> verify(token, key=key) Result(status='Error', value='Token traveled through time.') returns error if token is invalid >>> key = "y):'QGE8M-b+MEKl@k4e<;*9.BqL=@~B" >>> data = {"foo": 1234} >>> token = generate(data, key=key) >>> key2 = "12345678901234567890123456789012" >>> verify(token, key=key2) Result(status='Error', value='invalid JWT') ''' serializer = Serializer(key) try: return pipe( token, serializer.loads, ok, and_then(_expired), # pylint: disable=no-value-for-parameter and_then(_time_traveled), # pylint: disable=no-value-for-parameter rmap(lambda d: d['data']) # pylint: disable=no-value-for-parameter ) except (SignatureExpired, BadSignature, TypeError): return error('invalid JWT')
def _time_traveled(data): return ok(data) if data['iat'] <= _now() else error( 'Token traveled through time.')
def _expired(data): return ok(data) if data['exp'] >= _now() else error('Token expired.')
def to_int(val): '''Decode string/value to int''' try: return ok(int(val)) except (TypeError, ValueError) as err: return error(text_type(err))
def null(val): '''Decode string/value to None''' if val is not None and val.lower() not in ('none', 'null'): return error(u('Value can\'t be decoded')) return ok(None)
def dec(_val): return error('ERROR')