]>
Commit | Line | Data |
---|---|---|
11fdf7f2 | 1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
9f95a23c | 2 | // vim: ts=8 sw=2 smarttab ft=cpp |
11fdf7f2 TL |
3 | |
4 | #include "rgw_opa.h" | |
9f95a23c | 5 | #include "rgw_http_client.h" |
11fdf7f2 TL |
6 | |
7 | #define dout_context g_ceph_context | |
8 | #define dout_subsys ceph_subsys_rgw | |
9 | ||
10 | int rgw_opa_authorize(RGWOp *& op, | |
11 | req_state * const s) | |
12 | { | |
13 | ||
14 | ldpp_dout(op, 2) << "authorizing request using OPA" << dendl; | |
15 | ||
16 | /* get OPA url */ | |
17 | const string& opa_url = s->cct->_conf->rgw_opa_url; | |
18 | if (opa_url == "") { | |
19 | ldpp_dout(op, 2) << "OPA_URL not provided" << dendl; | |
20 | return -ERR_INVALID_REQUEST; | |
21 | } | |
22 | ldpp_dout(op, 2) << "OPA URL= " << opa_url.c_str() << dendl; | |
23 | ||
24 | /* get authentication token for OPA */ | |
25 | const string& opa_token = s->cct->_conf->rgw_opa_token; | |
26 | ||
27 | int ret; | |
28 | bufferlist bl; | |
29 | RGWHTTPTransceiver req(s->cct, "POST", opa_url.c_str(), &bl); | |
30 | ||
31 | /* set required headers for OPA request */ | |
32 | req.append_header("X-Auth-Token", opa_token); | |
33 | req.append_header("Content-Type", "application/json"); | |
34 | ||
35 | /* check if we want to verify OPA server SSL certificate */ | |
36 | req.set_verify_ssl(s->cct->_conf->rgw_opa_verify_ssl); | |
37 | ||
38 | /* create json request body */ | |
39 | JSONFormatter jf; | |
40 | jf.open_object_section(""); | |
41 | jf.open_object_section("input"); | |
42 | jf.dump_string("method", s->info.env->get("REQUEST_METHOD")); | |
43 | jf.dump_string("relative_uri", s->relative_uri.c_str()); | |
44 | jf.dump_string("decoded_uri", s->decoded_uri.c_str()); | |
45 | jf.dump_string("params", s->info.request_params.c_str()); | |
46 | jf.dump_string("request_uri_aws4", s->info.request_uri_aws4.c_str()); | |
47 | jf.dump_string("object_name", s->object.name.c_str()); | |
f6b5b4d7 | 48 | jf.dump_string("subuser", s->auth.identity->get_subuser().c_str()); |
9f95a23c | 49 | jf.dump_object("user_info", s->user->get_info()); |
11fdf7f2 TL |
50 | jf.dump_object("bucket_info", s->bucket_info); |
51 | jf.close_section(); | |
52 | jf.close_section(); | |
53 | ||
54 | std::stringstream ss; | |
55 | jf.flush(ss); | |
56 | req.set_post_data(ss.str()); | |
57 | req.set_send_length(ss.str().length()); | |
58 | ||
59 | /* send request */ | |
9f95a23c | 60 | ret = req.process(null_yield); |
11fdf7f2 TL |
61 | if (ret < 0) { |
62 | ldpp_dout(op, 2) << "OPA process error:" << bl.c_str() << dendl; | |
63 | return ret; | |
64 | } | |
65 | ||
66 | /* check OPA response */ | |
67 | JSONParser parser; | |
68 | if (!parser.parse(bl.c_str(), bl.length())) { | |
69 | ldpp_dout(op, 2) << "OPA parse error: malformed json" << dendl; | |
70 | return -EINVAL; | |
71 | } | |
72 | ||
73 | bool opa_result; | |
74 | JSONDecoder::decode_json("result", opa_result, &parser); | |
75 | ||
76 | if (opa_result == false) { | |
77 | ldpp_dout(op, 2) << "OPA rejecting request" << dendl; | |
78 | return -EPERM; | |
79 | } | |
80 | ||
81 | ldpp_dout(op, 2) << "OPA accepting request" << dendl; | |
82 | return 0; | |
83 | } |