mirror of
https://github.com/joyieldInc/predixy.git
synced 2025-12-24 22:46:41 +08:00
110 lines
2.5 KiB
C++
110 lines
2.5 KiB
C++
/*
|
|
* predixy - A high performance and full features proxy for redis.
|
|
* Copyright (C) 2017 Joyield, Inc. <joyield.com@gmail.com>
|
|
* All rights reserved.
|
|
*/
|
|
|
|
#include <algorithm>
|
|
#include "Auth.h"
|
|
#include "Conf.h"
|
|
#include "Request.h"
|
|
|
|
|
|
Auth::Auth(int mode):
|
|
mMode(mode),
|
|
mReadKeyPrefix(nullptr),
|
|
mWriteKeyPrefix(nullptr)
|
|
{
|
|
}
|
|
|
|
Auth::Auth(const AuthConf& conf):
|
|
mPassword(conf.password.c_str(), conf.password.size()),
|
|
mMode(conf.mode),
|
|
mReadKeyPrefix(nullptr),
|
|
mWriteKeyPrefix(nullptr)
|
|
{
|
|
if (!conf.readKeyPrefix.empty()) {
|
|
mReadKeyPrefix = new KeyPrefixSet(conf.readKeyPrefix.begin(), conf.readKeyPrefix.end());
|
|
}
|
|
if (!conf.writeKeyPrefix.empty()) {
|
|
mWriteKeyPrefix = new KeyPrefixSet(conf.writeKeyPrefix.begin(), conf.writeKeyPrefix.end());
|
|
}
|
|
if ((!mReadKeyPrefix || !mWriteKeyPrefix) && !conf.keyPrefix.empty()) {
|
|
auto kp = new KeyPrefixSet(conf.keyPrefix.begin(), conf.keyPrefix.end());
|
|
if (!mReadKeyPrefix) {
|
|
mReadKeyPrefix = kp;
|
|
}
|
|
if (!mWriteKeyPrefix) {
|
|
mWriteKeyPrefix = kp;
|
|
}
|
|
}
|
|
}
|
|
|
|
Auth::~Auth()
|
|
{
|
|
if (mReadKeyPrefix) {
|
|
delete mReadKeyPrefix;
|
|
}
|
|
if (mWriteKeyPrefix && mWriteKeyPrefix != mReadKeyPrefix) {
|
|
delete mWriteKeyPrefix;
|
|
}
|
|
}
|
|
|
|
bool Auth::permission(Request* req, const String& key) const
|
|
{
|
|
auto& cmd = Command::get(req->type());
|
|
if (!(mMode & cmd.mode)) {
|
|
return false;
|
|
}
|
|
const KeyPrefixSet* kp = nullptr;
|
|
if (cmd.mode & Command::Read) {
|
|
kp = mReadKeyPrefix;
|
|
} else if (cmd.mode & Command::Write) {
|
|
kp = mWriteKeyPrefix;
|
|
}
|
|
if (kp) {
|
|
auto it = kp->upper_bound(key);
|
|
const String* p = nullptr;
|
|
if (it == kp->end()) {
|
|
p = &(*kp->rbegin());
|
|
} else if (it != kp->begin()) {
|
|
p = &(*--it);
|
|
}
|
|
return p && key.hasPrefix(*p);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
Auth Authority::AuthAllowAll;
|
|
Auth Authority::AuthDenyAll(0);
|
|
|
|
Authority::Authority():
|
|
mDefault(&AuthAllowAll)
|
|
{
|
|
}
|
|
|
|
Authority::~Authority()
|
|
{
|
|
for (auto& i : mAuthMap) {
|
|
delete i.second;
|
|
}
|
|
mAuthMap.clear();
|
|
}
|
|
|
|
void Authority::add(const AuthConf& ac)
|
|
{
|
|
Auth* a = new Auth(ac);
|
|
auto it = mAuthMap.find(a->password());
|
|
if (it != mAuthMap.end()) {
|
|
Auth* p = it->second;
|
|
mAuthMap.erase(it);
|
|
delete p;
|
|
}
|
|
mAuthMap[a->password()] = a;
|
|
if (a->password().empty()) {
|
|
mDefault = a;
|
|
} else if (mDefault == &AuthAllowAll) {
|
|
mDefault = &AuthDenyAll;
|
|
}
|
|
}
|