injectAPIKeyToMetadata modifies the request body to include the API key ID in the meta_data. This function reads the request body, adds or updates the meta_data field, and sets the modified body back to the request. Parameters: - c: The Gin context containing the request. - apiKeyID: The API key ID
(c *gin.Context, apiKeyID string)
| 113 | // Returns: |
| 114 | // - error: An error if the body processing fails. |
| 115 | func injectAPIKeyToMetadata(c *gin.Context, apiKeyID string) error { |
| 116 | // Only proceed if this is a POST request |
| 117 | if c.Request.Method != "POST" { |
| 118 | return nil |
| 119 | } |
| 120 | |
| 121 | // Check if the request body is nil |
| 122 | if c.Request.Body == nil { |
| 123 | return nil |
| 124 | } |
| 125 | |
| 126 | // Read the request body |
| 127 | bodyBytes, err := io.ReadAll(c.Request.Body) |
| 128 | if err != nil { |
| 129 | return err |
| 130 | } |
| 131 | _ = c.Request.Body.Close() |
| 132 | |
| 133 | // Parse the request body as JSON |
| 134 | var bodyMap map[string]interface{} |
| 135 | if err := json.Unmarshal(bodyBytes, &bodyMap); err != nil { |
| 136 | // If not valid JSON, restore the original body and continue |
| 137 | c.Request.Body = io.NopCloser(bytes.NewBuffer(bodyBytes)) |
| 138 | return err |
| 139 | } |
| 140 | |
| 141 | // Check if meta_data field exists |
| 142 | metaData, ok := bodyMap["meta_data"].(map[string]interface{}) |
| 143 | if !ok { |
| 144 | // If meta_data doesn't exist or is not an object, create it |
| 145 | metaData = make(map[string]interface{}) |
| 146 | } |
| 147 | |
| 148 | // Add the API key ID to meta_data |
| 149 | metaData["LEDGERFORGE_GENERATED_BY"] = apiKeyID |
| 150 | |
| 151 | // Update the meta_data in the body |
| 152 | bodyMap["meta_data"] = metaData |
| 153 | |
| 154 | // Convert back to JSON |
| 155 | modifiedBody, err := json.Marshal(bodyMap) |
| 156 | if err != nil { |
| 157 | // If marshaling fails, restore the original body and continue |
| 158 | c.Request.Body = io.NopCloser(bytes.NewBuffer(bodyBytes)) |
| 159 | return err |
| 160 | } |
| 161 | |
| 162 | // Set the modified body back to the request |
| 163 | c.Request.Body = io.NopCloser(bytes.NewBuffer(modifiedBody)) |
| 164 | c.Request.ContentLength = int64(len(modifiedBody)) |
| 165 | |
| 166 | return nil |
| 167 | } |
| 168 | |
| 169 | // Authenticate returns a middleware function that handles authentication and authorization for all routes. |
| 170 | // It checks for the X-LedgerForge-Key header and validates it against either the master key or API keys. |