return CYNARA_API_INVALID_PARAM;
}
cynara_check_id checkId;
- int ret = p_cynara->impl->createRequest(clientStr, clientSessionStr, userStr, privilegeStr,
- checkId, callback, user_response_data);
+ int ret = p_cynara->impl->createCheckRequest(clientStr, clientSessionStr, userStr,
+ privilegeStr, checkId, callback,
+ user_response_data);
+ if (p_check_id && ret == CYNARA_API_SUCCESS)
+ *p_check_id = checkId;
+ return ret;
+ });
+}
+
+CYNARA_API
+int cynara_async_create_simple_request(cynara_async *p_cynara, const char *client,
+ const char *client_session, const char *user,
+ const char *privilege, cynara_check_id *p_check_id,
+ cynara_response_callback callback, void *user_response_data){
+ if (!p_cynara || !p_cynara->impl)
+ return CYNARA_API_INVALID_PARAM;
+ if (!client || !client_session || !user || !privilege)
+ return CYNARA_API_INVALID_PARAM;
+
+ return Cynara::tryCatch([&]() {
+ std::string clientStr;
+ std::string clientSessionStr;
+ std::string userStr;
+ std::string privilegeStr;
+
+ try {
+ clientStr = client;
+ clientSessionStr = client_session;
+ userStr = user;
+ privilegeStr = privilege;
+ } catch (const std::length_error &e) {
+ LOGE("%s", e.what());
+ return CYNARA_API_INVALID_PARAM;
+ }
+ cynara_check_id checkId;
+ int ret = p_cynara->impl->createSimpleRequest(clientStr, clientSessionStr, userStr,
+ privilegeStr, checkId, callback,
+ user_response_data);
if (p_check_id && ret == CYNARA_API_SUCCESS)
*p_check_id = checkId;
return ret;
#include <protocol/ProtocolClient.h>
#include <request/CancelRequest.h>
#include <request/CheckRequest.h>
+#include <request/SimpleCheckRequest.h>
#include <response/CancelResponse.h>
#include <response/CheckResponse.h>
+#include <response/SimpleCheckResponse.h>
#include <sockets/Socket.h>
#include "Logic.h"
-
namespace Cynara {
Logic::Logic(cynara_status_callback callback, void *userStatusData, const Configuration &conf)
return m_cache->get(session, PolicyKey(client, user, privilege));
}
-int Logic::createRequest(const std::string &client, const std::string &session,
+int Logic::createCheckRequest(const std::string &client, const std::string &session,
+ const std::string &user, const std::string &privilege,
+ cynara_check_id &checkId, cynara_response_callback callback,
+ void *userResponseData) {
+ return createRequest(false, client, session, user, privilege, checkId, callback,
+ userResponseData);
+}
+
+int Logic::createSimpleRequest(const std::string &client, const std::string &session,
+ const std::string &user, const std::string &privilege,
+ cynara_check_id &checkId, cynara_response_callback callback,
+ void *userResponseData) {
+ return createRequest(true, client, session, user, privilege, checkId, callback,
+ userResponseData);
+}
+
+int Logic::createRequest(bool simple, const std::string &client, const std::string &session,
const std::string &user, const std::string &privilege,
cynara_check_id &checkId, cynara_response_callback callback,
void *userResponseData) {
PolicyKey key(client, user, privilege);
ResponseCallback responseCallback(callback, userResponseData);
- m_checks.insert(CheckPair(sequenceNumber, CheckData(key, session, responseCallback)));
- m_socketClient->appendRequest(std::make_shared<CheckRequest>(key, sequenceNumber));
+ m_checks.insert(CheckPair(sequenceNumber, CheckData(key, session, responseCallback,
+ simple)));
+ if (simple)
+ m_socketClient->appendRequest(std::make_shared<SimpleCheckRequest>(key, sequenceNumber));
+ else
+ m_socketClient->appendRequest(std::make_shared<CheckRequest>(key, sequenceNumber));
onStatusChange(m_socketClient->getSockFd(), cynara_async_status::CYNARA_STATUS_FOR_RW);
checkId = static_cast<cynara_check_id>(sequenceNumber);
m_sequenceContainer.release(it->first);
it = m_checks.erase(it);
} else {
- m_socketClient->appendRequest(std::make_shared<CheckRequest>(it->second.key(), it->first));
+ if (it->second.isSimple())
+ m_socketClient->appendRequest(std::make_shared<SimpleCheckRequest>(it->second.key(),
+ it->first));
+ else
+ m_socketClient->appendRequest(std::make_shared<CheckRequest>(it->second.key(),
+ it->first));
++it;
}
}
}
}
+Logic::CheckMap::iterator Logic::checkResponseValid(ResponsePtr response) {
+ auto it = m_checks.find(response->sequenceNumber());
+ if (it == m_checks.end()) {
+ LOGC("Critical error. Unknown checkResponse received: sequenceNumber = [%" PRIu16 "]",
+ response->sequenceNumber());
+ throw UnexpectedErrorException("Unexpected response from cynara service");
+ }
+ return it;
+}
+
+void Logic::releaseRequest(Logic::CheckMap::iterator reqIt) {
+ m_sequenceContainer.release(reqIt->first);
+ m_checks.erase(reqIt);
+}
+
void Logic::processCheckResponse(CheckResponsePtr checkResponse) {
LOGD("checkResponse: policyType = [%" PRIu16 "], metadata = <%s>",
checkResponse->m_resultRef.policyType(),
checkResponse->m_resultRef.metadata().c_str());
- auto it = m_checks.find(checkResponse->sequenceNumber());
- if (it == m_checks.end()) {
- LOGC("Critical error. Unknown checkResponse received: sequenceNumber = [%" PRIu16 "]",
- checkResponse->sequenceNumber());
- throw UnexpectedErrorException("Unexpected response from cynara service");
- }
+ auto it = checkResponseValid(checkResponse);
int result = m_cache->update(it->second.session(), it->second.key(),
checkResponse->m_resultRef);
CheckData checkData(std::move(it->second));
- m_sequenceContainer.release(it->first);
- m_checks.erase(it);
+ releaseRequest(it);
+
if (!checkData.cancelled()) {
bool onAnswerCancel = m_inAnswerCancelResponseCallback;
m_inAnswerCancelResponseCallback = true;
}
}
+void Logic::processSimpleCheckResponse(SimpleCheckResponsePtr response) {
+ LOGD("simpleCheckResponse");
+ LOGD("checkResponse: policyType = [%" PRIu16 "], metadata = <%s>",
+ response->getResult().policyType(),
+ response->getResult().metadata().c_str());
+
+ auto it = checkResponseValid(response);
+ int result = response->getReturnValue();
+ if (result == CYNARA_API_SUCCESS)
+ result = m_cache->update(it->second.session(), it->second.key(),
+ response->getResult());
+ CheckData checkData(std::move(it->second));
+ releaseRequest(it);
+
+ if (!checkData.cancelled()) {
+ bool onAnswerCancel = m_inAnswerCancelResponseCallback;
+ m_inAnswerCancelResponseCallback = true;
+ checkData.callback().onAnswer(
+ static_cast<cynara_check_id>(response->sequenceNumber()), result);
+ m_inAnswerCancelResponseCallback = onAnswerCancel;
+ }
+}
+
void Logic::processCancelResponse(CancelResponsePtr cancelResponse) {
LOGD("cancelResponse");
- auto it = m_checks.find(cancelResponse->sequenceNumber());
- if (it == m_checks.end()) {
- LOGC("Critical error. Unknown cancelResponse received: sequenceNumber = [%" PRIu16 "]",
- cancelResponse->sequenceNumber());
- throw UnexpectedErrorException("Unexpected response from cynara service");
- }
+ auto it = checkResponseValid(cancelResponse);
if (!it->second.cancelled()) {
LOGC("Critical error. CancelRequest not sent: sequenceNumber = [%" PRIu16 "]",
cancelResponse->sequenceNumber());
throw UnexpectedErrorException("Unexpected response from cynara service");
}
- m_sequenceContainer.release(it->first);
- m_checks.erase(it);
+ releaseRequest(it);
}
void Logic::processResponses(void) {
ResponsePtr response;
CheckResponsePtr checkResponse;
CancelResponsePtr cancelResponse;
- while (response = m_socketClient->getResponse()) {
+ SimpleCheckResponsePtr simpleResponse;
+ while ((response = m_socketClient->getResponse())) {
checkResponse = std::dynamic_pointer_cast<CheckResponse>(response);
if (checkResponse) {
processCheckResponse(checkResponse);
continue;
}
+ simpleResponse = std::dynamic_pointer_cast<SimpleCheckResponse>(response);
+ if (simpleResponse) {
+ processSimpleCheckResponse(simpleResponse);
+ continue;
+ }
+
LOGC("Critical error. Casting Response to known response failed.");
throw UnexpectedErrorException("Unexpected response from cynara service");
}
virtual int checkCache(const std::string &client, const std::string &session,
const std::string &user, const std::string &privilege);
- virtual int createRequest(const std::string &client, const std::string &session,
- const std::string &user, const std::string &privilege,
- cynara_check_id &checkId, cynara_response_callback callback,
- void *userResponseData);
+ virtual int createCheckRequest(const std::string &client, const std::string &session,
+ const std::string &user, const std::string &privilege,
+ cynara_check_id &checkId, cynara_response_callback callback,
+ void *userResponseData);
+ virtual int createSimpleRequest(const std::string &client, const std::string &session,
+ const std::string &user, const std::string &privilege,
+ cynara_check_id &checkId, cynara_response_callback callback,
+ void *userResponseData);
virtual int process(void);
virtual int cancelRequest(cynara_check_id checkId);
virtual bool isFinishPermitted(void);
bool m_inAnswerCancelResponseCallback;
bool checkCacheValid(void);
+ int createRequest(bool simple, const std::string &client, const std::string &session,
+ const std::string &user, const std::string &privilege,
+ cynara_check_id &checkId, cynara_response_callback callback,
+ void *userResponseData);
void prepareRequestsToSend(void);
cynara_async_status socketDataStatus(void);
bool processOut(void);
+ CheckMap::iterator checkResponseValid(ResponsePtr response);
+ void releaseRequest(Logic::CheckMap::iterator reqIt);
void processCheckResponse(CheckResponsePtr checkResponse);
void processCancelResponse(CancelResponsePtr cancelResponse);
+ void processSimpleCheckResponse(SimpleCheckResponsePtr response);
void processResponses(void);
bool processIn(void);
bool ensureConnection(void);