Exemple #1
0
    def view_items(self, request):
        items = Struct()
        items.settings = self.settings,
        items.method = request.method
        items.formatter = None
        items.key = ''
        items.is_rest = self.is_rest
        items.use_session = self.use_session

        parameters = dict(request.GET)
        post_params = dict(request.POST)
        for k, v in post_params.items():
            if k in parameters:
                parameters[k].append(v)
            else:
                parameters[k] = v
        items.parameters = parameters

        path = request.path.strip().split('/')
        if path[0] == '':
            del path[0]
        length = len(path)
        if length > 0 and path[length - 1] == '':
            del path[length - 1]
        length = len(path)
        if length < self.base_path_length:
            items.error = Result.error(BasicView.CODE_NOT_FOUND, 'Not Found',
                                       '01')
            return items
        all_path = list(path)
        base_path = list(path[0:self.base_path_length])
        del path[0:self.base_path_length]
        items.all_path = all_path
        items.base_path = base_path
        items.path = path

        if self.is_rest:
            lenpath = len(path)
            if lenpath == 0:
                items.error = Result.error(BasicView.CODE_NOT_FOUND,
                                           'Not Found', '02')
                return items
            lstr = path[lenpath - 1]
            lidx = lstr.rfind('.')
            fmt = ''
            if lidx != -1:
                fmt = lstr[lidx + 1:].strip()
                if fmt != '' and fmt in self.formatter:
                    lstr = lstr[:lidx]
                    path[lenpath - 1] = lstr
                else:
                    fmt = ''
            if fmt == '' and BasicView.HEADER_RESPONSE_FORMAT in request.META:
                fmt = request.META[BasicView.HEADER_RESPONSE_FORMAT].strip()
            items.formatter = self.formatter[fmt]
            if BasicView.HEADER_ACCESS_KEY in request.META:
                items.key = request.META[BasicView.HEADER_ACCESS_KEY]
        else:
            items.template = self.template
        return items
Exemple #2
0
def profile(request):
    view_items = request.view_items
    formatter = view_items.formatter
    if view_items.is_rest and not view_items.use_session:
        key = view_items.key
        access = BasicView.get_access(formatter, key)
        if isinstance(access, HttpResponse):
            return access
        if access.user is not None and hasattr(access.user, 'password'):
            del access.user.password
        if hasattr(access, 'secret'):
            del access.secret
        data = Result.success(access)
        return BasicView.quick_return(formatter=formatter, data=data, nullable=False)
    else:
        data = Result.error(BasicView.CODE_NOT_ALLOWED, 'NOT ALLOWED')
        return BasicView.quick_return(formatter=formatter, data=data, nullable=False)
Exemple #3
0
def logout(request):
    view_items = request.view_items
    # rest
    if view_items.is_rest:
        formatter = view_items.formatter
        if view_items.use_session:
            auth_logout(request)
            data = Result.success()
            return BasicView.quick_return(formatter=formatter, data=data, nullable=False)
        else:
            key = view_items.key
            Access.revoke(key)
            data = Result.success()
            return BasicView.quick_return(formatter=formatter, data=data, nullable=False)
    # web
    else:
        settings = view_items.settings[0]
        auth_logout(request)
        return HttpResponseRedirect(settings['path']['home'])
Exemple #4
0
 def get_access(formatter, key, request=None):
     if key is None or '' == key:
         data = Result.error(BasicView.CODE_ACCESS_KEY_REQUIRED,
                             'Access Key is required')
         return BasicView.quick_return(formatter=formatter,
                                       data=data,
                                       nullable=False)
     access = Access.get(key)
     if access is None:
         data = Result.error(BasicView.CODE_ACCESS_KEY_EXPIRED,
                             'Access Key is expired')
         return BasicView.quick_return(formatter=formatter,
                                       data=data,
                                       nullable=False)
     if request is not None and access.secret is not None:
         secret = BasicView.create_secret(request)
         if secret != access.secret:
             data = Result.error(BasicView.CODE_ACCESS_KEY_INVALID,
                                 'Access Key is not valid')
             return BasicView.quick_return(formatter=formatter,
                                           data=data,
                                           nullable=False)
     return access
Exemple #5
0
def login(request):
    view_items = request.view_items
    # rest
    if view_items.is_rest:
        formatter = view_items.formatter
        if view_items.use_session and request.user.is_authenticated:
            data = Result.success("LOGGED_IN")
            return BasicView.quick_return(formatter=formatter, data=data, nullable=False)
        parameters = view_items.parameters
        username = ''
        if 'username' in parameters:
            username = parameters['username'][0]
        password = ''
        if 'password' in parameters:
            password = parameters['password'][0]
        if username == '' or password == '':
            data = Result.error(BasicView.CODE_USER_PASS_REQUIRED, 'username and password are required')
            return BasicView.quick_return(formatter=formatter, data=data, nullable=False)
        authUser = BasicDao.get({'model': AuthUser, 'filter': {'username': username}})
        if authUser is None:
            data = Result.error(BasicView.CODE_USER_NOT_FOUND, 'User is not found')
            return BasicView.quick_return(formatter=formatter, data=data, nullable=False)
        if not authUser.is_active:
            data = Result.error(BasicView.CODE_USER_INACTIVE, 'User is not active')
            return BasicView.quick_return(formatter=formatter, data=data, nullable=False)
        pwd_valid = check_password(password, authUser.password)
        if not pwd_valid:
            data = Result.error(BasicView.CODE_INVALID_PASSWORD, 'Invalid password')
            return BasicView.quick_return(formatter=formatter, data=data, nullable=False)
        authUser.last_login = datetime.now()
        authUser.save()
        if view_items.use_session:
            auth_login(request, authUser)
            data = Result.success()
            return BasicView.quick_return(formatter=formatter, data=data, nullable=False)
        else:
            key = str(uuid.uuid1())
            user = AccessUser(user=authUser)
            secret = BasicView.create_secret(request)
            access = Access(user=user, key=key, secret=secret)
            saved = Access.create(key, access)
            if not saved:
                data = Result.error(BasicView.CODE_ACCESS_KEY_REG_FAIL, 'Failed to register Access Key')
                return BasicView.quick_return(formatter=formatter, data=data, nullable=False)
            del access.user.password
            del access.secret
            data = Result.success(access)
            return BasicView.quick_return(formatter=formatter, data=data, nullable=False)
    # web
    else:
        settings = view_items.settings[0]
        redirect_to = ''
        if REDIRECT_FIELD_NAME in view_items.parameters:
            redirect_to = view_items.parameters[REDIRECT_FIELD_NAME][0]
        if request.user.is_authenticated:
            if not '' == redirect_to:
                redirect_to = base64.urlsafe_b64decode(redirect_to).decode()
            if redirect_to == settings['path']['login'] or redirect_to == '':
                return HttpResponseRedirect(settings['path']['home'])
            return HttpResponseRedirect(redirect_to)
        if 'POST' == request.method:
            form = AuthenticationForm(request, data=request.POST)
            if form.is_valid():
                auth_login(request, form.get_user())
                return HttpResponseRedirect(settings['path']['login'] + '?' + REDIRECT_FIELD_NAME + '=' + redirect_to)
        else:
            form = AuthenticationForm(request)

        current_site = get_current_site(request)
        context = {
            'form': form,
            REDIRECT_FIELD_NAME: redirect_to,
            'site': current_site,
            'settings': settings,
            'request': request
        }
        template = view_items.template.login
        return BasicView.quick_return(template=template, context=context, is_rest=False)
Exemple #6
0
 def wrapper(request, *args, **kwargs):
     view_items = request.view_items
     formatter = view_items.formatter
     use_session = view_items.use_session
     is_rest = view_items.is_rest
     if 'method' in input and isinstance(input['method'], list):
         method = request.method
         if not method.upper() in [
                 x.upper() for x in input['method']
         ]:
             if is_rest:
                 data = Result.error(
                     BasicView.CODE_UNSUPPORTED_METHOD,
                     'Method Not Allowed')
                 return BasicView.quick_return(formatter=formatter,
                                               data=data,
                                               nullable=False,
                                               is_rest=is_rest)
             else:
                 context = {
                     'settings': view_items.settings[0],
                     'request': request,
                     'error': {
                         'status': 405,
                         'text': 'Method Not Allowed'
                     }
                 }
                 template = view_items.template.status
                 return BasicView.quick_return(template=template,
                                               context=context,
                                               is_rest=is_rest)
     if 'private' in input and isinstance(input['private'], bool):
         private = input['private']
         if private:
             if view_items.is_rest:
                 if use_session:
                     if not request.user.is_authenticated:
                         data = Result.error(
                             BasicView.CODE_USER_NOT_LOGGED_IN,
                             'User is not logged in')
                         return BasicView.quick_return(
                             formatter=formatter,
                             data=data,
                             nullable=False)
                 else:
                     key = view_items.key
                     access = BasicView.get_access(
                         formatter, key, request)
                     if isinstance(access, HttpResponse):
                         return access
                     view_items.access = access
             else:
                 if not request.user.is_authenticated:
                     qstring = request.GET.urlencode()
                     redirect = request.path
                     if qstring != '':
                         redirect = redirect + '?' + qstring
                     redirect = base64.urlsafe_b64encode(
                         redirect.encode()).decode()
                     login = view_items.settings[0]['path']['login']
                     return HttpResponseRedirect(
                         login + '?' + REDIRECT_FIELD_NAME + '=' +
                         redirect)
     return function(request, *args, **kwargs)
Exemple #7
0
    def model(self, request):
        self.is_rest = True
        view_items = self.view_items(request)
        if hasattr(view_items, 'error'):
            error = view_items.error
            info = error.info
            error = error.error
            data = error['code'] + ' - ' + error['text'] + ' (' + info + ')'
            return BasicView.quick_return(status=400,
                                          data=data,
                                          nullable=False,
                                          is_rest=self.is_rest)
        formatter = view_items.formatter
        path = view_items.path
        parameters = view_items.parameters

        if len(path) < 2:
            data = Result.error(BasicView.CODE_NOT_FOUND, 'Invalid path')
            return BasicView.quick_return(formatter=formatter,
                                          data=data,
                                          nullable=False,
                                          is_rest=self.is_rest)

        # Model
        model = self.get_model(path[0])
        if model is None:
            data = Result.error(BasicView.CODE_UNKNOWN_MODEL,
                                'Unknown model: ' + path[0])
            return BasicView.quick_return(formatter=formatter,
                                          data=data,
                                          nullable=False,
                                          is_rest=self.is_rest)
        del path[0]

        # Action
        action = path[0]
        del path[0]
        if not hasattr(BasicApi, action):
            data = Result.error(BasicView.CODE_INVALID_ACTION,
                                'Invalid action: ' + path[0])
            return BasicView.quick_return(formatter=formatter,
                                          data=data,
                                          nullable=False,
                                          is_rest=self.is_rest)

        # User
        user = None
        if self.use_session:
            user = get_user(request)
            if not request.user.is_authenticated and API_USER_ENABLE:
                data = Result.error(BasicView.CODE_USER_NOT_LOGGED_IN,
                                    'User is not logged in')
                return BasicView.quick_return(formatter=formatter,
                                              data=data,
                                              nullable=False,
                                              is_rest=self.is_rest)
        else:
            key = view_items.key
            if key is None or '' == key:
                if API_USER_ENABLE:
                    data = Result.error(BasicView.CODE_ACCESS_KEY_REQUIRED,
                                        'Access Key is required')
                    return BasicView.quick_return(formatter=formatter,
                                                  data=data,
                                                  nullable=False,
                                                  is_rest=self.is_rest)
            else:
                access = Access.get(key)
                if access is None:
                    if API_USER_ENABLE:
                        data = Result.error(BasicView.CODE_ACCESS_KEY_EXPIRED,
                                            'Access Key is expired')
                        return BasicView.quick_return(formatter=formatter,
                                                      data=data,
                                                      nullable=False,
                                                      is_rest=self.is_rest)
                else:
                    if access.secret is not None and API_USER_ENABLE:
                        secret = BasicView.create_secret(request)
                        if secret != access.secret:
                            data = Result.error(
                                BasicView.CODE_ACCESS_KEY_INVALID,
                                'Access Key is not valid')
                            return BasicView.quick_return(formatter=formatter,
                                                          data=data,
                                                          nullable=False)
                    user = access.user
                    if ACCESS_TOUCH_ENABLE:
                        Access.touch(key)

        # Execute
        command = getattr(BasicApi, action)
        status = 200
        try:
            data = command({
                'model': model,
                'path': path,
                'parameters': parameters,
                'user': user
            })
            result = Result.success(data)
        except BasicApi.NotAllowed:
            result = Result.error(BasicView.CODE_NOT_ALLOWED, 'Not allowed')
        except BasicApi.BadRequest as br:
            result = Result.error(BasicView.CODE_BAD_REQUEST, str(br))
        except BasicApi.AppError as ar:
            logger.error(ar)
            result = Result.error(BasicView.CODE_APP_SYS_ERROR,
                                  'AppError: ' + str(ar))
            status = 500
        except Exception as ex:
            logger.error(ex)
            result = Result.error(BasicView.CODE_APP_SYS_ERROR,
                                  'SysError: ' + str(ex))
            status = 500
        mapi = BasicApi.get_model_api(model)
        kwargs = {}
        if hasattr(mapi, 'alias'):
            kwargs['alias'] = getattr(mapi, 'alias')
        if hasattr(mapi, 'ignore'):
            ignore = getattr(mapi, 'ignore')
            if ignore is not None and 'output' in ignore:
                kwargs['hidden'] = ignore['output']
        if hasattr(mapi, 'nullable'):
            kwargs['nullable'] = getattr(mapi, 'nullable')
        return HttpResponse(formatter.content_data(result, **kwargs),
                            formatter.content_type(), status)
Exemple #8
0
    def route(self, request):
        view_items = self.view_items(request)
        ctx = Struct({
            'is_rest': self.is_rest,
            'formatter': view_items.formatter,
            'data': None,
            'status': 200,
            'nullable': False,
            'template': None,
            'context': {
                'settings': self.settings,
                'request': request
            },
        })
        if hasattr(view_items, 'error'):
            error = view_items.error
            info = error.info
            error = error.error
            ctx.context.text = info
            ctx.data = error['code'] + ' - ' + error['text'] + ' (' + info + ')'
            ctx.status = 400
            ctx.template = self.template.notfound
        else:
            ctx.template = self.template.home
            path = list(view_items.path)
            del view_items.path
            lenpath = len(path)
            if lenpath > 0:
                package_object = None
                view_items.package_path = []
                for x in range(0, 3):
                    i = 3 - x
                    if lenpath < i:
                        continue
                    p = '/'.join(s for s in path[0:i])
                    if p in self.route_packages:
                        package_object = self.route_packages[p]
                        view_items.package_path = list(path[0:i])
                        del path[0:i]
                        break
                lenpath = len(path)
                if package_object is None:
                    ctx.context.text = '03'
                    ctx.data = Result.error(BasicView.CODE_NOT_FOUND,
                                            'Not Found (03)')
                    ctx.template = self.template.notfound
                elif lenpath == 0:
                    ctx.context.text = '04'
                    ctx.data = Result.error(BasicView.CODE_NOT_FOUND,
                                            'Not Found (04)')
                    ctx.template = self.template.notfound
                else:
                    if not hasattr(package_object, path[0]):
                        ctx.context.text = '05'
                        ctx.data = Result.error(BasicView.CODE_NOT_FOUND,
                                                'Not Found (05)')
                        ctx.template = self.template.notfound
                    else:
                        module_object = getattr(package_object, path[0])
                        view_items.module_path = [path[0]]
                        del path[0]
                        lenpath = len(path)
                        module_idx = -1
                        for i in range(0, lenpath):
                            if not hasattr(module_object, path[i]):
                                break
                            module_object = getattr(module_object, path[i])
                            view_items.module_path.append(path[i])
                            module_idx = i
                        if module_idx != -1:
                            del path[0:module_idx + 1]
                        view_items.function_path = list(path)
                        if not callable(module_object):
                            ctx.context.text = '06'
                            ctx.data = Result.error(BasicView.CODE_NOT_FOUND,
                                                    'Not Found (06)')
                            ctx.template = self.template.notfound
                        else:
                            request.view_items = view_items
                            try:
                                is_function = str(type(
                                    module_object)) == '<class \'function\'>'
                                if is_function:
                                    result = module_object(request)
                                else:
                                    function_object = module_object(
                                        settings=self.settings)
                                    result = function_object.call(request)

                                # Default nullable = True, agar false maka di view_items harus diset
                                ctx.nullable = True
                                if hasattr(request.view_items,
                                           'nullable') and isinstance(
                                               request.view_items.nullable,
                                               bool):
                                    ctx.nullable = request.view_items.nullable

                                if isinstance(result, HttpResponse):
                                    return result
                                elif isinstance(result, ViewResponse):
                                    ctx.context.context = result.context
                                    ctx.data = result.context
                                    ctx.template = result.template
                                else:
                                    ctx.context.context = result
                                    ctx.data = result
                                    ctx.template = request.view_items.template
                            except Exception as ex:
                                logger.error(ex)
                                ctx.context.error = {
                                    'code': '99',
                                    'text': str(ex)
                                }
                                ctx.data = Result.error(
                                    BasicView.CODE_APP_SYS_ERROR, str(ex))
                                ctx.nullable = False
                                ctx.template = self.template.error

        try:
            if not self.is_rest:
                for key, func in self.context_interceptors.items():
                    if hasattr(ctx.context, key):
                        continue
                    value = func(request)
                    setattr(ctx.context, key, value)
            kwargs = ctx.__dict__
            return BasicView.quick_return(**kwargs)
        except Exception as ex:
            logger.error(ex)
            ctx.context.error = {'code': '99', 'text': str(ex)}
            ctx.template = self.template.error
            return BasicView.quick_return(**kwargs)
Exemple #9
0
 def coba3(request):
     request.view_items.template = 'test.html'
     return Result.error('22', 'Tes salah method')
Exemple #10
0
 def coba2(request):
     request.view_items.template = 'test.html'
     return Result.error('21', 'Test Error')