Mercurial > hg > orthanc-authorization
annotate Plugin/CachedAuthorizationService.cpp @ 181:e20652d1e70a 0.5.2
closing branch 0.5.2
author | Alain Mazy <am@orthanc.team> |
---|---|
date | Thu, 16 May 2024 10:32:41 +0200 |
parents | e381ba725669 |
children | 7381a7674b36 |
rev | line source |
---|---|
1 | 1 /** |
2 * Advanced authorization plugin for Orthanc | |
68 | 3 * Copyright (C) 2017-2023 Osimis S.A., Belgium |
1 | 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 "CachedAuthorizationService.h" | |
20 | |
32 | 21 #include <OrthancException.h> |
71 | 22 #include <Toolbox.h> |
1 | 23 |
24 #include <boost/lexical_cast.hpp> | |
25 | |
26 namespace OrthancPlugins | |
27 { | |
28 std::string CachedAuthorizationService::ComputeKey(OrthancPluginHttpMethod method, | |
29 const AccessedResource& access, | |
72
e381ba725669
new PUT auth/tokens/{token-type} API route + updated interface with WebService
Alain Mazy <am@osimis.io>
parents:
71
diff
changeset
|
30 const Token* token, |
1 | 31 const std::string& tokenValue) const |
32 { | |
72
e381ba725669
new PUT auth/tokens/{token-type} API route + updated interface with WebService
Alain Mazy <am@osimis.io>
parents:
71
diff
changeset
|
33 if (token != NULL) |
e381ba725669
new PUT auth/tokens/{token-type} API route + updated interface with WebService
Alain Mazy <am@osimis.io>
parents:
71
diff
changeset
|
34 { |
e381ba725669
new PUT auth/tokens/{token-type} API route + updated interface with WebService
Alain Mazy <am@osimis.io>
parents:
71
diff
changeset
|
35 return (boost::lexical_cast<std::string>(method) + "|" + |
e381ba725669
new PUT auth/tokens/{token-type} API route + updated interface with WebService
Alain Mazy <am@osimis.io>
parents:
71
diff
changeset
|
36 boost::lexical_cast<std::string>(access.GetLevel()) + "|" + |
e381ba725669
new PUT auth/tokens/{token-type} API route + updated interface with WebService
Alain Mazy <am@osimis.io>
parents:
71
diff
changeset
|
37 access.GetOrthancId() + "|" + token->GetKey() + "|" + tokenValue); |
e381ba725669
new PUT auth/tokens/{token-type} API route + updated interface with WebService
Alain Mazy <am@osimis.io>
parents:
71
diff
changeset
|
38 } |
e381ba725669
new PUT auth/tokens/{token-type} API route + updated interface with WebService
Alain Mazy <am@osimis.io>
parents:
71
diff
changeset
|
39 else |
e381ba725669
new PUT auth/tokens/{token-type} API route + updated interface with WebService
Alain Mazy <am@osimis.io>
parents:
71
diff
changeset
|
40 { |
e381ba725669
new PUT auth/tokens/{token-type} API route + updated interface with WebService
Alain Mazy <am@osimis.io>
parents:
71
diff
changeset
|
41 return (boost::lexical_cast<std::string>(method) + "|" + |
e381ba725669
new PUT auth/tokens/{token-type} API route + updated interface with WebService
Alain Mazy <am@osimis.io>
parents:
71
diff
changeset
|
42 boost::lexical_cast<std::string>(access.GetLevel()) + "|" + |
e381ba725669
new PUT auth/tokens/{token-type} API route + updated interface with WebService
Alain Mazy <am@osimis.io>
parents:
71
diff
changeset
|
43 access.GetOrthancId() + "|anonymous"); |
e381ba725669
new PUT auth/tokens/{token-type} API route + updated interface with WebService
Alain Mazy <am@osimis.io>
parents:
71
diff
changeset
|
44 } |
1 | 45 } |
46 | |
47 | |
71 | 48 std::string CachedAuthorizationService::ComputeKey(const std::string& permission, |
72
e381ba725669
new PUT auth/tokens/{token-type} API route + updated interface with WebService
Alain Mazy <am@osimis.io>
parents:
71
diff
changeset
|
49 const Token* token, |
71 | 50 const std::string& tokenValue) const |
51 { | |
72
e381ba725669
new PUT auth/tokens/{token-type} API route + updated interface with WebService
Alain Mazy <am@osimis.io>
parents:
71
diff
changeset
|
52 if (token != NULL) |
e381ba725669
new PUT auth/tokens/{token-type} API route + updated interface with WebService
Alain Mazy <am@osimis.io>
parents:
71
diff
changeset
|
53 { |
e381ba725669
new PUT auth/tokens/{token-type} API route + updated interface with WebService
Alain Mazy <am@osimis.io>
parents:
71
diff
changeset
|
54 return (permission + "|" + token->GetKey() + "|" + tokenValue); |
e381ba725669
new PUT auth/tokens/{token-type} API route + updated interface with WebService
Alain Mazy <am@osimis.io>
parents:
71
diff
changeset
|
55 } |
e381ba725669
new PUT auth/tokens/{token-type} API route + updated interface with WebService
Alain Mazy <am@osimis.io>
parents:
71
diff
changeset
|
56 else |
e381ba725669
new PUT auth/tokens/{token-type} API route + updated interface with WebService
Alain Mazy <am@osimis.io>
parents:
71
diff
changeset
|
57 { |
e381ba725669
new PUT auth/tokens/{token-type} API route + updated interface with WebService
Alain Mazy <am@osimis.io>
parents:
71
diff
changeset
|
58 return (permission + "|anonymous"); |
e381ba725669
new PUT auth/tokens/{token-type} API route + updated interface with WebService
Alain Mazy <am@osimis.io>
parents:
71
diff
changeset
|
59 } |
71 | 60 } |
61 | |
62 | |
63 CachedAuthorizationService::CachedAuthorizationService(BaseAuthorizationService* decorated /* takes ownership */, | |
1 | 64 ICacheFactory& factory) : |
65 decorated_(decorated), | |
66 cache_(factory.Create()) | |
67 { | |
68 if (decorated_.get() == NULL) | |
69 { | |
70 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
71 } | |
72 } | |
73 | |
74 | |
71 | 75 bool CachedAuthorizationService::IsGrantedInternal(unsigned int& validity, |
76 OrthancPluginHttpMethod method, | |
77 const AccessedResource& access, | |
78 const Token* token, | |
79 const std::string& tokenValue) | |
1 | 80 { |
81 assert(decorated_.get() != NULL); | |
82 | |
72
e381ba725669
new PUT auth/tokens/{token-type} API route + updated interface with WebService
Alain Mazy <am@osimis.io>
parents:
71
diff
changeset
|
83 std::string key = ComputeKey(method, access, token, tokenValue); |
1 | 84 std::string value; |
85 | |
86 if (cache_->Retrieve(value, key)) | |
87 { | |
88 // Return the previously cached value | |
89 return (value == "1"); | |
90 } | |
91 | |
71 | 92 bool granted = decorated_->IsGrantedInternal(validity, method, access, token, tokenValue); |
1 | 93 |
94 if (granted) | |
95 { | |
96 if (validity > 0) | |
97 { | |
98 cache_->Store(key, "1", validity); | |
99 } | |
100 | |
101 return true; | |
102 } | |
103 else | |
104 { | |
105 if (validity > 0) | |
106 { | |
107 cache_->Store(key, "0", validity); | |
108 } | |
109 | |
110 return false; | |
111 } | |
112 } | |
113 | |
114 | |
71 | 115 bool CachedAuthorizationService::GetUserProfileInternal(unsigned int& validity, |
116 Json::Value& profile /* out */, | |
117 const Token* token, | |
118 const std::string& tokenValue) | |
119 { | |
120 // no cache used when retrieving the full user profile | |
121 return decorated_->GetUserProfileInternal(validity, profile, token, tokenValue); | |
122 } | |
123 | |
124 bool CachedAuthorizationService::HasUserPermissionInternal(unsigned int& validity, | |
125 const std::string& permission, | |
126 const Token* token, | |
127 const std::string& tokenValue) | |
1 | 128 { |
129 assert(decorated_.get() != NULL); | |
130 | |
72
e381ba725669
new PUT auth/tokens/{token-type} API route + updated interface with WebService
Alain Mazy <am@osimis.io>
parents:
71
diff
changeset
|
131 std::string key = ComputeKey(permission, token, tokenValue); |
71 | 132 std::string value; |
133 | |
134 if (cache_->Retrieve(value, key)) | |
135 { | |
136 // Return the previously cached value | |
137 return (value == "1"); | |
138 } | |
139 | |
140 bool granted = decorated_->HasUserPermissionInternal(validity, permission, token, tokenValue); | |
141 | |
142 if (granted) | |
143 { | |
144 if (validity > 0) | |
145 { | |
146 cache_->Store(key, "1", validity); | |
147 } | |
148 | |
149 return true; | |
150 } | |
151 else | |
152 { | |
153 if (validity > 0) | |
154 { | |
155 cache_->Store(key, "0", validity); | |
156 } | |
157 | |
158 return false; | |
159 } | |
1 | 160 } |
69
af44dce56328
new 'auth/user-profile' Rest API route
Alain Mazy <am@osimis.io>
parents:
68
diff
changeset
|
161 |
71 | 162 |
69
af44dce56328
new 'auth/user-profile' Rest API route
Alain Mazy <am@osimis.io>
parents:
68
diff
changeset
|
163 |
1 | 164 } |