aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/qlicenseservice/clienthandler.cpp
blob: 8ecb6c521e0a7a9d6e165973aa590e5023deae61 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
/* Copyright (C) 2022 The Qt Company Ltd.
 *
 * SPDX-License-Identifier: GPL-3.0-only WITH Qt-GPL-exception-1.0
*/

#include "clienthandler.h"

#include "jsonhandler.h"
#include "utils.h"

namespace QLicenseService {

bool ClientHandler::checkLicenseExpiryTime(std::string &reply)
{
    if (m_floatingLicense) {
        // No checking from stored files in case of floating license
        return false;
    }
    std::cout << "Offline - checking validity from license file " << m_request.licenseFile << std::endl;
    // Open the license file
    std::string data;
    if (utils::readFile(data, m_request.licenseFile) != 0) {
        std::cout << "No license file - rejecting license " << m_request.licenseFile << std::endl;
        reply = replyString[e_bad_connection];
        return false;
    }
    JsonHandler license(data);
    // Check license status
    if (license.get("status") != "true") {
        std::cout << "License status = false: Rejecting license\n";
        reply = replyString[e_bad_connection];
        return false;
    }
    // Expiry date. Add 1 day to expiry date to get the end actually at the beginning of the next day
    std::string expDate = license.get("expiry_date");
    std::time_t expEpoch = utils::stringToEpoch(expDate.c_str()) + SECS_IN_DAY;
    // Current date
    std::time_t current = std::time(0);
    // See if the time has expire
    if (current > expEpoch) {
        // Store the leeway time if applicable
        if (license.get("leeway_hours") != "") {
            m_license.leeway_hours = license.getInt("leeway_hours");
            m_license.current_timestamp = current;
            m_license.expiry_epoch = expEpoch;
        }
        return false;
    }
    std::cout << "License granted, expires at " << expDate << std::endl;
    reply = replyString[e_license_granted];
    return true;
}

int ClientHandler::parseRequest()
{
    // First find out the command, and drop it out from the list
    std::string cmd = utils::trimStr(params[0]);
    params.erase(params.begin());

    m_request.reqType = RequestType::no_request;
    if (cmd == LICENSE_REQUEST_CMD) {
        m_request.reqType = RequestType::license_request;
    } else if (cmd ==PERMANENT_REQUEST_CMD) {
        m_request.reqType = RequestType::long_term_request;
        // find either 'add' or 'remove'
        if (params.size() > 0) {
            if (params[0] != OP_ADD_RESERVATION && params[0] != OP_REMOVE_RESERVATION) {
                std::cout << "Invalid operation for permanent request: " << params[0] << std::endl;
                return e_bad_request;
            }
            m_request.operation = params[0];
        } else {
            std::cout << "No operation for permanent request: 'add' or 'remove' needed\n";
            return e_bad_request;
        }

        // Found and operation: Not needed in the list any more
        params.erase(params.begin());
    } else if (cmd == SERVER_VERSION_CMD) {
        m_request.reqType = RequestType::server_version;
        buildRequestJson();
        return 0;
    } else if (cmd == DAEMON_VERSION_CMD) {
        m_request.reqType = RequestType::daemon_version;
    } else if (cmd == RESERVATION_QUERY_CMD) {
        m_request.reqType = RequestType::reservation_query;
    } else {
        std::cout << "Invalid command: " << cmd << std::endl;
        return e_bad_request;
    }

    bool argFound = false;
    std::string arg;
    for (const std::string &item : params) {
        if (item.empty()) {
            continue;
        }
        if (!argFound) {
            if (item[0] == '-') {
                arg = item;
                argFound = true;
                continue;
            }
            else {
                std::cout << "Not a valid argument: \"" << item << "\"\n";
                return e_bad_request;
            }
        } else {
            if (arg == "-a") m_request.appName = utils::strToLower(item);
            else if (arg == "-v") m_request.appVersion = item;
            else if (arg == "-u") m_request.userId = item;
            else if (arg == "-i") m_request.licenseId = item;
            else if (arg == "-p") m_request.parentReservationId = item;
            else if (arg == "-r") m_request.runnerType = item;
            else if (arg == "-e") m_request.email = item;
            else if (arg == "-l") m_request.serverAddr = item;
            else {
                std::cout << "Invalid argument: \"" << arg << "\"\n";
                return e_bad_request;
            }
            argFound = false;
            arg = "";
        }
    }
    // Check if we're run out of items in argument list without getting the value:
    if (argFound) {
        std::cout << "No value for argument: \"" << arg << "\"\n";
        return e_bad_request;
    }

    if (!m_request.parentReservationId.empty()) {
        m_hasParent = true;
    }

    std::stringstream ss;
    ss <<  WORKING_DIR  << DIR_SEPARATOR << LICENSE_FILE_PREFIX;
    ss << m_request.userId << "_" << m_request.licenseId << LICENSE_FILE_EXTENSION;
    m_request.licenseFile += ss.str();
    buildRequestJson();
    return 0;
}

bool ClientHandler::checkLeewayTime(std::string &reply)
{
    // Leeway time granted?
    if (m_license.leeway_hours == 0) {
        return false;
    }
    // License expired and offline: Allow some leeway time
    int leewayTimeLeft = m_license.expiry_epoch + (m_license.leeway_hours * SECS_IN_HOUR) - m_license.current_timestamp;
    if (leewayTimeLeft > 0) {
        std::stringstream ss;
        ss << replyString[e_no_conn_leeway]
            << std::fixed << std::setprecision(1)
            << (float)leewayTimeLeft / SECS_IN_DAY << " days";
        reply = ss.str();
        return true;
    }
    return false;
}

void ClientHandler::updateLicense(const std::string &responseJson)
{
    JsonHandler json(responseJson);
    m_license.status = json.getBool("status");
    m_license.message = json.get("message");
    m_license.leeway_hours = json.getInt("leeway_hours");
    m_license.last_timestamp = utils::getTimestampNow();
    m_license.expiry_date = json.get("expiry_date");
    m_license.license_key = json.get("license_key");
    m_license.license_id = json.get("license_number");
    m_license.reservation_id = json.get("reservation_id");
    m_license.user_id = json.get("user_id");
}

void ClientHandler::addChildClient(ClientHandler *client)
{
    m_childClients[client->getSocketId()] = client;
}

void ClientHandler::removeCachedFile() {
    utils::deleteFile(m_request.licenseFile);
}

void ClientHandler::resetTime()
{
    m_license.last_timestamp = utils::getTimestampNow();
}

bool ClientHandler::removeChildClient(uint16_t socketId)
{
    if (m_childClients.find(socketId) != m_childClients.end()) {
        ClientHandler *client = m_childClients[socketId];
        m_childClients.erase(socketId);
        delete client;
        return true;
    }
    return false;
}

bool ClientHandler::clientInStorage(uint16_t socketId)
{
    if (m_childClients.find(socketId) != m_childClients.end()) {
        return true;
    }
    return false;
}

} // namespace QLicenseService