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