forked from joyieldInc/predixy
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathAuth.cpp
114 lines (103 loc) · 2.67 KB
/
Auth.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
* predixy - A high performance and full features proxy for redis.
* Copyright (C) 2017 Joyield, Inc. <[email protected]>
* 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;
}
}
if (!conf.namePrefix.empty()) {
logDebug("config namespace: %s", conf.namePrefix.c_str());
mNamePrefix = conf.namePrefix;
}
}
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;
}
}