kaisero / fireREST

Python library for interacting with Cisco Firepower Management Center REST API
GNU General Public License v3.0
70 stars 49 forks source link

Issue with token refresh #53

Closed chris-gibbs closed 3 years ago

chris-gibbs commented 3 years ago

Firstly, great library! Really saves me a heap of time compared to access the FMC API directly.

I'm trying to run through ruleset sequentially to move lots of access rules into categories, however I think this could be triggered on also everything that relies on resolve_by_name.

Mostly working but hit a issue that I have not been expecting. I'm really not parsing responses for invalid token because from my understanding the wrapper @utils.handle_errors on Connection _request should be handling token refresh and retry.

That reasoning seems to be okay but I also happened to be using resolve_by_name and that doesnt seem to be protected by handle_errors.

Can the wrapper in resolve_by_name also be sent through handle_errors?

In the meantime, I will update my code to not be as lazy and only utilise the resolve_by_name on the first call to get the UUID for future calls.

I happened to be running it in a debugging session in FMC and also had pigtail running.

VSCode Stack Trace

Traceback (most recent call last):
  File "C:\Program Files\Python39\lib\runpy.py", line 197, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\Program Files\Python39\lib\runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "c:\Users\ictcg\.vscode\extensions\ms-python.python-2021.9.1246542782\pythonFiles\lib\python\debugpy\__main__.py", line 45, in <module>
    cli.main()
  File "c:\Users\ictcg\.vscode\extensions\ms-python.python-2021.9.1246542782\pythonFiles\lib\python\debugpy/..\debugpy\server\cli.py", line 444, in main
    run()
  File "c:\Users\ictcg\.vscode\extensions\ms-python.python-2021.9.1246542782\pythonFiles\lib\python\debugpy/..\debugpy\server\cli.py", line 285, in run_file
    runpy.run_path(target_as_str, run_name=compat.force_str("__main__"))
  File "C:\Program Files\Python39\lib\runpy.py", line 268, in run_path
    return _run_module_code(code, init_globals, run_name,
  File "C:\Program Files\Python39\lib\runpy.py", line 97, in _run_module_code
    _run_code(code, mod_globals, init_globals,
  File "C:\Program Files\Python39\lib\runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "Z:\Documents\Code\cisco-FMC-client/update_access_policy_categories.py", line 92, in <module>
    update_access_policy_categories(fmc,POLICY_NAME)
  File "Z:\Documents\Code\cisco-FMC-client/update_access_policy_categories.py", line 22, in update_access_policy_categories
    category = fmc.policy.accesspolicy.category.get(
  File "z:\Documents\Code\cisco-FMC-client\venv\lib\site-packages\fireREST\utils.py", line 109, in wrapper
    if item['name'] == container_name:
TypeError: string indices must be integers

Pigtail stack trace

TCAT: 09-26 05:45:17 INFO: __REDACTED__     -       -       443     POST    /api/fmc_config/v1/domain/__REDACTED__    /policy/accesspolicies/__REDACTED__    /accessrules    category=__REDACTED__    201     -       1100    3308    https://__REDACTED__    FireREST/1.0.8  -
TCAT: 09-26 05:45:17 [ajp-nio-127.0.0.1-9009-exec-6] ERROR com.cisco.api.external.rest.common.utils.TokenValidationUtils - Access Token has expired. Please get renewed access token.
TCAT: 09-26 05:45:17 [ajp-nio-127.0.0.1-9009-exec-6] ERROR com.cisco.api.external.rest.common.filters.AuthenticationFilter - Access Token invalid.
TCAT: 09-26 05:45:17 [ajp-nio-127.0.0.1-9009-exec-6] ERROR com.cisco.api.external.rest.common.filters.AuthenticationFilter - Access token invalid.
TCAT: 09-26 05:45:17 APIException:Access token invalid.
TCAT: 09-26 05:45:17    at com.cisco.api.external.rest.common.filters.AuthenticationFilter.authenticateAccessToken(AuthenticationFilter.java:307)
TCAT: 09-26 05:45:17    at com.cisco.api.external.rest.common.filters.AuthenticationFilter.beforeHandle(AuthenticationFilter.java:151)
TCAT: 09-26 05:45:17    at org.restlet.routing.Filter.handle(Filter.java:195)
TCAT: 09-26 05:45:17    at org.restlet.routing.Filter.doHandle(Filter.java:150)
TCAT: 09-26 05:45:17    at org.restlet.routing.Filter.handle(Filter.java:197)
TCAT: 09-26 05:45:17    at org.restlet.routing.Filter.doHandle(Filter.java:150)
TCAT: 09-26 05:45:17    at com.cisco.api.external.rest.common.filter.AuditFilter.doHandle(AuditFilter.java:133)
TCAT: 09-26 05:45:17    at org.restlet.routing.Filter.handle(Filter.java:197)
TCAT: 09-26 05:45:17    at org.restlet.routing.Filter.doHandle(Filter.java:150)
TCAT: 09-26 05:45:17    at org.restlet.routing.Filter.handle(Filter.java:197)
TCAT: 09-26 05:45:17    at org.restlet.routing.Filter.doHandle(Filter.java:150)
TCAT: 09-26 05:45:17    at org.restlet.routing.Filter.handle(Filter.java:197)
TCAT: 09-26 05:45:17    at org.restlet.routing.Filter.doHandle(Filter.java:150)
TCAT: 09-26 05:45:17    at org.restlet.engine.application.StatusFilter.doHandle(StatusFilter.java:140)
TCAT: 09-26 05:45:17    at org.restlet.routing.Filter.handle(Filter.java:197)
TCAT: 09-26 05:45:17    at org.restlet.routing.Filter.doHandle(Filter.java:150)
TCAT: 09-26 05:45:17    at org.restlet.routing.Filter.handle(Filter.java:197)
TCAT: 09-26 05:45:17    at org.restlet.engine.CompositeHelper.handle(CompositeHelper.java:202)
TCAT: 09-26 05:45:17    at org.restlet.engine.application.ApplicationHelper.handle(ApplicationHelper.java:75)
TCAT: 09-26 05:45:17    at org.restlet.Application.handle(Application.java:385)
TCAT: 09-26 05:45:17    at org.restlet.routing.Filter.doHandle(Filter.java:150)
TCAT: 09-26 05:45:17    at org.restlet.routing.Filter.handle(Filter.java:197)
TCAT: 09-26 05:45:17    at org.restlet.routing.Router.doHandle(Router.java:422)
TCAT: 09-26 05:45:17    at org.restlet.routing.Router.handle(Router.java:639)
TCAT: 09-26 05:45:17    at org.restlet.routing.Filter.doHandle(Filter.java:150)
TCAT: 09-26 05:45:17    at org.restlet.routing.Filter.handle(Filter.java:197)
TCAT: 09-26 05:45:17    at org.restlet.routing.Router.doHandle(Router.java:422)
TCAT: 09-26 05:45:17    at org.restlet.routing.Router.handle(Router.java:639)
TCAT: 09-26 05:45:17    at org.restlet.routing.Filter.doHandle(Filter.java:150)
TCAT: 09-26 05:45:17    at org.restlet.routing.Filter.handle(Filter.java:197)
TCAT: 09-26 05:45:17    at org.restlet.routing.Filter.doHandle(Filter.java:150)
TCAT: 09-26 05:45:17    at org.restlet.routing.Filter.handle(Filter.java:197)
TCAT: 09-26 05:45:17    at org.restlet.routing.Filter.doHandle(Filter.java:150)
TCAT: 09-26 05:45:17    at org.restlet.engine.application.StatusFilter.doHandle(StatusFilter.java:140)
TCAT: 09-26 05:45:17    at org.restlet.routing.Filter.handle(Filter.java:197)
TCAT: 09-26 05:45:17    at org.restlet.routing.Filter.doHandle(Filter.java:150)
TCAT: 09-26 05:45:17    at org.restlet.routing.Filter.handle(Filter.java:197)
TCAT: 09-26 05:45:17    at org.restlet.engine.CompositeHelper.handle(CompositeHelper.java:202)
TCAT: 09-26 05:45:17    at org.restlet.Component.handle(Component.java:408)
TCAT: 09-26 05:45:17    at com.cisco.api.external.rest.common.APIComponent.handle(APIComponent.java:294)
TCAT: 09-26 05:45:17    at org.restlet.Server.handle(Server.java:507)
TCAT: 09-26 05:45:17    at org.restlet.engine.connector.ServerHelper.handle(ServerHelper.java:63)
TCAT: 09-26 05:45:17    at org.restlet.engine.adapter.HttpServerHelper.handle(HttpServerHelper.java:143)
TCAT: 09-26 05:45:17    at org.restlet.ext.servlet.ServerServlet.service(ServerServlet.java:1117)
TCAT: 09-26 05:45:17    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
TCAT: 09-26 05:45:17    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
TCAT: 09-26 05:45:17    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
TCAT: 09-26 05:45:17    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
TCAT: 09-26 05:45:17    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
TCAT: 09-26 05:45:17    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
TCAT: 09-26 05:45:17    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
TCAT: 09-26 05:45:17    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
TCAT: 09-26 05:45:17    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
TCAT: 09-26 05:45:17    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
TCAT: 09-26 05:45:17    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
TCAT: 09-26 05:45:17    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
TCAT: 09-26 05:45:17    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
TCAT: 09-26 05:45:17    at org.apache.coyote.ajp.AjpProcessor.service(AjpProcessor.java:394)
TCAT: 09-26 05:45:17    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
TCAT: 09-26 05:45:17    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:853)
TCAT: 09-26 05:45:17    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1587)
TCAT: 09-26 05:45:17    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
TCAT: 09-26 05:45:17    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
TCAT: 09-26 05:45:17    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
TCAT: 09-26 05:45:17    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
TCAT: 09-26 05:45:17    at java.base/java.lang.Thread.run(Unknown Source)
kaisero commented 3 years ago

Glad that the project is of help to you. :)

I skimmed through the codebase and from what I found it should theoretically be protected by the handle_errors decorator, since resolve_by_name uses _request function from Connection.py.

I'll look into this

kaisero commented 3 years ago

I found the problem. When doing a refresh, the initial request in not being retried. I have added the missing functionality and will publish the changes in v1.0.9