cxxmcp 1.1.6
C++ MCP SDK
Loading...
Searching...
No Matches
token.hpp
Go to the documentation of this file.
1// Copyright (c) 2025 [caomengxuan666]
2
3#pragma once
4
5#include <optional>
6#include <string>
7#include <utility>
8#include <vector>
9
11#include "cxxmcp/auth/types.hpp"
13
16
17namespace mcp::auth {
18
20struct TokenSet {
21 std::string access_token;
22 std::string token_type = "Bearer";
23 std::optional<std::string> refresh_token;
24 std::optional<TimePoint> expires_at;
25 ScopeList scopes;
26 MetadataMap metadata;
27
30 bool expired(TimePoint now = SystemClock::now()) const {
31 return expires_at.has_value() && *expires_at <= now;
32 }
33};
34
37 TokenSet token_set;
38 bool refresh_token_rotated = false;
39};
40
45struct TokenKey {
46 std::string resource;
47 std::string issuer;
48 std::string client_id;
49 MetadataMap attributes;
50};
51
54 public:
55 virtual ~TokenStore() = default;
56
57 virtual core::Result<std::optional<TokenSet>> load(const TokenKey& key) = 0;
58 virtual core::Result<core::Unit> save(const TokenKey& key,
59 TokenSet tokens) = 0;
60 virtual core::Result<core::Unit> remove(const TokenKey& key) = 0;
61};
62
68class InMemoryTokenStore final : public TokenStore {
69 public:
70 core::Result<std::optional<TokenSet>> load(const TokenKey& key) override {
71 const auto iter = find_entry(key);
72 if (iter == entries_.end()) {
73 return std::optional<TokenSet>{};
74 }
75 return iter->second;
76 }
77
78 core::Result<core::Unit> save(const TokenKey& key, TokenSet tokens) override {
79 auto iter = find_entry(key);
80 if (iter == entries_.end()) {
81 entries_.emplace_back(key, std::move(tokens));
82 } else {
83 iter->second = std::move(tokens);
84 }
85 return core::Unit{};
86 }
87
88 core::Result<core::Unit> remove(const TokenKey& key) override {
89 auto iter = find_entry(key);
90 if (iter != entries_.end()) {
91 entries_.erase(iter);
92 }
93 return core::Unit{};
94 }
95
96 private:
97 using Entry = std::pair<TokenKey, TokenSet>;
98
99 static bool matches(const MetadataMap& lhs, const MetadataMap& rhs) {
100 if (lhs.size() != rhs.size()) {
101 return false;
102 }
103 bool equal = true;
104 auto lhs_iter = lhs.begin();
105 auto rhs_iter = rhs.begin();
106 for (; lhs_iter != lhs.end(); ++lhs_iter, ++rhs_iter) {
107 equal = constant_time_string_equal(lhs_iter->first, rhs_iter->first) &
108 constant_time_string_equal(lhs_iter->second, rhs_iter->second) &
109 equal;
110 }
111 return equal;
112 }
113
114 static bool matches(const TokenKey& lhs, const TokenKey& rhs) {
115 return constant_time_string_equal(lhs.resource, rhs.resource) &
116 constant_time_string_equal(lhs.issuer, rhs.issuer) &
117 constant_time_string_equal(lhs.client_id, rhs.client_id) &
118 matches(lhs.attributes, rhs.attributes);
119 }
120
121 std::vector<Entry>::iterator find_entry(const TokenKey& key) {
122 for (auto iter = entries_.begin(); iter != entries_.end(); ++iter) {
123 if (matches(iter->first, key)) {
124 return iter;
125 }
126 }
127 return entries_.end();
128 }
129
130 std::vector<Entry>::const_iterator find_entry(const TokenKey& key) const {
131 for (auto iter = entries_.begin(); iter != entries_.end(); ++iter) {
132 if (matches(iter->first, key)) {
133 return iter;
134 }
135 }
136 return entries_.end();
137 }
138
139 std::vector<Entry> entries_;
140};
141
142} // namespace mcp::auth
Shared lightweight value types for cxxmcp auth contracts.
Minimal non-persistent token store useful for tests and simple apps.
Definition token.hpp:68
Application-provided OAuth token persistence boundary.
Definition token.hpp:53
Constant-time comparison helpers for auth secrets and lookup keys.
bool constant_time_string_equal(std::string_view lhs, std::string_view rhs) noexcept
Compare two strings without data-dependent early exit.
Definition constant_time.hpp:17
Shared result and error primitives used by the public cxxmcp SDK.
std::monostate Unit
Success value for operations that only need to report failure.
Definition result.hpp:55
tl::expected< T, Error > Result
Alias for the SDK result type.
Definition result.hpp:64
Stable key for token storage.
Definition token.hpp:45
Token refresh result, including optional refresh-token rotation.
Definition token.hpp:36
OAuth access and refresh token state owned by the application.
Definition token.hpp:20
bool expired(TimePoint now=SystemClock::now()) const
Returns true when an expiry timestamp exists and is not in the future.
Definition token.hpp:30