globalconfiguration.cpp 8.47 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
64
    }
    
    BOOST_FOREACH(boost::property_tree::iptree::value_type &global, cfg.get_child("global")) {
        // ----- READING PLUGIN SETTINGS -----
        if (boost::iequals(global.first, "mqttprefix")) {
            pluginSettings.mqttPrefix = 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());
Alessio Netti's avatar
Alessio Netti committed
82
83
84
85
86
87
88
89
90
91
92
93
        } else if (boost::iequals(global.first, "statistics")) {
            statistics = to_bool(global.second.data());
        } 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();
94
95
            } else if (boost::iequals(global.first, "filter")) {
                analyticsSettings.filter = global.second.data();
Alessio Netti's avatar
Alessio Netti committed
96
97
            } else if (boost::iequals(global.first, "jobFilter")) {
                analyticsSettings.jobFilter = global.second.data();
98
99
            } else if (boost::iequals(global.first, "jobMatch")) {
                analyticsSettings.jobMatch = global.second.data();
100
101
            } else if (boost::iequals(global.first, "jobIdFilter")) {
                analyticsSettings.jobIdFilter = global.second.data();
Alessio Netti's avatar
Alessio Netti committed
102
103
104
105
106
107
108
109
            } else {
                LOG(warning) << "  Value \"" << global.first << "\" not recognized. Omitting";
            }
        }
    }

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

    readAdditionalBlocks(cfg);
Alessio Netti's avatar
Alessio Netti committed
132
}
133
134
135

bool GlobalConfiguration::readRestAPIUsers(RESTHttpsServer* server) {
    //open file
136
137
    std::string globalConfig = cfgFilePath;
    globalConfig.append(cfgFileName);
138
139
140
141
142
143

    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) {
144
        LOG(error) << "Error when reading users from " << cfgFileName << ":" << e.what();
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
        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
166
                    attributes.second[PUT] = true;
167
168
169
170
171
                } else if (boost::iequals(perm.first, "POST")) {
#ifdef DEBUG
                    LOG(info) << "  Permission \"POST\"";
#endif
                    attributes.second[POST] = true;
172
173
174
175
176
177
178
179
180
181
182
                } 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
                }
            }
183
	    if (attributes.first.size() != 40) {
184
185
		LOG(warning) << "User " << username << "'s password does not appear to be a sha1 hash!";
	    } else if (server->addUser(username, attributes)) {
186
187
188
189
190
191
192
193
                LOG(warning) << "User " << username << " already existed and was overwritten!";
            }
        } else {
            // do nothing and continue search for the user section
        }
    }
    return true;
}