DataFed icon indicating copy to clipboard operation
DataFed copied to clipboard

[DAPS-1522] Authz Router Logging Improvements

Open megatnt1122 opened this issue 1 month ago • 1 comments

Ticket

#1522

Description

Logging improvements to authz_router

Tasks

  • [ ] - A description of the PR has been provided, and a diagram included if it is a new feature.
  • [ ] - Formatter has been run
  • [ ] - CHANGELOG comment has been added
  • [ ] - Labels have been assigned to the pr
  • [ ] - A reviwer has been added
  • [ ] - A user has been assigned to work on the pr
  • [ ] - If new feature a unit test has been added

Summary by Sourcery

Improve observability and test coverage for the authz_router service.

Enhancements:

  • Replace ad-hoc console logging in authz_router endpoints with structured logger calls that include client, correlation ID, route, status, and context details.

Tests:

  • Add unit tests for the /perm/check endpoint to verify permission checks for an admin user on an owned record.
  • Add unit tests for the /perm/get endpoint to validate returned permission bits and error handling for invalid IDs.

megatnt1122 avatar Nov 25 '25 13:11 megatnt1122

Reviewer's Guide

Refactors authz_router logging to use a centralized logger with structured request lifecycle events for key endpoints and adds basic unit coverage for perm/check and perm/get routes.

Sequence diagram for GET authz/gridftp with structured logging

sequenceDiagram
    actor Client
    participant AuthzRouter
    participant GLib
    participant Repo
    participant Logger

    Client->>AuthzRouter: GET /authz/gridftp?client&repo&file&act
    AuthzRouter->>GLib: getUserFromClientID client
    GLib-->>AuthzRouter: client
    AuthzRouter->>Logger: logRequestStarted client_id, correlationId, GET, authz/gridftp, Started, description

    alt client lookup fallback
        AuthzRouter->>GLib: getUserFromClientID_noexcept client
        GLib-->>AuthzRouter: client_or_null
    end

    alt client not found
        AuthzRouter->>Logger: logRequestFailure client_null, correlationId, GET, authz/gridftp, Failure, description, error(ERR_PERM_DENIED)
        AuthzRouter->>GLib: handleException error, res
        GLib-->>Client: error response
    else client found
        AuthzRouter->>Repo: new Repo repo
        AuthzRouter->>Repo: get_path_type file
        Repo-->>AuthzRouter: PathType

        alt path_type UNKNOWN
            AuthzRouter->>Logger: logRequestFailure client_id, correlationId, GET, authz/gridftp, Failure, description, error(ERR_PERM_DENIED)
            AuthzRouter->>GLib: handleException error, res
            GLib-->>Client: error response
        else path_type valid
            AuthzRouter->>AuthzRouter: check act against permissions
            alt authorized
                AuthzRouter-->>Client: success response
                AuthzRouter->>Logger: logRequestSuccess client_id, correlationId, GET, authz/gridftp, Success, description, extra(client_id,is_admin)
            else not authorized
                AuthzRouter->>Logger: logRequestFailure client_id, correlationId, GET, authz/gridftp, Failure, description, error(ERR_PERM_DENIED)
                AuthzRouter->>GLib: handleException error, res
                GLib-->>Client: error response
            end
        end
    end

    opt unexpected error
        AuthzRouter->>Logger: logRequestFailure client_maybe_null, correlationId, GET, authz/gridftp, Failure, description, error(e)
        AuthzRouter->>GLib: handleException e, res
        GLib-->>Client: error response
    end

Sequence diagram for GET authz/perm/check and authz/perm/get logging lifecycle

sequenceDiagram
    actor Client
    participant AuthzRouter
    participant GLib
    participant Logger

    Client->>AuthzRouter: GET /authz/perm/check or /authz/perm/get
    AuthzRouter->>GLib: getUserFromClientID client
    GLib-->>AuthzRouter: client

    alt perm_check_route
        AuthzRouter->>Logger: logRequestStarted client_id, correlationId, GET, authz/perm/check, Started, description
    else perm_get_route
        AuthzRouter->>Logger: logRequestStarted client_id, correlationId, GET, authz/perm/get, Started, description
    end

    AuthzRouter->>GLib: resolveID id, client
    GLib-->>AuthzRouter: type_and_id
    AuthzRouter->>AuthzRouter: compute permissions result

    alt handler succeeds
        AuthzRouter-->>Client: {granted: result}
        alt perm_check_route
            AuthzRouter->>Logger: logRequestSuccess client_id, correlationId, GET, authz/perm/check, Success, description, extra(result)
        else perm_get_route
            AuthzRouter->>Logger: logRequestSuccess client_id, correlationId, GET, authz/perm/get, Success, description, extra(result)
        end
    else handler throws error
        alt perm_check_route
            AuthzRouter->>Logger: logRequestFailure client_id, correlationId, GET, authz/perm/check, Failure, description, extra(result), error(e)
        else perm_get_route
            AuthzRouter->>Logger: logRequestFailure client_id, correlationId, GET, authz/perm/get, Failure, description, extra(result), error(e)
        end
        AuthzRouter->>GLib: handleException e, res
        GLib-->>Client: error response
    end

Class diagram for authz_router logging integration

classDiagram
    class AuthzRouter {
        +get_gridftp(req,res) void
        +get_perm_check(req,res) void
        +get_perm_get(req,res) void
    }

    class Logger {
        +logRequestStarted(client,correlationId,httpVerb,routePath,status,description) void
        +logRequestSuccess(client,correlationId,httpVerb,routePath,status,description,extra) void
        +logRequestFailure(client,correlationId,httpVerb,routePath,status,description,extra,error) void
    }

    class GLib {
        +getUserFromClientID(clientId) Client
        +getUserFromClientID_noexcept(clientId) Client
        +resolveID(id,client) Tuple
        +handleException(error,res) void
    }

    class Repo {
        +Repo(repoId)
        +get_path_type(path) PathType
    }

    class Client {
        +_id string
        +is_admin boolean
    }

    AuthzRouter ..> Logger : uses
    AuthzRouter ..> GLib : uses
    AuthzRouter ..> Repo : uses
    GLib ..> Client : returns
    Repo ..> PathType : returns

File-Level Changes

Change Details Files
Replace console logging in the /gridftp endpoint with structured logger calls for start, success, and failure, including correlation IDs and client metadata.
  • Import shared logger module and define a common basePath for authz routes
  • Track client in a variable outside the try block so it is available in both success and error logging paths
  • Log request start with client ID, correlation ID, HTTP verb, route path, and a JSON-encoded description of repo/file/action
  • On successful authorization, log a success event including client admin status in an extra payload
  • On exceptions, log a failure event including error details and client metadata before delegating to generic exception handling
core/database/foxx/api/authz_router.js
Add structured logging around /perm/check and /perm/get endpoints and ensure their results are captured in logs.
  • Initialize client and result variables outside try blocks for both perm endpoints
  • On request start, log a Started event with client ID, correlation ID, HTTP verb, route path, and a short description of the permission check/get operation
  • After computing permissions and sending the response, log a Success event including the computed result in extra/description
  • On exceptions, log a Failure event including the last known result (if any) and the thrown error, then pass control to existing error handling
core/database/foxx/api/authz_router.js
Extend unit tests to cover behavior of perm/check and perm/get endpoints.
  • Add test verifying perm/check returns granted=true for an admin user on their own record
  • Add test verifying perm/get returns a numeric permission bits value for an admin user on a record
  • Add test verifying perm/get returns HTTP 400 when called with an invalid ID format
core/database/foxx/tests/authz_router.test.js

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an issue from a review comment by replying to it. You can also reply to a review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull request title to generate a title at any time. You can also comment @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in the pull request body to generate a PR summary at any time exactly where you want it. You can also comment @sourcery-ai summary on the pull request to (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the pull request to resolve all Sourcery comments. Useful if you've already addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull request to dismiss all existing Sourcery reviews. Especially useful if you want to start fresh with a new review - don't forget to comment @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

  • Contact our support team for questions or feedback.
  • Visit our documentation for detailed guides and information.
  • Keep in touch with the Sourcery team by following us on X/Twitter, LinkedIn or GitHub.

sourcery-ai[bot] avatar Nov 25 '25 13:11 sourcery-ai[bot]