Mercurial > hg > orthanc-gcp
annotate Plugin/GoogleAccount.cpp @ 43:5f50a2b2ae04
fix missing cpp
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 24 Feb 2021 07:27:30 +0100 |
parents | 21499c134785 |
children | 509334672b6b |
rev | line source |
---|---|
0 | 1 /** |
2 * Google Cloud Platform credentials for DICOMweb and Orthanc | |
42
21499c134785
upgrade to year 2021
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
40
diff
changeset
|
3 * Copyright (C) 2019-2021 Osimis S.A., Belgium |
0 | 4 * |
5 * This program is free software: you can redistribute it and/or | |
6 * modify it under the terms of the GNU General Public License as | |
7 * published by the Free Software Foundation, either version 3 of the | |
8 * License, or (at your option) any later version. | |
9 * | |
10 * In addition, as a special exception, the copyright holders of this | |
11 * program give permission to link the code of its release with the | |
12 * OpenSSL project's "OpenSSL" library (or with modified versions of it | |
13 * that use the same license as the "OpenSSL" library), and distribute | |
14 * the linked executables. You must obey the GNU General Public License | |
15 * in all respects for all of the code used other than "OpenSSL". If you | |
16 * modify file(s) with this exception, you may extend this exception to | |
17 * your version of the file(s), but you are not obligated to do so. If | |
18 * you do not wish to do so, delete this exception statement from your | |
19 * version. If you delete this exception statement from all source files | |
20 * in the program, then also delete it here. | |
21 * | |
22 * This program is distributed in the hope that it will be useful, but | |
23 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
25 * General Public License for more details. | |
26 * | |
27 * You should have received a copy of the GNU General Public License | |
28 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
29 **/ | |
30 | |
31 | |
32 #include "GoogleAccount.h" | |
33 | |
40 | 34 #include <Logging.h> |
31 | 35 #include <Toolbox.h> |
0 | 36 |
37 void GoogleAccount::LoadAuthorizedUser(const std::string& json) | |
38 { | |
39 google::cloud::StatusOr<google::cloud::storage::oauth2::AuthorizedUserCredentialsInfo> info = | |
40 google::cloud::storage::oauth2::ParseAuthorizedUserCredentials(json, "memory"); | |
41 | |
42 if (!info) | |
43 { | |
44 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat, | |
45 "Cannot parse authorized user configuration"); | |
46 } | |
47 else | |
48 { | |
49 type_ = Type_AuthorizedUser; | |
50 authorizedUser_.reset(new google::cloud::storage::oauth2::AuthorizedUserCredentialsInfo(*info)); | |
51 } | |
52 } | |
53 | |
54 | |
55 bool GoogleAccount::LoadServiceAccount(const OrthancPlugins::OrthancConfiguration& account) | |
56 { | |
57 std::string path; | |
58 | |
59 if (!account.LookupStringValue(path, "ServiceAccountFile")) | |
60 { | |
61 return false; | |
62 } | |
63 | |
64 OrthancPlugins::MemoryBuffer f; | |
65 f.ReadFile(path); | |
66 | |
67 std::string s; | |
68 f.ToString(s); | |
69 | |
70 google::cloud::StatusOr<google::cloud::storage::oauth2::ServiceAccountCredentialsInfo> info = | |
71 google::cloud::storage::oauth2::ParseServiceAccountCredentials(s, "memory"); | |
72 | |
73 if (!info) | |
74 { | |
75 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat, | |
76 "Cannot parse service account configuration at: " + path); | |
77 } | |
78 | |
79 type_ = Type_ServiceAccount; | |
80 serviceAccount_.reset(new google::cloud::storage::oauth2::ServiceAccountCredentialsInfo(*info)); | |
81 return true; | |
82 } | |
83 | |
84 | |
85 bool GoogleAccount::LoadAuthorizedUserFile(const OrthancPlugins::OrthancConfiguration& account) | |
86 { | |
87 std::string path; | |
88 | |
89 if (account.LookupStringValue(path, "AuthorizedUserFile")) | |
90 { | |
91 OrthancPlugins::MemoryBuffer f; | |
92 f.ReadFile(path); | |
93 | |
94 std::string s; | |
95 f.ToString(s); | |
96 | |
97 LoadAuthorizedUser(s); | |
98 return true; | |
99 } | |
100 else | |
101 { | |
102 return false; | |
103 } | |
104 } | |
105 | |
106 | |
107 bool GoogleAccount::LoadAuthorizedUserStrings(const OrthancPlugins::OrthancConfiguration& account) | |
108 { | |
109 std::string clientId, clientSecret, refreshToken; | |
110 | |
111 if (account.LookupStringValue(clientId, "AuthorizedUserClientId") && | |
112 account.LookupStringValue(clientSecret, "AuthorizedUserClientSecret") && | |
113 account.LookupStringValue(refreshToken, "AuthorizedUserRefreshToken")) | |
114 { | |
115 Json::Value json = Json::objectValue; | |
116 json["client_id"] = clientId; | |
117 json["client_secret"] = clientSecret; | |
118 json["refresh_token"] = refreshToken; | |
119 | |
120 LoadAuthorizedUser(json.toStyledString()); | |
121 return true; | |
122 } | |
123 else | |
124 { | |
125 return false; | |
126 } | |
127 } | |
128 | |
129 | |
130 GoogleAccount::GoogleAccount(const OrthancPlugins::OrthancConfiguration& account, | |
131 const std::string& name) : | |
132 name_(name) | |
133 { | |
134 if (!account.LookupStringValue(project_, "Project")) | |
135 { | |
136 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat, | |
137 "Missing \"Project\" option for account \"" + name + "\""); | |
138 } | |
139 | |
140 if (!account.LookupStringValue(location_, "Location")) | |
141 { | |
142 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat, | |
143 "Missing \"Location\" option for account \"" + name + "\""); | |
144 } | |
145 | |
146 if (!account.LookupStringValue(dataset_, "Dataset")) | |
147 { | |
148 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat, | |
149 "Missing \"Dataset\" option for account \"" + name + "\""); | |
150 } | |
151 | |
152 if (!account.LookupStringValue(dicomStore_, "DicomStore")) | |
153 { | |
154 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat, | |
155 "Missing \"DicomStore\" option for account \"" + name + "\""); | |
156 } | |
157 | |
158 if (!LoadServiceAccount(account) && | |
159 !LoadAuthorizedUserFile(account) && | |
160 !LoadAuthorizedUserStrings(account)) | |
161 { | |
162 throw Orthanc::OrthancException( | |
163 Orthanc::ErrorCode_BadFileFormat, | |
164 "Missing \"ServiceAccount\" or \"AuthorizedUserXXX\" option for account \"" + name + "\""); | |
165 } | |
166 } | |
167 | |
168 | |
169 const google::cloud::storage::oauth2::AuthorizedUserCredentialsInfo& GoogleAccount::GetAuthorizedUser() const | |
170 { | |
171 if (authorizedUser_.get() == NULL) | |
172 { | |
173 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | |
174 } | |
175 else | |
176 { | |
177 return *authorizedUser_; | |
178 } | |
179 } | |
180 | |
181 | |
182 google::cloud::storage::oauth2::ServiceAccountCredentialsInfo& GoogleAccount::GetServiceAccount() const | |
183 { | |
184 if (serviceAccount_.get() == NULL) | |
185 { | |
186 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | |
187 } | |
188 else | |
189 { | |
190 return *serviceAccount_; | |
191 } | |
192 } | |
193 | |
194 | |
195 static std::string AddTrailingSlash(const std::string& url) | |
196 { | |
197 // Add a trailing slash if needed | |
198 if (url.empty() || | |
199 url[url.size() - 1] != '/') | |
200 { | |
201 return url + '/'; | |
202 } | |
203 else | |
204 { | |
205 return url; | |
206 } | |
207 } | |
208 | |
209 | |
210 bool GoogleAccount::UpdateServerDefinition(const std::string& dicomWebPluginRoot, | |
211 const std::string& baseGoogleUrl, | |
212 const std::string& token) const | |
213 { | |
214 std::string url = (AddTrailingSlash(baseGoogleUrl) + | |
215 "projects/" + project_ + | |
216 "/locations/" + location_ + | |
217 "/datasets/" + dataset_ + | |
218 "/dicomStores/" + dicomStore_ + | |
219 "/dicomWeb/"); | |
220 | |
11
798951e457f3
fix parsing of authorization header
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
221 size_t colon = token.find(':'); |
798951e457f3
fix parsing of authorization header
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
222 if (colon == std::string::npos) |
798951e457f3
fix parsing of authorization header
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
223 { |
798951e457f3
fix parsing of authorization header
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
224 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
798951e457f3
fix parsing of authorization header
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
225 } |
798951e457f3
fix parsing of authorization header
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
226 |
798951e457f3
fix parsing of authorization header
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
227 std::string headerKey = Orthanc::Toolbox::StripSpaces(token.substr(0, colon)); |
798951e457f3
fix parsing of authorization header
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
228 std::string headerValue = Orthanc::Toolbox::StripSpaces(token.substr(colon + 1)); |
798951e457f3
fix parsing of authorization header
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
229 |
0 | 230 Json::Value headers = Json::objectValue; |
11
798951e457f3
fix parsing of authorization header
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
0
diff
changeset
|
231 headers[headerKey] = headerValue; |
0 | 232 |
233 Json::Value server = Json::objectValue; | |
234 server["Url"] = url; | |
235 server["HasDelete"] = "1"; // Google Cloud Platform allows "-X DELETE" | |
236 server["HttpHeaders"] = headers; | |
237 | |
238 Json::Value answer; | |
239 if (OrthancPlugins::RestApiPut(answer, AddTrailingSlash(dicomWebPluginRoot) + "servers/" + name_, | |
240 server, true)) | |
241 { | |
242 return true; | |
243 } | |
244 else | |
245 { | |
246 LOG(ERROR) << "Cannot update DICOMweb access to Google Cloud Platform: " << name_; | |
247 return false; | |
248 } | |
249 } |