]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_rest_oidc_provider.cc
import quincy beta 17.1.0
[ceph.git] / ceph / src / rgw / rgw_rest_oidc_provider.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
3
4 #include <errno.h>
5
6 #include "common/errno.h"
7 #include "common/Formatter.h"
8 #include "common/ceph_json.h"
9
10 #include "include/types.h"
11 #include "rgw_string.h"
12
13 #include "rgw_common.h"
14 #include "rgw_op.h"
15 #include "rgw_rest.h"
16 #include "rgw_role.h"
17 #include "rgw_rest_oidc_provider.h"
18 #include "rgw_oidc_provider.h"
19 #include "rgw_sal.h"
20
21 #define dout_subsys ceph_subsys_rgw
22
23 using namespace std;
24
25 int RGWRestOIDCProvider::verify_permission(optional_yield y)
26 {
27 if (s->auth.identity->is_anonymous()) {
28 return -EACCES;
29 }
30
31 provider_arn = s->info.args.get("OpenIDConnectProviderArn");
32 if (provider_arn.empty()) {
33 ldpp_dout(this, 20) << "ERROR: Provider ARN is empty"<< dendl;
34 return -EINVAL;
35 }
36
37 auto ret = check_caps(s->user->get_caps());
38 if (ret == 0) {
39 return ret;
40 }
41
42 uint64_t op = get_op();
43 auto rgw_arn = rgw::ARN::parse(provider_arn, true);
44 if (rgw_arn) {
45 if (!verify_user_permission(this, s, *rgw_arn, op)) {
46 return -EACCES;
47 }
48 } else {
49 return -EACCES;
50 }
51
52 return 0;
53 }
54
55 void RGWRestOIDCProvider::send_response()
56 {
57 if (op_ret) {
58 set_req_state_err(s, op_ret);
59 }
60 dump_errno(s);
61 end_header(s, this);
62 }
63
64 int RGWRestOIDCProviderRead::check_caps(const RGWUserCaps& caps)
65 {
66 return caps.check_cap("oidc-provider", RGW_CAP_READ);
67 }
68
69 int RGWRestOIDCProviderWrite::check_caps(const RGWUserCaps& caps)
70 {
71 return caps.check_cap("oidc-provider", RGW_CAP_WRITE);
72 }
73
74 int RGWCreateOIDCProvider::verify_permission(optional_yield y)
75 {
76 if (s->auth.identity->is_anonymous()) {
77 return -EACCES;
78 }
79
80 auto ret = check_caps(s->user->get_caps());
81 if (ret == 0) {
82 return ret;
83 }
84
85 string idp_url = url_remove_prefix(provider_url);
86 if (!verify_user_permission(this,
87 s,
88 rgw::ARN(idp_url,
89 "oidc-provider",
90 s->user->get_tenant(), true),
91 get_op())) {
92 return -EACCES;
93 }
94 return 0;
95 }
96
97 int RGWCreateOIDCProvider::get_params()
98 {
99 provider_url = s->info.args.get("Url");
100
101 auto val_map = s->info.args.get_params();
102 for (auto& it : val_map) {
103 if (it.first.find("ClientIDList.member.") != string::npos) {
104 client_ids.emplace_back(it.second);
105 }
106 if (it.first.find("ThumbprintList.member.") != string::npos) {
107 thumbprints.emplace_back(it.second);
108 }
109 }
110
111 if (provider_url.empty() || thumbprints.empty()) {
112 ldpp_dout(this, 20) << "ERROR: one of url or thumbprints is empty" << dendl;
113 return -EINVAL;
114 }
115
116 return 0;
117 }
118
119 void RGWCreateOIDCProvider::execute(optional_yield y)
120 {
121 op_ret = get_params();
122 if (op_ret < 0) {
123 return;
124 }
125
126 std::unique_ptr<rgw::sal::RGWOIDCProvider> provider = store->get_oidc_provider();
127 provider->set_url(provider_url);
128 provider->set_tenant(s->user->get_tenant());
129 provider->set_client_ids(client_ids);
130 provider->set_thumbprints(thumbprints);
131 op_ret = provider->create(s, true, y);
132
133 if (op_ret == 0) {
134 s->formatter->open_object_section("CreateOpenIDConnectProviderResponse");
135 s->formatter->open_object_section("CreateOpenIDConnectProviderResult");
136 provider->dump(s->formatter);
137 s->formatter->close_section();
138 s->formatter->open_object_section("ResponseMetadata");
139 s->formatter->dump_string("RequestId", s->trans_id);
140 s->formatter->close_section();
141 s->formatter->close_section();
142 }
143
144 }
145
146 void RGWDeleteOIDCProvider::execute(optional_yield y)
147 {
148 std::unique_ptr<rgw::sal::RGWOIDCProvider> provider = store->get_oidc_provider();
149 provider->set_arn(provider_arn);
150 provider->set_tenant(s->user->get_tenant());
151 op_ret = provider->delete_obj(s, y);
152
153 if (op_ret < 0 && op_ret != -ENOENT && op_ret != -EINVAL) {
154 op_ret = ERR_INTERNAL_ERROR;
155 }
156
157 if (op_ret == 0) {
158 s->formatter->open_object_section("DeleteOpenIDConnectProviderResponse");
159 s->formatter->open_object_section("ResponseMetadata");
160 s->formatter->dump_string("RequestId", s->trans_id);
161 s->formatter->close_section();
162 s->formatter->close_section();
163 }
164 }
165
166 void RGWGetOIDCProvider::execute(optional_yield y)
167 {
168 std::unique_ptr<rgw::sal::RGWOIDCProvider> provider = store->get_oidc_provider();
169 provider->set_arn(provider_arn);
170 provider->set_tenant(s->user->get_tenant());
171 op_ret = provider->get(s);
172
173 if (op_ret < 0 && op_ret != -ENOENT && op_ret != -EINVAL) {
174 op_ret = ERR_INTERNAL_ERROR;
175 }
176
177 if (op_ret == 0) {
178 s->formatter->open_object_section("GetOpenIDConnectProviderResponse");
179 s->formatter->open_object_section("ResponseMetadata");
180 s->formatter->dump_string("RequestId", s->trans_id);
181 s->formatter->close_section();
182 s->formatter->open_object_section("GetOpenIDConnectProviderResult");
183 provider->dump_all(s->formatter);
184 s->formatter->close_section();
185 s->formatter->close_section();
186 }
187 }
188
189 int RGWListOIDCProviders::verify_permission(optional_yield y)
190 {
191 if (s->auth.identity->is_anonymous()) {
192 return -EACCES;
193 }
194
195 if (int ret = check_caps(s->user->get_caps()); ret == 0) {
196 return ret;
197 }
198
199 if (!verify_user_permission(this,
200 s,
201 rgw::ARN(),
202 get_op())) {
203 return -EACCES;
204 }
205
206 return 0;
207 }
208
209 void RGWListOIDCProviders::execute(optional_yield y)
210 {
211 vector<std::unique_ptr<rgw::sal::RGWOIDCProvider>> result;
212 op_ret = store->get_oidc_providers(s, s->user->get_tenant(), result);
213
214 if (op_ret == 0) {
215 s->formatter->open_array_section("ListOpenIDConnectProvidersResponse");
216 s->formatter->open_object_section("ResponseMetadata");
217 s->formatter->dump_string("RequestId", s->trans_id);
218 s->formatter->close_section();
219 s->formatter->open_object_section("ListOpenIDConnectProvidersResult");
220 s->formatter->open_array_section("OpenIDConnectProviderList");
221 for (const auto& it : result) {
222 s->formatter->open_object_section("Arn");
223 auto& arn = it->get_arn();
224 ldpp_dout(s, 0) << "ARN: " << arn << dendl;
225 s->formatter->dump_string("Arn", arn);
226 s->formatter->close_section();
227 }
228 s->formatter->close_section();
229 s->formatter->close_section();
230 s->formatter->close_section();
231 }
232 }
233