Issue:
[FEATURE] Allow rotating and revoking API keys

### Feature Description

As of now, the `merchant_account` table has an `api_key` field which restricts a merchant account to only have one API key. Furthermore, there are no mechanisms in place to revoke and regenerate API keys. To improve the convenience of rotating and revoking API keys, it'd be better to allow multiple API keys to be associated with a merchant account. Furthermore, API keys are stored in plaintext as of now. It'd be great if they could be hashed as well, when this request is addressed.

### Possible Implementation

A possible approach to address this is to add an `api_keys` table with `name`, `merchant_id`, `hashed_key` fields (including any additional fields as necessary). And for the API interface, this could include endpoints to create, retrieve, update and revoke an API key, and an endpoint to list all API keys associated with the current merchant account.

### Have you spent some time to check if this feature request has been raised before?

- [X] I checked and didn't find similar issue

### Have you read the Contributing Guidelines?

- [X] I have read the [Contributing Guidelines](https://github.com/juspay/hyperswitch/blob/main/docs/CONTRIBUTING.md)

### Are you willing to submit a PR?

Yes I am willing to submit a PR!

Resolution:
<think>
PR Context:
- Title: feat(router): implement API endpoints for managing API keys
- Merged: 2023-02-10T09:06:18Z
- Files changed: 30 files
- Commits: 21 commits

Implementation approach:
## Type of Change
<!-- Put an `x` in the boxes that apply -->

- [ ] Bugfix
- [x] New feature
- [ ] Enhancement
- [ ] Refactoring
- [ ] Dependency updates

## Description
<!-- Describe your changes in detail -->
This PR implements the endpoints to create, retrieve, update, revoke and list API keys. 

- As of now, the `last_used` field is included in the storage model, but I don't expect it to be actively used until API keys are cached in Redis or in-memory.
- The endpoints use admi
</think>

To implement this, you'll need to modify:


**Detailed Implementation:**


**Commit 1:** feat(router): implement API endpoints for managing API keys (#511)
Files to modify:


**crates/api_models/src/api_keys.rs**
  Add:
    - function: private::from
    - function: private::from
    - function: pub::serialize
    - function: pub::deserialize
    - function: private::expecting
    - function: private::visit_str
    - function: private::schema
    - function: private::test_serialization
    - function: private::test_deserialization
    - function: private::test_null
    - struct: pub::CreateApiKeyRequest
    - struct: pub::CreateApiKeyResponse
    - struct: pub::RetrieveApiKeyResponse
    - struct: pub::UpdateApiKeyRequest
    - struct: pub::RevokeApiKeyResponse
    - struct: pub::ListApiKeyConstraints
    - struct: private::NeverVisitor
    - enum: pub::ApiKeyExpiration
    - impl: impl From<ApiKeyExpiration> for Option<PrimitiveDateTime>
    - impl: impl From<Option<PrimitiveDateTime>> for ApiKeyExpiration
    - impl: impl serde::de::Visitor<'de> for NeverVisitor
    - impl: impl ToSchema<'a> for ApiKeyExpiration
    - mod: private::never
    - mod: private::api_key_expiration_tests

**crates/api_models/src/lib.rs**
  Add:
    - mod: pub::api_keys

**crates/common_utils/src/crypto.rs**
  Add:
    - function: pub::generate_cryptographically_secure_random_string
    - function: pub::generate_cryptographically_secure_random_bytes

**crates/router/src/compatibility/stripe/errors.rs**
  Modify existing code

**crates/router/src/consts.rs**
  Modify existing code

**crates/router/src/core.rs**
  Add:
    - mod: pub::api_keys

**crates/router/src/core/admin.rs**
  Modify existing code

**crates/router/src/core/api_keys.rs**
  Add:
    - function: pub::new
    - function: pub::new_hash_key
    - function: pub::new_key_id
    - function: pub::prefix
    - function: pub::peek
    - function: pub::keyed_hash
    - function: pub::verify_hash
    - function: pub::create_api_key
    - function: pub::retrieve_api_key
    - function: pub::update_api_key
    - function: pub::revoke_api_key
    - function: pub::list_api_keys
    - function: private::from
    - function: private::test_hashing_and_verification
    - struct: pub::PlaintextApiKey
    - struct: pub::HashedApiKey
    - impl: impl PlaintextApiKey
    - impl: impl From<HashedApiKey> for storage::HashedApiKey
    - mod: private::tests

**crates/router/src/core/errors.rs**
  Add:
    - enum: pub::ApiKeyError

**crates/router/src/core/errors/api_error_response.rs**
  Modify existing code

**crates/router/src/db.rs**
  Add:
    - mod: pub::api_keys

**crates/router/src/db/api_keys.rs**
  Add:
    - function: private::insert_api_key
    - function: private::update_api_key
    - function: private::revoke_api_key
    - function: private::find_api_key_optional
    - function: private::list_api_keys_by_merchant_id
    - function: private::insert_api_key
    - function: private::update_api_key
    - function: private::revoke_api_key
    - function: private::find_api_key_optional
    - function: private::list_api_keys_by_merchant_id
    - trait: pub::ApiKeyInterface
    - impl: impl ApiKeyInterface for Store
    - impl: impl ApiKeyInterface for MockDb

**crates/router/src/lib.rs**
  Modify existing code

**crates/router/src/openapi.rs**
  Modify existing code

**crates/router/src/routes.rs**
  Add:
    - mod: pub::api_keys

**crates/router/src/routes/api_keys.rs**
  Add:
    - function: pub::api_key_create
    - function: pub::api_key_retrieve
    - function: pub::api_key_update
    - function: pub::api_key_revoke
    - function: pub::api_key_list
    - function: private::get_merchant_id_header

**crates/router/src/routes/app.rs**
  Add:
    - function: pub::server
    - struct: pub::ApiKeys
    - impl: impl ApiKeys

**crates/router/src/types/api.rs**
  Add:
    - mod: pub::api_keys

**crates/router/src/types/api/api_keys.rs**
  Modify existing code

**crates/router/src/types/storage.rs**
  Add:
    - mod: pub::api_keys

**crates/router/src/types/storage/api_keys.rs**
  Modify existing code

**crates/router/src/types/transformers.rs**
  Add:
    - function: private::from
    - function: private::from
    - function: private::from
    - impl: impl From<
        F<(
            storage_models::api_keys::ApiKey,
            crate::core::api_keys::PlaintextApiKey,
        )>,
    > for F<api_models::api_keys::CreateApiKeyResponse>
    - impl: impl From<F<storage_models::api_keys::ApiKey>> for F<api_models::api_keys::RetrieveApiKeyResponse>
    - impl: impl From<F<api_models::api_keys::UpdateApiKeyRequest>> for F<storage_models::api_keys::ApiKeyUpdate>

**crates/router_env/src/env.rs**
  Add:
    - function: pub::prefix_for_env

**crates/router_env/src/logger/types.rs**
  Modify existing code

**crates/storage_models/src/api_keys.rs**
  Add:
    - function: private::from
    - function: private::from
    - function: private::to_sql
    - function: private::from_sql
    - function: private::build
    - struct: pub::ApiKey
    - struct: pub::ApiKeyNew
    - struct: pub::ApiKeyUpdateInternal
    - struct: pub::HashedApiKey
    - enum: pub::ApiKeyUpdate
    - impl: impl From<ApiKeyUpdate> for ApiKeyUpdateInternal
    - impl: impl From<String> for HashedApiKey
    - impl: impl ToSql<Text, DB> for super::HashedApiKey
    - impl: impl FromSql<Text, DB> for super::HashedApiKey
    - impl: impl Queryable<Text, DB> for super::HashedApiKey
    - mod: private::diesel_impl

**crates/storage_models/src/lib.rs**
  Add:
    - mod: pub::api_keys

**crates/storage_models/src/query.rs**
  Add:
    - mod: pub::api_keys

**crates/storage_models/src/query/api_keys.rs**
  Add:
    - function: pub::insert
    - function: pub::update_by_key_id
    - function: pub::revoke_by_key_id
    - function: pub::find_optional_by_key_id
    - function: pub::find_by_merchant_id
    - impl: impl ApiKeyNew
    - impl: impl ApiKey

**crates/storage_models/src/schema.rs**
  Modify existing code