1
|
1 /**
|
|
2 * Advanced authorization plugin for Orthanc
|
|
3 * Copyright (C) 2017 Osimis, Belgium
|
|
4 *
|
|
5 * This program is free software: you can redistribute it and/or
|
|
6 * modify it under the terms of the GNU Affero General Public License
|
|
7 * as published by the Free Software Foundation, either version 3 of
|
|
8 * the License, or (at your option) any later version.
|
|
9 *
|
|
10 * This program is distributed in the hope that it will be useful, but
|
|
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
13 * Affero General Public License for more details.
|
|
14 *
|
|
15 * You should have received a copy of the GNU Affero General Public License
|
|
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
17 **/
|
|
18
|
|
19 #include "AuthorizationWebService.h"
|
|
20
|
|
21 #include "../Resources/Orthanc/Core/Logging.h"
|
|
22 #include "../Resources/Orthanc/Plugins/Samples/Common/OrthancPluginCppWrapper.h"
|
|
23
|
|
24 namespace OrthancPlugins
|
|
25 {
|
|
26 bool AuthorizationWebService::IsGrantedInternal(unsigned int& validity,
|
|
27 OrthancPluginHttpMethod method,
|
|
28 const AccessedResource& access,
|
|
29 const Token* token,
|
|
30 const std::string& tokenValue)
|
|
31 {
|
|
32 Json::Value body = Json::objectValue;
|
|
33
|
|
34 switch (method)
|
|
35 {
|
|
36 case OrthancPluginHttpMethod_Get:
|
|
37 body["method"] ="get";
|
|
38 break;
|
|
39
|
|
40 case OrthancPluginHttpMethod_Post:
|
|
41 body["method"] ="post";
|
|
42 break;
|
|
43
|
|
44 case OrthancPluginHttpMethod_Put:
|
|
45 body["method"] ="put";
|
|
46 break;
|
|
47
|
|
48 case OrthancPluginHttpMethod_Delete:
|
|
49 body["method"] ="delete";
|
|
50 break;
|
|
51
|
|
52 default:
|
|
53 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
|
|
54 }
|
|
55
|
|
56 body["level"] = EnumerationToString(access.GetLevel());
|
|
57
|
|
58 if (access.GetLevel() == AccessLevel_System)
|
|
59 {
|
|
60 body["uri"] = access.GetOrthancId();
|
|
61 }
|
|
62 else
|
|
63 {
|
|
64 body["orthanc-id"] = access.GetOrthancId();
|
|
65 body["dicom-uid"] = access.GetDicomUid();
|
|
66 }
|
|
67
|
|
68 if (token != NULL)
|
|
69 {
|
|
70 body["token-key"] = token->GetKey();
|
|
71 body["token-value"] = tokenValue;
|
|
72 }
|
|
73
|
|
74 MemoryBuffer answerBody(context_);
|
|
75 MemoryBuffer answerHeaders(context_);
|
|
76 uint16_t httpStatus = 0;
|
|
77
|
|
78 uint32_t headersCount = 0;
|
10
|
79 const char* headersKeys[2];
|
|
80 const char* headersValues[2];
|
1
|
81
|
|
82 if (token != NULL &&
|
|
83 token->GetType() == TokenType_HttpHeader)
|
|
84 {
|
|
85 // If the token source is a HTTP header, forward it also as a
|
|
86 // HTTP header
|
10
|
87 headersKeys[headersCount] = token->GetKey().c_str();
|
|
88 headersValues[headersCount] = tokenValue.c_str();
|
|
89 headersCount++;
|
1
|
90 }
|
|
91
|
10
|
92 // set the correct content type for the outgoing
|
|
93 headersKeys[headersCount] = "Content-Type";
|
|
94 headersValues[headersCount] = "application/json";
|
|
95 headersCount++;
|
|
96
|
1
|
97 std::string flatBody = body.toStyledString();
|
|
98
|
|
99 if (OrthancPluginHttpClient(context_, *answerBody, *answerHeaders,
|
|
100 &httpStatus, OrthancPluginHttpMethod_Post,
|
|
101 url_.c_str(), headersCount, headersKeys, headersValues,
|
|
102 flatBody.c_str(), flatBody.size(),
|
|
103 username_.empty() ? NULL : username_.c_str(),
|
|
104 password_.empty() ? NULL : password_.c_str(),
|
|
105 10 /* timeout */, NULL, NULL, NULL, 0)
|
|
106 != OrthancPluginErrorCode_Success)
|
|
107 {
|
|
108 throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol);
|
|
109 }
|
|
110
|
|
111 Json::Value answer;
|
|
112 answerBody.ToJson(answer);
|
|
113
|
|
114 static const char* GRANTED = "granted";
|
|
115 static const char* VALIDITY = "validity";
|
|
116
|
|
117 if (answer.type() != Json::objectValue ||
|
|
118 !answer.isMember(GRANTED) ||
|
|
119 answer[GRANTED].type() != Json::booleanValue ||
|
|
120 (answer.isMember(VALIDITY) &&
|
|
121 answer[VALIDITY].type() != Json::intValue))
|
|
122 {
|
|
123 LOG(ERROR) << "Syntax error in the result of the Web service";
|
|
124 throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol);
|
|
125 }
|
|
126
|
|
127 validity = 0;
|
|
128 if (answer.isMember(VALIDITY))
|
|
129 {
|
|
130 int tmp = answer[VALIDITY].asInt();
|
|
131 if (tmp < 0)
|
|
132 {
|
|
133 LOG(ERROR) << "A validity duration cannot be negative";
|
|
134 throw Orthanc::OrthancException(Orthanc::ErrorCode_NetworkProtocol);
|
|
135 }
|
|
136
|
|
137 validity = static_cast<unsigned int>(tmp);
|
|
138 }
|
|
139
|
|
140 return answer[GRANTED].asBool();
|
|
141 }
|
|
142
|
|
143
|
|
144 AuthorizationWebService::AuthorizationWebService(OrthancPluginContext* context,
|
|
145 const std::string& url) :
|
|
146 context_(context),
|
|
147 url_(url)
|
|
148 {
|
|
149 if (context_ == NULL)
|
|
150 {
|
|
151 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
|
|
152 }
|
|
153 }
|
|
154
|
|
155
|
|
156 void AuthorizationWebService::SetCredentials(const std::string& username,
|
|
157 const std::string& password)
|
|
158 {
|
|
159 username_ = username;
|
|
160 password_ = password;
|
|
161 }
|
|
162 }
|