summaryrefslogtreecommitdiffstats
path: root/src/rgw/rgw_rest_sts.h
blob: d9baa2c3cacd8a93660442aba6625178da1a89af (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab

#ifndef CEPH_RGW_REST_STS_H
#define CEPH_RGW_REST_STS_H

#include "rgw_auth.h"
#include "rgw_auth_filters.h"
#include "rgw_sts.h"
#include "rgw_web_idp.h"

namespace rgw {
namespace auth {
namespace sts   {

class WebTokenEngine : public rgw::auth::Engine {
  CephContext* const cct;

  using result_t = rgw::auth::Engine::result_t;
  using token_t = rgw::web_idp::WebTokenClaims;

  const rgw::auth::TokenExtractor* const extractor;
  const rgw::auth::WebIdentityApplier::Factory* const apl_factory;

  bool is_applicable(const std::string& token) const noexcept;

  boost::optional<token_t>
  get_from_idp(const DoutPrefixProvider* dpp, const std::string& token) const;

  result_t authenticate(const DoutPrefixProvider* dpp,
                        const std::string& token,
                        const req_state* s) const;

public:
  WebTokenEngine(CephContext* const cct,
                    const rgw::auth::TokenExtractor* const extractor,
                    const rgw::auth::WebIdentityApplier::Factory* const apl_factory)
    : cct(cct),
      extractor(extractor),
      apl_factory(apl_factory) {
  }

  const char* get_name() const noexcept override {
    return "rgw::auth::sts::WebTokenEngine";
  }

  result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s) const override {
    return authenticate(dpp, extractor->get_token(s), s);
  }
}; /* class WebTokenEngine */

class DefaultStrategy : public rgw::auth::Strategy,
                        public rgw::auth::TokenExtractor,
                        public rgw::auth::WebIdentityApplier::Factory {
  RGWRados* const store;

  /* The engine. */
  const WebTokenEngine web_token_engine;

  using aplptr_t = rgw::auth::IdentityApplier::aplptr_t;

  /* The method implements TokenExtractor for Web Token in req_state. */
  std::string get_token(const req_state* const s) const override {
    return s->info.args.get("WebIdentityToken");
  }

  aplptr_t create_apl_web_identity( CephContext* cct,
                                    const req_state* s,
                                    const rgw::web_idp::WebTokenClaims& token) const override {
    auto apl = rgw::auth::add_sysreq(cct, store, s,
      rgw::auth::WebIdentityApplier(cct, store, token));
    return aplptr_t(new decltype(apl)(std::move(apl)));
  }

public:
  DefaultStrategy(CephContext* const cct,
                  RGWRados* const store)
    : store(store),
      web_token_engine(cct,
                        static_cast<rgw::auth::TokenExtractor*>(this),
                        static_cast<rgw::auth::WebIdentityApplier::Factory*>(this)) {
    /* When the constructor's body is being executed, all member engines
     * should be initialized. Thus, we can safely add them. */
    using Control = rgw::auth::Strategy::Control;
    add_engine(Control::SUFFICIENT, web_token_engine);
  }

  const char* get_name() const noexcept override {
    return "rgw::auth::sts::DefaultStrategy";
  }
};

}; /* namespace sts */
}; /* namespace auth */
};

class RGWREST_STS : public RGWRESTOp {
protected:
  STS::STSService sts;
public:
  RGWREST_STS() = default;
  int verify_permission() override;
  void send_response() override;
};

class RGWSTSAssumeRoleWithWebIdentity : public RGWREST_STS {
protected:
  string duration;
  string providerId;
  string policy;
  string roleArn;
  string roleSessionName;
  string sub;
  string aud;
  string iss;
public:
  RGWSTSAssumeRoleWithWebIdentity() = default;
  void execute() override;
  int get_params();
  const char* name() const override { return "assume_role_web_identity"; }
  RGWOpType get_type() override { return RGW_STS_ASSUME_ROLE_WEB_IDENTITY; }
};

class RGWSTSAssumeRole : public RGWREST_STS {
protected:
  string duration;
  string externalId;
  string policy;
  string roleArn;
  string roleSessionName;
  string serialNumber;
  string tokenCode;
public:
  RGWSTSAssumeRole() = default;
  void execute() override;
  int get_params();
  const char* name() const override { return "assume_role"; }
  RGWOpType get_type() override { return RGW_STS_ASSUME_ROLE; }
};

class RGWSTSGetSessionToken : public RGWREST_STS {
protected:
  string duration;
  string serialNumber;
  string tokenCode;
public:
  RGWSTSGetSessionToken() = default;
  void execute() override;
  int verify_permission() override;
  int get_params();
  const char* name() const override { return "get_session_token"; }
  RGWOpType get_type() override { return RGW_STS_GET_SESSION_TOKEN; }
};

class RGW_Auth_STS {
public:
  static int authorize(const DoutPrefixProvider *dpp,
                       RGWRados *store,
                       const rgw::auth::StrategyRegistry& auth_registry,
                       struct req_state *s);
};

class RGWHandler_REST_STS : public RGWHandler_REST {
  const rgw::auth::StrategyRegistry& auth_registry;
  const string& post_body;
  RGWOp *op_post() override;
  void rgw_sts_parse_input();
public:

  static int init_from_header(struct req_state *s, int default_formatter, bool configurable_format);

  RGWHandler_REST_STS(const rgw::auth::StrategyRegistry& auth_registry, const string& post_body="")
    : RGWHandler_REST(),
      auth_registry(auth_registry),
      post_body(post_body) {}
  ~RGWHandler_REST_STS() override = default;

  int init(RGWRados *store,
           struct req_state *s,
           rgw::io::BasicClient *cio) override;
  int authorize(const DoutPrefixProvider* dpp) override;
  int postauth_init() override { return 0; }
};

class RGWRESTMgr_STS : public RGWRESTMgr {
public:
  RGWRESTMgr_STS() = default;
  ~RGWRESTMgr_STS() override = default;
  
  RGWRESTMgr *get_resource_mgr(struct req_state* const s,
                               const std::string& uri,
                               std::string* const out_uri) override {
    return this;
  }

  RGWHandler_REST* get_handler(struct req_state*,
                               const rgw::auth::StrategyRegistry&,
                               const std::string&) override;
};

#endif /* CEPH_RGW_REST_STS_H */