2.12.2021, 9:00 - 11:00: Due to updates GitLab may be unavailable for some minutes between 09:00 and 11:00.

globalconfiguration.cpp 8.78 KB
Newer Older
1
2
3
//================================================================================
// Name        : globalconfiguration.cpp
// Author      : Alessio Netti
Micha Müller's avatar
Micha Müller committed
4
// Contact     : info@dcdb.it
5
6
7
8
9
10
11
12
13
14
15
16
// Copyright   : Leibniz Supercomputing Centre
// Description : Common functionality implementation for reading in configuration files.
//================================================================================

//================================================================================
// This file is part of DCDB (DataCenter DataBase)
// Copyright (C) 2019-2019 Leibniz Supercomputing Centre
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
Alessio Netti's avatar
Alessio Netti committed
17
//
18
19
20
21
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
Alessio Netti's avatar
Alessio Netti committed
22
//
23
24
25
26
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
//================================================================================
Alessio Netti's avatar
Alessio Netti committed
27
28

#include "globalconfiguration.h"
29
#include "RESTHttpsServer.h"
30
#include "boost/filesystem.hpp"
Alessio Netti's avatar
Alessio Netti committed
31
32

GlobalConfiguration::GlobalConfiguration(const std::string& cfgFilePath, const std::string& cfgFileName) {
33
34
35
36
37
38
39
40
41
42
43
44
45
46
    boost::filesystem::path p(cfgFilePath);
    if (boost::filesystem::exists(p)) {
	if (boost::filesystem::is_directory(p)) {
	    this->cfgFileName = cfgFileName;
	    this->cfgFilePath = cfgFilePath;
	} else {
	    this->cfgFileName = p.filename().native();
	    this->cfgFilePath = p.parent_path().native();
	}
	if (this->cfgFilePath[this->cfgFilePath.length()-1] != '/')
	    this->cfgFilePath.append("/");
    } else {
	throw std::runtime_error(cfgFilePath + " does not exist");
    }
Alessio Netti's avatar
Alessio Netti committed
47
48
}

49
void GlobalConfiguration::readConfig() {
Alessio Netti's avatar
Alessio Netti committed
50
    // Open file
51
52
    std::string globalConfig = cfgFilePath;
    globalConfig.append(cfgFileName);
Alessio Netti's avatar
Alessio Netti committed
53
54
55
56
57
    boost::property_tree::iptree cfg;
    // Parse to property_tree
    try {
        boost::property_tree::read_info(globalConfig, cfg);
    } catch (boost::property_tree::info_parser_error& e) {
58
        throw std::runtime_error("Error when parsing " + globalConfig + ": " + e.what());
Alessio Netti's avatar
Alessio Netti committed
59
60
61
62
63
    }
    
    BOOST_FOREACH(boost::property_tree::iptree::value_type &global, cfg.get_child("global")) {
        // ----- READING PLUGIN SETTINGS -----
        if (boost::iequals(global.first, "mqttprefix")) {
64
            pluginSettings.mqttPrefix = MQTTChecker::formatTopic(global.second.data());
65
66
        } else if (boost::iequals(global.first, "autoPublish")) {
            pluginSettings.autoPublish = to_bool(global.second.data());
Alessio Netti's avatar
Alessio Netti committed
67
68
69
70
71
72
73
74
75
76
77
78
79
80
        } else if (boost::iequals(global.first, "tempdir")) {
            pluginSettings.tempdir = global.second.data();
            if (pluginSettings.tempdir[pluginSettings.tempdir.length() - 1] != '/')
                pluginSettings.tempdir.append("/");
        } else if (boost::iequals(global.first, "cacheInterval")) {
            pluginSettings.cacheInterval = stoul(global.second.data()) * 1000;
        // ----- READING GLOBAL SETTINGS -----
        } else if (boost::iequals(global.first, "threads")) {
            threads = stoi(global.second.data());
        } else if (boost::iequals(global.first, "daemonize")) {
            daemonize = to_bool(global.second.data());
        } else if (boost::iequals(global.first, "validateConfig")) {
            validateConfig = to_bool(global.second.data());
        } else if (boost::iequals(global.first, "verbosity")) {
81
            logLevelFile = stoi(global.second.data());
82
83
        } else if (boost::iequals(global.first, "statisticsInterval")) {
            statisticsInterval = stoi(global.second.data());
84
85
	} else if (boost::iequals(global.first, "statisticsMqttPart")) {
	    statisticsMqttPart = MQTTChecker::formatTopic(global.second.data());
Alessio Netti's avatar
Alessio Netti committed
86
87
88
89
90
91
92
93
94
95
        } else if (!readAdditionalValues(global)) {
            LOG(warning) << "  Value \"" << global.first << "\" not recognized. Omitting";
        }
    }

    // ----- READING ANALYTICS SETTINGS -----
    if(cfg.find("analytics") != cfg.not_found()) {
        BOOST_FOREACH(boost::property_tree::iptree::value_type & global, cfg.get_child("analytics")) {
            if (boost::iequals(global.first, "hierarchy")) {
                analyticsSettings.hierarchy = global.second.data();
96
97
            } else if (boost::iequals(global.first, "filter")) {
                analyticsSettings.filter = global.second.data();
Alessio Netti's avatar
Alessio Netti committed
98
99
            } else if (boost::iequals(global.first, "jobFilter")) {
                analyticsSettings.jobFilter = global.second.data();
100
101
            } else if (boost::iequals(global.first, "jobMatch")) {
                analyticsSettings.jobMatch = global.second.data();
102
103
            } else if (boost::iequals(global.first, "jobIdFilter")) {
                analyticsSettings.jobIdFilter = global.second.data();
104
105
            } else if (boost::iequals(global.first, "jobDomainId")) {
                analyticsSettings.jobDomainId = global.second.data();
Alessio Netti's avatar
Alessio Netti committed
106
107
108
109
110
111
112
113
            } else {
                LOG(warning) << "  Value \"" << global.first << "\" not recognized. Omitting";
            }
        }
    }

    // ----- READING REST API SETTINGS -----
    if(cfg.find("restAPI") != cfg.not_found()) {
114
	restAPISettings.enabled = true;
Alessio Netti's avatar
Alessio Netti committed
115
116
        BOOST_FOREACH(boost::property_tree::iptree::value_type & global, cfg.get_child("restAPI")) {
            if (boost::iequals(global.first, "address")) {
117
118
                restAPISettings.host = global.second.data();
                size_t pos = restAPISettings.host.find(":");
Alessio Netti's avatar
Alessio Netti committed
119
                if (pos != std::string::npos) {
120
121
                    restAPISettings.port = restAPISettings.host.substr(pos + 1);
                    restAPISettings.host.erase(pos);
Alessio Netti's avatar
Alessio Netti committed
122
123
124
125
126
                }
            } else if (boost::iequals(global.first, "certificate")) {
                restAPISettings.certificate = global.second.data();
            } else if (boost::iequals(global.first, "privateKey")) {
                restAPISettings.privateKey = global.second.data();
127
            } else if (boost::iequals(global.first, "user")) {
Alessio Netti's avatar
Alessio Netti committed
128
129
130
131
132
133
134
135
                //Avoids unnecessary "Value not recognized" message
            } else {
                LOG(warning) << "  Value \"" << global.first << "\" not recognized. Omitting";
            }
        }
    }

    readAdditionalBlocks(cfg);
Alessio Netti's avatar
Alessio Netti committed
136
}
137
138
139

bool GlobalConfiguration::readRestAPIUsers(RESTHttpsServer* server) {
    //open file
140
141
    std::string globalConfig = cfgFilePath;
    globalConfig.append(cfgFileName);
142
143
144
145
146
147

    boost::property_tree::iptree cfg;
    //parse to property_tree
    try {
        boost::property_tree::read_info(globalConfig, cfg);
    } catch (boost::property_tree::info_parser_error& e) {
148
        LOG(error) << "Error when reading users from " << cfgFileName << ":" << e.what();
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
        return false;
    }

    //read users
    BOOST_FOREACH(boost::property_tree::iptree::value_type &global, cfg.get_child("restAPI")) {
        if (boost::iequals(global.first, "user")) {
            std::string username = global.second.data();
            userAttributes_t attributes;
#ifdef DEBUG
            LOG(info) << "Username: \"" << username << "\"";
#endif
            BOOST_FOREACH(boost::property_tree::iptree::value_type &perm, global.second) {
                if (boost::iequals(perm.first, "GET")) {
#ifdef DEBUG
                    LOG(info) << "  Permission \"GET\"";
#endif
                    attributes.second[GET] = true;
                } else if (boost::iequals(perm.first, "PUT")) {
#ifdef DEBUG
                    LOG(info) << "  Permission \"PUT\"";
#endif
170
                    attributes.second[PUT] = true;
171
172
173
174
175
                } else if (boost::iequals(perm.first, "POST")) {
#ifdef DEBUG
                    LOG(info) << "  Permission \"POST\"";
#endif
                    attributes.second[POST] = true;
176
177
178
179
180
181
182
183
184
185
186
                } else if (boost::iequals(perm.first, "password")) {
                    attributes.first = perm.second.data();
#ifdef DEBUG
                    LOG(info) << "  Password: \"" << attributes.first << "\"";
#endif
                } else {
#ifdef DEBUG
                    LOG(warning) << "Permission \"" << perm.first << "\" not recognized. Omitting";
#endif
                }
            }
187
	    if (attributes.first.size() != 40) {
188
189
		LOG(warning) << "User " << username << "'s password does not appear to be a sha1 hash!";
	    } else if (server->addUser(username, attributes)) {
190
191
192
193
194
195
196
197
                LOG(warning) << "User " << username << " already existed and was overwritten!";
            }
        } else {
            // do nothing and continue search for the user section
        }
    }
    return true;
}