89c2d2cd0e0bc8c475b850636924bd7ae3cdae13
[platform/core/security/cynara.git] / src / admin / logic / Logic.cpp
1 /*
2  *  Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License
15  */
16 /**
17  * @file        src/admin/logic/Logic.cpp
18  * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
19  * @version     1.0
20  * @brief       This file contains implementation of Logic class - main libcynara-admin class
21  */
22
23 #include <cinttypes>
24 #include <memory>
25
26 #include <cynara-admin-error.h>
27 #include <common.h>
28 #include <exceptions/ServerConnectionErrorException.h>
29 #include <log/log.h>
30 #include <protocol/Protocol.h>
31 #include <protocol/ProtocolAdmin.h>
32 #include <request/AdminCheckRequest.h>
33 #include <request/InsertOrUpdateBucketRequest.h>
34 #include <request/pointers.h>
35 #include <request/RemoveBucketRequest.h>
36 #include <request/SetPoliciesRequest.h>
37 #include <response/CheckResponse.h>
38 #include <response/CodeResponse.h>
39 #include <response/pointers.h>
40 #include <sockets/SocketClient.h>
41 #include <sockets/SocketPath.h>
42 #include <types/ProtocolFields.h>
43
44 #include "Logic.h"
45
46 namespace Cynara {
47
48 Logic::Logic() {
49     m_socketClient = std::make_shared<SocketClient>(SocketPath::admin,
50                                                     std::make_shared<ProtocolAdmin>());
51 }
52
53 ProtocolFrameSequenceNumber generateSequenceNumber(void) {
54     static ProtocolFrameSequenceNumber sequenceNumber = 0;
55     return ++sequenceNumber;
56 }
57
58 template<typename T, typename... Args>
59 int Logic::askCynaraAndInterpreteCodeResponse(Args... args) {
60     ProtocolFrameSequenceNumber sequenceNumber = generateSequenceNumber();
61
62     //Ask cynara service
63     CodeResponsePtr codeResponse;
64     try {
65         RequestPtr request = std::make_shared<T>(args..., sequenceNumber);
66         ResponsePtr response = m_socketClient->askCynaraServer(request);
67         if (!response) {
68             LOGW("Disconnected by cynara server.");
69             return CYNARA_ADMIN_API_SERVICE_NOT_AVAILABLE;
70         }
71         codeResponse = std::dynamic_pointer_cast<CodeResponse>(response);
72         if (!codeResponse) {
73             LOGC("Critical error. Casting Response to CodeResponse failed.");
74             return CYNARA_ADMIN_API_UNEXPECTED_CLIENT_ERROR;
75         }
76
77         LOGD("codeResponse: code [%" PRIu16 "]", codeResponse->m_code);
78         switch (codeResponse->m_code) {
79             case CodeResponse::Code::OK:
80                 LOGI("Policies set successfully.");
81                 return CYNARA_ADMIN_API_SUCCESS;
82             case CodeResponse::Code::NOT_ALLOWED:
83                 LOGE("Cynara service answered: Operation not allowed.");
84                 return CYNARA_ADMIN_API_OPERATION_NOT_ALLOWED;
85             case CodeResponse::Code::NO_BUCKET:
86                 LOGE("Trying to use unexisting bucket.");
87                 return CYNARA_ADMIN_API_BUCKET_NOT_FOUND;
88             default:
89                 LOGE("Unexpected response code from server: [%d]",
90                      static_cast<int>(codeResponse->m_code));
91                 return CYNARA_ADMIN_API_UNEXPECTED_CLIENT_ERROR;
92         }
93     } catch (const ServerConnectionErrorException &ex) {
94         LOGE("Cynara service not available.");
95         return CYNARA_ADMIN_API_SERVICE_NOT_AVAILABLE;
96     } catch (const std::bad_alloc &ex) {
97         LOGE("Cynara admin client out of memory.");
98         return CYNARA_ADMIN_API_OUT_OF_MEMORY;
99     } catch (const std::exception &ex) {
100         LOGE("Unexpected client error: <%s>", ex.what());
101         return CYNARA_ADMIN_API_UNEXPECTED_CLIENT_ERROR;
102     }
103 }
104
105 int Logic::setPolicies(const std::map<PolicyBucketId, std::vector<Policy>> &insertOrUpdate,
106                 const std::map<PolicyBucketId, std::vector<PolicyKey>> &remove) noexcept {
107     return askCynaraAndInterpreteCodeResponse<SetPoliciesRequest>(insertOrUpdate, remove);
108 }
109
110 int Logic::insertOrUpdateBucket(const PolicyBucketId &bucket,
111                                 const PolicyResult &policyResult) noexcept {
112     return askCynaraAndInterpreteCodeResponse<InsertOrUpdateBucketRequest>(bucket, policyResult);
113 }
114
115 int Logic::removeBucket(const PolicyBucketId &bucket) noexcept {
116     return askCynaraAndInterpreteCodeResponse<RemoveBucketRequest>(bucket);
117 }
118
119 int Logic::adminCheck(const PolicyBucketId &startBucket, bool recursive, const PolicyKey &key,
120                       PolicyResult &result) noexcept {
121
122     ProtocolFrameSequenceNumber sequenceNumber = generateSequenceNumber();
123
124     //Ask cynara service
125     CheckResponsePtr checkResponse;
126     try {
127         RequestPtr request = std::make_shared<AdminCheckRequest>(key, startBucket, recursive,
128                                                                  sequenceNumber);
129         ResponsePtr response = m_socketClient->askCynaraServer(request);
130         if (!response) {
131             LOGW("Disconnected by cynara server.");
132             return CYNARA_ADMIN_API_SERVICE_NOT_AVAILABLE;
133         }
134         checkResponse = std::dynamic_pointer_cast<CheckResponse>(response);
135         if (!checkResponse) {
136             LOGC("Casting Response to CheckResponse failed.");
137             return CYNARA_ADMIN_API_UNEXPECTED_CLIENT_ERROR;
138         }
139
140         LOGD("checkResponse: policyType [%" PRIu16 "], metadata <%s>",
141              checkResponse->m_resultRef.policyType(),
142              checkResponse->m_resultRef.metadata().c_str());
143     } catch (const ServerConnectionErrorException &ex) {
144         LOGE("Cynara service not available.");
145         return CYNARA_ADMIN_API_SERVICE_NOT_AVAILABLE;
146     } catch (const std::bad_alloc &ex) {
147         LOGE("Cynara admin client out of memory.");
148         return CYNARA_ADMIN_API_OUT_OF_MEMORY;
149     } catch (const std::exception &ex) {
150         LOGE("Unexpected client error: <%s>", ex.what());
151         return CYNARA_ADMIN_API_UNEXPECTED_CLIENT_ERROR;
152     }
153
154     result = checkResponse->m_resultRef;
155     return CYNARA_ADMIN_API_SUCCESS;
156 }
157
158 } // namespace Cynara