Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build: expose openapi on http server #1718

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

leofvo
Copy link

@leofvo leofvo commented Oct 24, 2024

Adding an http endpoint to expose the openapi.json file
http://hostname:port/openapi.json

Also allow to enable the exposition or not using the config, not exposed by default to keep the actual behavior.

If you need to expose your openAPI, you can add the following configuration:

server:
  http:
    enabled: true
    expose_openapi: false

close #1714

Summary by CodeRabbit

  • New Features

    • Introduced a new configuration option to control the exposure of the OpenAPI specification.
    • Enhanced handling of HTTP and gRPC routes for improved clarity and separation of concerns.
  • Bug Fixes

    • Improved registration of gRPC handlers for better functionality and reliability.
  • Documentation

    • Added comments for clarity on the new configuration field's purpose.

Copy link

coderabbitai bot commented Oct 24, 2024

Walkthrough

The changes introduce a new configuration option expose_openapi: false in the example.config.yaml file, which controls whether the OpenAPI specification is exposed by the HTTP server. Corresponding modifications in internal/config/config.go add a boolean field ExposeOpenAPI to the HTTP struct, defaulting to false. The internal/servers/server.go file is updated to implement a new HTTP multiplexer, conditionally registering the OpenAPI endpoint based on the ExposeOpenAPI configuration.

Changes

File Path Change Summary
example.config.yaml Added configuration option: expose_openapi: false in the server section.
internal/config/config.go Added field: ExposeOpenAPI bool in HTTP struct; default value set to false.
internal/servers/server.go Introduced grpcMux and httpMux variables; updated HTTP server to conditionally register OpenAPI endpoint.

Assessment against linked issues

Objective Addressed Explanation
Add an endpoint to expose openapi (Issue #1714) The endpoint for exposing OpenAPI is not implemented.

🐰 In the garden, I hop and play,
New configs bloom, bright as day.
OpenAPI hides, but not for long,
Soon it’ll sing its JSON song!
With expose_openapi, we’ll find our way,
To share our specs, hip-hip-hooray! 🌼


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 298593b and a93e520.

📒 Files selected for processing (1)
  • internal/servers/server.go (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • internal/servers/server.go

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Outside diff range and nitpick comments (4)
example.config.yaml (1)

11-11: Add documentation for the new configuration option.

Other sections in the file are well-documented with comments explaining their purpose. Consider adding a comment block above the server section or within it to explain the expose_openapi option.

Example addition:

server:
  rate_limit: 100
  http:
    enabled: true
    port: 3476
+   # expose_openapi controls whether the OpenAPI specification is accessible
+   # via HTTP endpoint at /openapi.json
    expose_openapi: false
internal/servers/server.go (2)

Line range hint 338-349: Add security headers to HTTP server responses.

While the CORS configuration is good, consider adding additional security headers to enhance the security posture.

Add security headers by wrapping the CORS handler:

 		httpServer = &http.Server{
 			Addr: ":" + srv.HTTP.Port,
 			Handler: cors.New(cors.Options{
 				AllowCredentials: true,
 				AllowedOrigins:   srv.HTTP.CORSAllowedOrigins,
 				AllowedHeaders:   srv.HTTP.CORSAllowedHeaders,
 				AllowedMethods: []string{
 					http.MethodGet, http.MethodPost,
 					http.MethodHead, http.MethodPatch, http.MethodDelete, http.MethodPut,
 				},
-			}).Handler(httpMux),
+			}).Handler(securityHeaders(httpMux)),
 			ReadHeaderTimeout: 5 * time.Second,
 		}

+// securityHeaders adds security-related headers to all responses
+func securityHeaders(next http.Handler) http.Handler {
+    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+        w.Header().Set("X-Content-Type-Options", "nosniff")
+        w.Header().Set("X-Frame-Options", "DENY")
+        w.Header().Set("X-XSS-Protection", "1; mode=block")
+        w.Header().Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains")
+        next.ServeHTTP(w, r)
+    })
+}

330-334: Add code comments to document the OpenAPI endpoint.

The implementation meets the PR objectives, but would benefit from documentation explaining the endpoint's purpose and configuration.

 		if srv.HTTP.ExposeOpenAPI {
+			// Serve OpenAPI specification in JSON format when enabled via server configuration
+			// This endpoint is useful when deploying Permify in an API gateway environment
+			// Configuration: server.http.expose_openapi: true
 			httpMux.HandleFunc("/openapi.json", func(w http.ResponseWriter, r *http.Request) {
 				http.ServeFile(w, r, "./docs/api-reference/openapi.json")
 			})
 		}
internal/config/config.go (1)

40-40: Fix formatting issues in the new field declaration.

The field addition is appropriate, but there are formatting inconsistencies:

  • Replace tabs with spaces to match the codebase style
  • Fix the alignment of the field tags and comments

Apply this diff to fix the formatting:

-		ExposeOpenAPI			 bool 		 `mapstructure:"expose_openapi"` // expose OpenAPI configuration
+		ExposeOpenAPI      bool      `mapstructure:"expose_openapi"` // Expose OpenAPI configuration
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between dd605a2 and d4eef32.

📒 Files selected for processing (3)
  • example.config.yaml (1 hunks)
  • internal/config/config.go (2 hunks)
  • internal/servers/server.go (2 hunks)
🔇 Additional comments (2)
example.config.yaml (1)

11-11: LGTM! The configuration placement and default value are appropriate.

The new expose_openapi option is correctly placed under the server.http section and defaults to false, which maintains backward compatibility as specified in the PR objectives.

internal/config/config.go (1)

280-280: LGTM!

The default value of false aligns with the PR objectives to keep the OpenAPI endpoint disabled by default.

internal/servers/server.go Outdated Show resolved Hide resolved
internal/servers/server.go Outdated Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between d4eef32 and 298593b.

📒 Files selected for processing (1)
  • internal/servers/server.go (2 hunks)
🔇 Additional comments (3)
internal/servers/server.go (3)

308-324: LGTM! Well-structured handler registration.

The refactoring improves code maintainability by grouping handlers and providing clear error messages. This implementation addresses the previous review comments effectively.


Line range hint 341-352: LGTM! Proper CORS configuration.

The CORS setup is well-configured with appropriate security settings and method restrictions.


328-336: Verify OpenAPI configuration handling.

Let's ensure the configuration is properly handled across the codebase.

✅ Verification successful

Let me gather more information about the configuration structure and its usage to ensure complete verification.


Based on the gathered information, I can now provide the final response:

OpenAPI configuration is properly implemented and secure

The implementation is correctly configured with:

  • Configuration properly defined in internal/config/config.go with ExposeOpenAPI field mapped to expose_openapi
  • Default configuration in example.config.yaml has it disabled by default (false)
  • The endpoint is only exposed when explicitly enabled through configuration
  • The implementation includes proper HTTP method validation (GET only)
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify OpenAPI configuration and file existence

# Check if OpenAPI configuration is properly defined in config files
echo "Checking config files for OpenAPI settings..."
rg -l "expose_openapi" --type yaml

# Verify OpenAPI file existence and JSON validity
echo -e "\nVerifying OpenAPI file..."
if [ -f "./docs/api-reference/openapi.json" ]; then
    echo "OpenAPI file exists"
    if jq empty "./docs/api-reference/openapi.json" 2>/dev/null; then
        echo "OpenAPI file is valid JSON"
    else
        echo "OpenAPI file is not valid JSON"
    fi
else
    echo "OpenAPI file does not exist"
fi

Length of output: 426


Script:

#!/bin/bash
# Check the configuration structure in example config
echo "Checking example config structure:"
cat example.config.yaml | grep -A 5 -B 5 "expose_openapi"

# Check for HTTP server configuration struct definition
echo -e "\nChecking HTTP server configuration struct:"
ast-grep --pattern 'type HTTP struct {
  $$$
  ExposeOpenAPI $_ `$$$`
  $$$
}'

# Look for other potential usages of ExposeOpenAPI
echo -e "\nChecking other usages of ExposeOpenAPI:"
rg "ExposeOpenAPI" -B 2 -A 2

Length of output: 1907

internal/servers/server.go Outdated Show resolved Hide resolved
factorize repetitive blocks
verify http method on openapi request
@leofvo leofvo force-pushed the expose-openapi-on-http-server branch from 298593b to a93e520 Compare October 28, 2024 10:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add an endpoint to expose openapi
1 participant