1 /** 2 * Orthanc - A Lightweight, RESTful DICOM Store 3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics 4 * Department, University Hospital of Liege, Belgium 5 * Copyright (C) 2017-2021 Osimis S.A., Belgium 6 * 7 * This program is free software: you can redistribute it and/or 8 * modify it under the terms of the GNU Affero General Public License 9 * as published by the Free Software Foundation, either version 3 of 10 * the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Affero General Public License for more details. 16 * 17 * You should have received a copy of the GNU Affero General Public License 18 * along with this program. If not, see <http://www.gnu.org/licenses/>. 19 **/ 20 21 22 #include "PostgreSQLParameters.h" 23 24 #include <Logging.h> 25 #include <OrthancException.h> 26 27 #include <boost/lexical_cast.hpp> 28 29 30 namespace OrthancDatabases 31 { Reset()32 void PostgreSQLParameters::Reset() 33 { 34 host_ = "localhost"; 35 port_ = 5432; 36 username_ = ""; 37 password_ = ""; 38 database_.clear(); 39 uri_.clear(); 40 ssl_ = false; 41 lock_ = true; 42 maxConnectionRetries_ = 10; 43 connectionRetryInterval_ = 5; 44 } 45 46 PostgreSQLParameters()47 PostgreSQLParameters::PostgreSQLParameters() 48 { 49 Reset(); 50 } 51 52 PostgreSQLParameters(const OrthancPlugins::OrthancConfiguration & configuration)53 PostgreSQLParameters::PostgreSQLParameters(const OrthancPlugins::OrthancConfiguration& configuration) 54 { 55 Reset(); 56 57 std::string s; 58 59 if (configuration.LookupStringValue(s, "ConnectionUri")) 60 { 61 SetConnectionUri(s); 62 } 63 else 64 { 65 if (configuration.LookupStringValue(s, "Host")) 66 { 67 SetHost(s); 68 } 69 70 unsigned int port; 71 if (configuration.LookupUnsignedIntegerValue(port, "Port")) 72 { 73 SetPortNumber(port); 74 } 75 76 if (configuration.LookupStringValue(s, "Database")) 77 { 78 SetDatabase(s); 79 } 80 81 if (configuration.LookupStringValue(s, "Username")) 82 { 83 SetUsername(s); 84 } 85 86 if (configuration.LookupStringValue(s, "Password")) 87 { 88 SetPassword(s); 89 } 90 91 ssl_ = configuration.GetBooleanValue("EnableSsl", false); 92 } 93 94 lock_ = configuration.GetBooleanValue("Lock", true); // Use locking by default 95 96 maxConnectionRetries_ = configuration.GetUnsignedIntegerValue("MaximumConnectionRetries", 10); 97 connectionRetryInterval_ = configuration.GetUnsignedIntegerValue("ConnectionRetryInterval", 5); 98 } 99 100 SetConnectionUri(const std::string & uri)101 void PostgreSQLParameters::SetConnectionUri(const std::string& uri) 102 { 103 uri_ = uri; 104 } 105 106 GetConnectionUri() const107 std::string PostgreSQLParameters::GetConnectionUri() const 108 { 109 if (uri_.empty()) 110 { 111 std::string actualUri = "postgresql://"; 112 113 if (!username_.empty()) 114 { 115 actualUri += username_; 116 117 if (!password_.empty()) 118 { 119 actualUri += ":" + password_; 120 } 121 122 actualUri += "@" + host_; 123 } 124 else 125 { 126 actualUri += host_; 127 } 128 129 if (port_ > 0) 130 { 131 actualUri += ":" + boost::lexical_cast<std::string>(port_); 132 } 133 134 actualUri += "/" + database_; 135 136 return actualUri; 137 } 138 else 139 { 140 return uri_; 141 } 142 } 143 144 SetHost(const std::string & host)145 void PostgreSQLParameters::SetHost(const std::string& host) 146 { 147 uri_.clear(); 148 host_ = host; 149 } 150 SetPortNumber(unsigned int port)151 void PostgreSQLParameters::SetPortNumber(unsigned int port) 152 { 153 if (port == 0 || 154 port >= 65535) 155 { 156 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); 157 } 158 159 uri_.clear(); 160 port_ = port; 161 } 162 SetUsername(const std::string & username)163 void PostgreSQLParameters::SetUsername(const std::string& username) 164 { 165 uri_.clear(); 166 username_ = username; 167 } 168 SetPassword(const std::string & password)169 void PostgreSQLParameters::SetPassword(const std::string& password) 170 { 171 uri_.clear(); 172 password_ = password; 173 } 174 SetDatabase(const std::string & database)175 void PostgreSQLParameters::SetDatabase(const std::string& database) 176 { 177 uri_.clear(); 178 database_ = database; 179 } 180 Format(std::string & target) const181 void PostgreSQLParameters::Format(std::string& target) const 182 { 183 if (uri_.empty()) 184 { 185 // Note about SSL: "require" means that "I want my data to be 186 // encrypted, and I accept the overhead. I trust that the 187 // network will make sure I always connect to the server I want." 188 // https://www.postgresql.org/docs/current/libpq-ssl.html 189 target = std::string(ssl_ ? "sslmode=require" : "sslmode=disable") + 190 " user=" + username_ + 191 " host=" + host_ + 192 " port=" + boost::lexical_cast<std::string>(port_); 193 194 if (!password_.empty()) 195 { 196 target += " password=" + password_; 197 } 198 199 if (database_.size() > 0) 200 { 201 target += " dbname=" + database_; 202 } 203 } 204 else 205 { 206 target = uri_; 207 } 208 } 209 } 210