~aleteoryx/muditaos

ref: c58c8568d31deca7c3ccf403986a266ee676c0c0 muditaos/module-services/service-desktop/endpoints/security/SecurityEndpointHelper.cpp -rw-r--r-- 2.8 KiB
c58c8568 — Pawel Olejniczak [CP-143] Set 204 code for responses with empty body 4 years ago
                                                                                
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
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "SecurityEndpointHelper.hpp"
#include <parser/ParserUtils.hpp>
#include <service-appmgr/model/ApplicationManager.hpp>
#include <service-appmgr/messages/PreventBlockingRequest.hpp>
#include <service-desktop/service-desktop/ServiceDesktop.hpp>
#include <module-apps/locks/data/PhoneLockMessages.hpp>
#include <json11.hpp>

namespace parserFSM
{
    class Context;
} // namespace parserFSM

using namespace parserFSM;

auto SecurityEndpointHelper::preventBlockingDevice() -> bool
{
    auto desktopService = dynamic_cast<ServiceDesktop *>(owner);
    auto msg            = std::make_shared<app::manager::PreventBlockingRequest>(desktopService->GetName());
    return desktopService->bus.sendUnicast(std::move(msg), "ApplicationManager");
}

auto SecurityEndpointHelper::processPut(Context &context) -> ProcessResult
{
    auto code = processConfiguration(context);
    return {sent::no, endpoint::ResponseContext{.status = code}};
}

auto SecurityEndpointHelper::processGet(Context &context) -> ProcessResult
{
    auto code = processStatus(context);
    return {sent::no, endpoint::ResponseContext{.status = code}};
}

auto SecurityEndpointHelper::processStatus(Context &context) -> http::Code
{
    auto desktopService = dynamic_cast<ServiceDesktop *>(owner);
    auto security       = desktopService->getSecurity()->getEndpointSecurity();

    if (security == EndpointSecurity::Allow) {
        preventBlockingDevice();
    }

    return security == EndpointSecurity::Allow ? http::Code::NoContent : http::Code::Forbidden;
}

auto SecurityEndpointHelper::passCodeArrayToVecOfInts(const json11::Json::array &passCode) -> std::vector<unsigned int>
{
    std::vector<unsigned int> passCodeAsInts(0, 0);

    for (const auto &value : passCode) {
        if (value.is_number()) {
            auto v = value.number_value();
            passCodeAsInts.push_back(v);
        }
        else {
            throw std::invalid_argument("value not a digit");
        }
    }

    return passCodeAsInts;
}

auto SecurityEndpointHelper::processConfiguration(Context &context) -> http::Code
{
    auto body     = context.getBody();
    auto passCode = body[json::usb::phoneLockCode].array_items();
    http::Code status{http::Code::BadRequest};

    if (passCode.size() == PasscodeLength) {
        try {
            auto msg = std::make_shared<locks::ExternalUnLockPhone>(passCodeArrayToVecOfInts(passCode));
            status   = owner->bus.sendUnicast(std::move(msg), app::manager::ApplicationManager::ServiceName)
                         ? http::Code::NoContent
                         : http::Code::InternalServerError;
        }
        catch (const std::exception &e) {
            LOG_ERROR("Passcode decoding exception: %s", e.what());
        }
    }

    return status;
}