コード例 #1
0
ファイル: catorestapi.py プロジェクト: AsherBond/cato
    def GET(self):
        args = web.input()
        output_format = args.get("output_format", "")
        version = catoconfig.VERSION

        if output_format == "json":
            response = api.response(response='{"Version" : "%s"}' % version)
        elif output_format == "text":
            response = api.response(response=version)
        else:
            response = api.response(response="<Version>%s</Version>" % version)

        return response.Write(output_format)
コード例 #2
0
ファイル: catorestapi.py プロジェクト: AsherBond/cato
 def handle(self):
     try:
         return web.application.handle(self)
     except (web.HTTPError, KeyboardInterrupt, SystemExit):
         raise
     except InfoException as ex:
         # we're using a custom HTTP status code to indicate 'information' back to the user.
         args = web.input()
         web.ctx.status = "280 Informational Response"
         output_format = args.get("output_format", "")
         logger.info(ex.__str__())
         response = api.response(err_code=api.response.Codes.Exception, err_detail=ex.__str__())
         return response.Write(output_format)
     except Exception as ex:
         args = web.input()
         web.ctx.status = "400 Bad Request"
         output_format = args.get("output_format", "")
         logger.exception(ex.__str__())
         response = api.response(err_code=api.response.Codes.Exception, err_detail=ex.__str__())
         return response.Write(output_format)
コード例 #3
0
ファイル: catorestapi.py プロジェクト: AsherBond/cato
    def go(self, method):
        args = web.input()
        web.header('X-CSK-Method', method)
        # web.header('Content-Type', 'text/xml')

        # here's the rub - if this was a POST, there might be lots of additional data in web.data().
        # the keys above in web.input() are valid too, but the post args take precedence.
        # so, merge them.
        if web.data():
            # TODO: don't continue to assume JSON, base the unpacking of the args on the Content-Type header
            ct = web.ctx.env.get('CONTENT_TYPE')
            logger.debug("Content-Type: %s" % (ct))
            
            if ct != "application/json":
                logger.warning("POST data should set the header - Content-Type: application/json.")

            # TODO: this should be based on content-type, but for now we continue to assume it's json
            # regardless of the content-type header
            postargs = catocommon.argloader(web.data())
            if postargs:
                logger.info("Post Data: %s" % postargs)
                for k, v in postargs.iteritems():
                    args[k] = v

        logger.info("Request: %s" % method)
        logger.info("Args: %s" % args)

        output_format = args.get("output_format", "")

        is_authenticated, user_id = api.authenticate(method, args)
        if not is_authenticated:
            # authentication failures won't return details to the client
            # but will write some info in the api log
            # the second return arg holds a failure code
            if getattr(args, 'key', ''):
                logger.error("Authentication Failure [%s] - [%s]" % (getattr(args, 'key', ''), user_id))
            else:
                logger.error("Authentication Failure [%s]" % user_id)

            response = api.response(err_code="AuthenticationFailure", err_msg="Authentication Failure")
            return response.Write(output_format)

        # the args collection is passed to the target function, BUT
        # we wanna stick a few things in there we might need.
        args["output_format"] = output_format

        # THESE FLAGS GRANT SPECIAL ABILITIES!!!!
        # ensure they are cleared before authenticating each request
        api._ADMIN = False
        api._DEVELOPER = False

        # the API commands do some logging that use these detail properties
        u = catouser.User()
        u.FromID(user_id)
        if u:
            logger.debug("""Authenticated:
                User: %s
                Full Name: %s
                Role: %s
                Tags: %s""" % (u.LoginID, u.FullName, u.Role, u.Tags))

            api._USER_ID = u.ID

            api._USER_ROLE = u.Role
            api._USER_FULLNAME = u.FullName

            # flags are set so certain methods can have restricted access.
            if u.Role == "Administrator":
                logger.info("[%s] is operating with ADMIN privileges." % (u.FullName))
                api._ADMIN = True
                api._DEVELOPER = True
            if u.Role == "Developer":
                logger.info("[%s] is operating with DEVELOPER privileges." % (u.FullName))
                api._DEVELOPER = True

            # Tags are placed in a global for any access checks
            api._USER_TAGS = u.Tags
        else:
            logger.error("Authenticated, but unable to build a User object.")
            response = api.response(err_code="Exception", err_msg="Authenticated, but unable to build a User object.")
            return response.Write(output_format)

        endpoints = api.endpoints

        # If Maestro is enabled, load those endpoints
        try:
            sys.path.insert(0, os.path.join(CSK_HOME, "maestro", "lib"))
            from maestroapi import api as mapi
            endpoints = dict(endpoints.items() + mapi.endpoints.items())
        except:
            pass

        # If Legato is enabled, load those endpoints
        try:
            sys.path.insert(0, os.path.join(CSK_HOME, "legato", "lib"))
            from cskcdapi import api as cdapi
            endpoints = dict(endpoints.items() + cdapi.endpoints.items())
        except:
            pass
        
        if endpoints.get(method):
            response = catocommon.FindAndCall(endpoints[method], args)
        else:
            response = api.response(err_code="Exception", err_msg="'%s' is not a valid API endpoint." % (method))
            return response.Write(output_format)

        # FindAndCall can have all sorts of return values.
        # in this case, we expect it would be an api.response object.
        # but never assume
        if hasattr(response, "Method"):
            response.Method = method

            # is this a JSONP request?
            if "callback" in args:
                """
                    IF there is an arg called "callback", that means we want the results formatted as a javascript function call.

                    (of course, if we wanna eventually support both XML and JSON result types that's fine...
                    it just means the payload *inside* the jsonp callback will be xml or json as requested.)
                """
                payload = response.Write(output_format)
                web.header('Content-Type', 'application/javascript')
                return "%s(%s)" % (args["callback"], payload)
            else:
                return response.Write(output_format)
        else:
            # the result from FindAndCall wasn't a response object.
            # so make one
            response = api.response(err_code=api.response.Codes.Exception, err_detail=response)
            return response.Write(output_format)