]>
Commit | Line | Data |
---|---|---|
f91f0fd5 TL |
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" | |
f67539c2 | 19 | #include "rgw_sal_rados.h" |
f91f0fd5 TL |
20 | |
21 | #define dout_subsys ceph_subsys_rgw | |
22 | ||
f67539c2 | 23 | int RGWRestOIDCProvider::verify_permission(optional_yield y) |
f91f0fd5 TL |
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()) { | |
b3b6e05e | 31 | ldpp_dout(this, 20) << "ERROR: Provider ARN is empty"<< dendl; |
f91f0fd5 TL |
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 | ||
f67539c2 | 72 | int RGWCreateOIDCProvider::verify_permission(optional_yield y) |
f91f0fd5 TL |
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()) { | |
b3b6e05e | 110 | ldpp_dout(this, 20) << "ERROR: one of url or thumbprints is empty" << dendl; |
f91f0fd5 TL |
111 | return -EINVAL; |
112 | } | |
113 | ||
114 | return 0; | |
115 | } | |
116 | ||
f67539c2 | 117 | void RGWCreateOIDCProvider::execute(optional_yield y) |
f91f0fd5 TL |
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); | |
b3b6e05e | 126 | op_ret = provider.create(s, true, y); |
f91f0fd5 TL |
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 | ||
f67539c2 | 141 | void RGWDeleteOIDCProvider::execute(optional_yield y) |
f91f0fd5 TL |
142 | { |
143 | RGWOIDCProvider provider(s->cct, store->getRados()->pctl, provider_arn, s->user->get_tenant()); | |
b3b6e05e | 144 | op_ret = provider.delete_obj(s, y); |
f67539c2 | 145 | |
f91f0fd5 TL |
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 | ||
f67539c2 | 159 | void RGWGetOIDCProvider::execute(optional_yield y) |
f91f0fd5 TL |
160 | { |
161 | RGWOIDCProvider provider(s->cct, store->getRados()->pctl, provider_arn, s->user->get_tenant()); | |
b3b6e05e | 162 | op_ret = provider.get(s); |
f91f0fd5 TL |
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 | ||
f67539c2 | 180 | int RGWListOIDCProviders::verify_permission(optional_yield y) |
f91f0fd5 TL |
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 | ||
f67539c2 | 200 | void RGWListOIDCProviders::execute(optional_yield y) |
f91f0fd5 TL |
201 | { |
202 | vector<RGWOIDCProvider> result; | |
b3b6e05e | 203 | op_ret = RGWOIDCProvider::get_providers(s, store->getRados(), s->user->get_tenant(), result); |
f91f0fd5 TL |
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(); | |
b3b6e05e | 215 | ldpp_dout(s, 0) << "ARN: " << arn << dendl; |
f91f0fd5 TL |
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 |