mirror of
https://github.com/mudita/MuditaOS.git
synced 2026-04-23 08:33:48 -04:00
To allow the automation of gathering logs and swapping out OS images during tests a MSC reboot endpoint was added. Together with a change to ecoboot, this allows the sending of a "reboot to MSC" command. The deivce will then reboot and enter MSC mode.
124 lines
4.9 KiB
C++
124 lines
4.9 KiB
C++
// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved.
|
|
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
|
|
|
|
#include <endpoints/security/SecurityEndpointHelper.hpp>
|
|
#include <endpoints/message/Sender.hpp>
|
|
#include <endpoints/JsonKeyNames.hpp>
|
|
#include <service-appmgr/ServiceApplicationManagerName.hpp>
|
|
#include <service-appmgr/messages/PreventBlockingRequest.hpp>
|
|
#include <service-desktop/ServiceDesktop.hpp>
|
|
#include <apps-common/locks/data/PhoneLockMessages.hpp>
|
|
|
|
namespace sdesktop::endpoints
|
|
{
|
|
using sender::putToSendQueue;
|
|
|
|
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, ResponseContext{.status = code}};
|
|
}
|
|
|
|
auto SecurityEndpointHelper::processGet(Context &context) -> ProcessResult
|
|
{
|
|
if (context.getBody()[json::messages::category].string_value() == json::usb::phoneLockStatus) {
|
|
return {sent::no, processStatus(context)};
|
|
}
|
|
if (context.getBody()[json::messages::category].string_value() == json::usb::phoneLockTime) {
|
|
if (auto phoneLockTime = getPhoneLockTime(context); phoneLockTime > std::time(nullptr)) {
|
|
auto timeLeftToNextAttempt = phoneLockTime - std::time(nullptr);
|
|
context.setResponseBody(json11::Json::object(
|
|
{{json::usb::phoneLockTime, static_cast<int>(phoneLockTime)},
|
|
{json::usb::timeLeftToNextAttempt, static_cast<int>(timeLeftToNextAttempt)}}));
|
|
context.setResponseStatus(http::Code::OK);
|
|
}
|
|
else {
|
|
context.setResponseStatus(http::Code::UnprocessableEntity);
|
|
}
|
|
putToSendQueue(context.createSimpleResponse());
|
|
return {sent::yes, std::nullopt};
|
|
}
|
|
return {sent::no, ResponseContext{.status = http::Code::BadRequest}};
|
|
}
|
|
|
|
auto SecurityEndpointHelper::processStatus(Context & /*context*/) -> ResponseContext
|
|
{
|
|
auto desktopService = dynamic_cast<ServiceDesktop *>(owner);
|
|
auto security = desktopService->getSecurity()->getEndpointSecurity();
|
|
ResponseContext responseContext{};
|
|
|
|
if (security.access == EndpointSecurity::Allow) {
|
|
preventBlockingDevice();
|
|
responseContext.status = http::Code::NoContent;
|
|
}
|
|
else {
|
|
switch (security.reason) {
|
|
case BlockReason::NoReason:
|
|
case BlockReason::DeviceLocked:
|
|
responseContext.status = http::Code::Forbidden;
|
|
break;
|
|
case BlockReason::OnboardingNotFinished:
|
|
case BlockReason::BatteryCriticalLevel:
|
|
responseContext.status = http::Code::Locked;
|
|
responseContext.body =
|
|
json11::Json::object({{json::common::reason, std::to_string(static_cast<int>(security.reason))}});
|
|
break;
|
|
}
|
|
}
|
|
return responseContext;
|
|
}
|
|
|
|
auto SecurityEndpointHelper::getPhoneLockTime(Context & /*context*/) -> time_t
|
|
{
|
|
auto desktopService = static_cast<ServiceDesktop *>(owner);
|
|
return desktopService->getSecurity()->getPhoneLockTime();
|
|
}
|
|
|
|
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), service::name::appmgr)
|
|
? http::Code::NoContent
|
|
: http::Code::InternalServerError;
|
|
}
|
|
catch (const std::exception &e) {
|
|
LOG_ERROR("Passcode decoding exception");
|
|
}
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
} // namespace sdesktop::endpoints
|