ugent-library / old-people-service

People service
Apache License 2.0
0 stars 0 forks source link

[OpenAPI] Secure the RESTFul API #21

Closed netsensei closed 1 year ago

netsensei commented 1 year ago

Story

The RESTful API of the People service needs to be secured. I can only access the API calls if I pass an API key along with the HTTP requests.

Success criteria

Implementation suggestion

Define how you will secure the API in the openapi.yaml file:

security:
  - apiKey: []

components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: X-Api-Key

In api.go imlement a security handler:

func (s *apiSecurityHandler) HandleApiKey(ctx context.Context, operationName string, t api.ApiKey) (context.Context, error) {
    if t.APIKey == s.APIKey {
        return ctx, nil
    }
    return ctx, errors.New("unauthorized")
}

Add it to mux in api.go:

apiServer, err := api.NewServer(api.NewService(repo), &apiSecurityHandler{APIKey: config.APIKey})
if err != nil {
    return err
}

Finally, add the config.APIKey to your Config struct as an environment variable.

Automatic testing scenario

Write a high-level way to test this with Cypress if applicable.

Additional information

e.g. requires external API integration, etc.

Related issues

nicolasfranck commented 1 year ago

@netsensei for some reason that builtin authentication handler returns status 401 instead of 403 (so also in the oai-service), either when no key is given, or when the wrong key is given.

See also https://github.com/ogen-go/ogen/blob/9fe6c379919feffc4adf00592bf5ff5cd651f278/ogenerrors/ogenerrors.go#L53

I can of course change the status code in the error handler (https://github.com/ugent-library/people-service/blob/main/cmd/server_cmd.go#L60), but then there is also that wrapped error that contains "unauthorized" somewhere.

netsensei commented 1 year ago

@nicolasfranck 401 is the correct status code when you don't pass an API key; or the API key is invalid, revoked, etc.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401

indicates that the client request has not been completed because it lacks valid authentication credentials for the requested resource.

403 would be used if the application refuses authorization:

The access is tied to the application logic, such as insufficient rights to a resource.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403