Add adminCheck() method prototype in admin Logic
[platform/core/security/cynara.git] / src / admin / api / admin-api.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        admin-api.cpp
18  * @author      Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
19  * @version     1.0
20  * @brief       Implementation of external libcynara-admin API
21  */
22
23 #include <map>
24 #include <new>
25 #include <stdexcept>
26 #include <string>
27 #include <string.h>
28 #include <vector>
29
30 #include <common.h>
31 #include <log/log.h>
32 #include <types/Policy.h>
33 #include <types/PolicyBucket.h>
34 #include <types/PolicyBucketId.h>
35 #include <types/PolicyKey.h>
36 #include <types/PolicyResult.h>
37 #include <types/PolicyType.h>
38
39 #include <cynara-admin.h>
40 #include <cynara-admin-error.h>
41
42 #include <api/ApiInterface.h>
43 #include <logic/Logic.h>
44
45 struct cynara_admin {
46     Cynara::ApiInterface *impl;
47
48     cynara_admin(Cynara::ApiInterface *_impl) : impl(_impl) {
49     }
50     ~cynara_admin() {
51         delete impl;
52     }
53 };
54
55 CYNARA_API
56 int cynara_admin_initialize(struct cynara_admin **pp_cynara_admin) {
57     if (!pp_cynara_admin)
58         return CYNARA_ADMIN_API_INVALID_PARAM;
59
60     try {
61         *pp_cynara_admin = new cynara_admin(new Cynara::Logic);
62     } catch (const std::bad_alloc &ex) {
63         return CYNARA_ADMIN_API_OUT_OF_MEMORY;
64     }
65
66     init_log();
67
68     LOGD("Cynara admin initialized");
69
70     return CYNARA_ADMIN_API_SUCCESS;
71 }
72
73 CYNARA_API
74 int cynara_admin_finish(struct cynara_admin *p_cynara_admin) {
75     delete p_cynara_admin;
76
77     return CYNARA_ADMIN_API_SUCCESS;
78 }
79
80 CYNARA_API
81 int cynara_admin_set_policies(struct cynara_admin *p_cynara_admin,
82                               const struct cynara_admin_policy *const *policies) {
83     if (!p_cynara_admin || !p_cynara_admin->impl)
84         return CYNARA_ADMIN_API_INVALID_PARAM;
85     if (!policies)
86         return CYNARA_ADMIN_API_INVALID_PARAM;
87
88     std::map<Cynara::PolicyBucketId, std::vector<Cynara::Policy>> insertOrUpdate;
89     std::map<Cynara::PolicyBucketId, std::vector<Cynara::PolicyKey>> remove;
90
91     auto key = ([](const cynara_admin_policy *policy)->Cynara::PolicyKey {
92         std::string wildcard(CYNARA_ADMIN_WILDCARD);
93
94         auto feature = ([&wildcard] (const char *str)->Cynara::PolicyKeyFeature {
95             if (wildcard.compare(str))
96                 return Cynara::PolicyKeyFeature::create(str);
97             else
98                 return Cynara::PolicyKeyFeature::createWildcard();
99         });
100
101         return Cynara::PolicyKey(feature(policy->client), feature(policy->user),
102                                  feature(policy->privilege));
103     });
104
105     try {
106         for (auto i = policies; *i; i++) {
107             const cynara_admin_policy *policy = *i;
108             if(!policy->bucket || !policy->client || !policy->user || !policy->privilege)
109                 return CYNARA_ADMIN_API_INVALID_PARAM;
110
111             switch (policy->result) {
112                 case CYNARA_ADMIN_DELETE:
113                     remove[policy->bucket].push_back(key(policy));
114                     break;
115                 case CYNARA_ADMIN_DENY:
116                     insertOrUpdate[policy->bucket].push_back(Cynara::Policy(key(policy),
117                                                         Cynara::PredefinedPolicyType::DENY));
118                     break;
119                 case CYNARA_ADMIN_ALLOW:
120                     insertOrUpdate[policy->bucket].push_back(Cynara::Policy(key(policy),
121                                                         Cynara::PredefinedPolicyType::ALLOW));
122                     break;
123                 case CYNARA_ADMIN_BUCKET:
124                     if (!policy->result_extra)
125                         return CYNARA_ADMIN_API_INVALID_PARAM;
126                     insertOrUpdate[policy->bucket].push_back(Cynara::Policy(key(policy),
127                                                         Cynara::PolicyResult(
128                                                         Cynara::PredefinedPolicyType::BUCKET,
129                                                         policy->result_extra)));
130                     break;
131                 case CYNARA_ADMIN_NONE:
132                 default:
133                     return CYNARA_ADMIN_API_INVALID_PARAM;
134             }
135         }
136     } catch (const std::bad_alloc &ex) {
137         return CYNARA_ADMIN_API_OUT_OF_MEMORY;
138     }
139
140     return p_cynara_admin->impl->setPolicies(insertOrUpdate, remove);
141 }
142
143 CYNARA_API
144 int cynara_admin_set_bucket(struct cynara_admin *p_cynara_admin, const char *bucket,
145                             int operation, const char *extra) {
146     if (!p_cynara_admin || !p_cynara_admin->impl)
147         return CYNARA_ADMIN_API_INVALID_PARAM;
148     if (!bucket)
149         return CYNARA_ADMIN_API_INVALID_PARAM;
150
151     std::string extraStr;
152     try {
153          extraStr = extra ? extra : "";
154     } catch (const std::bad_alloc &ex) {
155         return CYNARA_ADMIN_API_OUT_OF_MEMORY;
156     }
157     switch (operation) {
158         case CYNARA_ADMIN_DELETE:
159             return p_cynara_admin->impl->removeBucket(bucket);
160         case CYNARA_ADMIN_DENY:
161             return p_cynara_admin->impl->insertOrUpdateBucket(bucket,
162                 Cynara::PolicyResult(Cynara::PredefinedPolicyType::DENY, extraStr));
163         case CYNARA_ADMIN_ALLOW:
164             return p_cynara_admin->impl->insertOrUpdateBucket(bucket,
165                 Cynara::PolicyResult(Cynara::PredefinedPolicyType::ALLOW, extraStr));
166         case CYNARA_ADMIN_NONE:
167             if (bucket != Cynara::defaultPolicyBucketId) {
168                 return p_cynara_admin->impl->insertOrUpdateBucket(bucket,
169                     Cynara::PolicyResult(Cynara::PredefinedPolicyType::NONE));
170             }
171             return CYNARA_ADMIN_API_OPERATION_NOT_ALLOWED;
172         case CYNARA_ADMIN_BUCKET:
173         default:
174             return CYNARA_ADMIN_API_INVALID_PARAM;
175     }
176 }
177
178 CYNARA_API
179 int cynara_admin_check(struct cynara_admin *p_cynara_admin,
180                        const char *start_bucket, const int recursive,
181                        const char *client, const char *user, const char *privilege,
182                        int *result, char **result_extra) {
183     if (!p_cynara_admin || !p_cynara_admin->impl)
184         return CYNARA_ADMIN_API_INVALID_PARAM;
185     if (!start_bucket)
186         return CYNARA_ADMIN_API_INVALID_PARAM;
187     if (!client || !user || !privilege)
188         return CYNARA_ADMIN_API_INVALID_PARAM;
189     if (!result || !result_extra)
190         return CYNARA_ADMIN_API_INVALID_PARAM;
191
192     Cynara::PolicyResult policyResult;
193
194     try {
195         int ret = p_cynara_admin->impl->adminCheck(start_bucket, recursive != 0,
196                                                    Cynara::PolicyKey(client, user, privilege),
197                                                    policyResult);
198         if (ret != CYNARA_ADMIN_API_SUCCESS)
199             return ret;
200     } catch (const std::bad_alloc &ex) {
201         return CYNARA_ADMIN_API_OUT_OF_MEMORY;
202     } catch (const std::length_error &ex) {
203         return CYNARA_ADMIN_API_INVALID_PARAM;
204     }
205
206     char *str = nullptr;
207     if (!policyResult.metadata().empty()) {
208         str = strdup(policyResult.metadata().c_str());
209         if (!str)
210             return CYNARA_ADMIN_API_OUT_OF_MEMORY;
211     }
212     *result = static_cast<int>(policyResult.policyType());
213     *result_extra = str;
214
215     return CYNARA_ADMIN_API_SUCCESS;
216 }