Line data Source code
1 : /**
2 : Copyright (c) 2016-2022 Roman Katuntsev <sbkarr@stappler.org>
3 : Copyright (c) 2023-2024 Stappler LLC <admin@stappler.dev>
4 :
5 : Permission is hereby granted, free of charge, to any person obtaining a copy
6 : of this software and associated documentation files (the "Software"), to deal
7 : in the Software without restriction, including without limitation the rights
8 : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 : copies of the Software, and to permit persons to whom the Software is
10 : furnished to do so, subject to the following conditions:
11 :
12 : The above copyright notice and this permission notice shall be included in
13 : all copies or substantial portions of the Software.
14 :
15 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 : THE SOFTWARE.
22 : **/
23 :
24 : #include "SPDbUser.h"
25 :
26 : #include "SPDbAdapter.h"
27 : #include "SPDbScheme.h"
28 : #include "SPDbWorker.h"
29 : #include "SPValid.h"
30 :
31 : namespace STAPPLER_VERSIONIZED stappler::db {
32 :
33 0 : User *User::create(const Transaction &a, const StringView &name, const StringView &password) {
34 0 : return create(a, Value{
35 0 : std::make_pair("name", Value(name)),
36 0 : std::make_pair("password", Value(password)),
37 0 : });
38 : }
39 :
40 50 : User *User::setup(const Transaction &a, const StringView &name, const StringView &password) {
41 50 : auto s = a.getAdapter().getApplicationInterface()->getUserScheme();
42 50 : if (Worker(*s, a).asSystem().count() == 0) {
43 400 : return create(a, Value{
44 100 : std::make_pair("name", Value(name)),
45 100 : std::make_pair("password", Value(password)),
46 100 : std::make_pair("isAdmin", Value(true)),
47 250 : });
48 : }
49 0 : return nullptr;
50 : }
51 50 : User *User::create(const Transaction &a, Value &&val) {
52 50 : auto s = a.getAdapter().getApplicationInterface()->getUserScheme();
53 :
54 50 : auto d = Worker(*s, a).asSystem().create(val);
55 100 : return new User(std::move(d), *s);
56 50 : }
57 :
58 0 : User *User::get(const Adapter &a, const StringView &name, const StringView &password) {
59 0 : auto s = a.getApplicationInterface()->getUserScheme();
60 0 : return get(a, *s, name, password);
61 : }
62 :
63 0 : User *User::get(const Adapter &a, const Scheme &scheme, const StringView &name, const StringView &password) {
64 0 : return a.authorizeUser(Auth(a.getApplicationInterface(), scheme), name, password);
65 : }
66 :
67 0 : User *User::get(const Adapter &a, const Scheme &scheme, const BytesView &key) {
68 0 : for (auto &it : scheme.getFields()) {
69 0 : if (it.second.getType() == db::Type::Bytes && it.second.getTransform() == db::Transform::PublicKey && it.second.isIndexed()) {
70 0 : auto d = Worker(scheme, a).asSystem().select(db::Query().select(it.second.getName(), Value(key)));
71 0 : if (d.isArray() && d.size() == 1) {
72 0 : return new User(std::move(d.getValue(0)), scheme);
73 : }
74 0 : break;
75 0 : }
76 : }
77 0 : return nullptr;
78 : }
79 :
80 150 : User *User::get(const Adapter &a, uint64_t oid) {
81 150 : auto s = a.getApplicationInterface()->getUserScheme();
82 150 : return get(a, *s, oid);
83 : }
84 :
85 150 : User *User::get(const Adapter &a, const Scheme &s, uint64_t oid) {
86 150 : auto d = Worker(s, a).asSystem().get(oid);
87 150 : if (d.isDictionary()) {
88 25 : return new User(std::move(d), s);
89 : }
90 125 : return nullptr;
91 150 : }
92 :
93 575 : User *User::get(const Transaction &a, const StringView &name, const StringView &password) {
94 575 : auto s = a.getAdapter().getApplicationInterface()->getUserScheme();
95 575 : return get(a, *s, name, password);
96 : }
97 :
98 575 : User *User::get(const Transaction &a, const Scheme &scheme, const StringView &name, const StringView &password) {
99 575 : return a.getAdapter().authorizeUser(Auth(a.getAdapter().getApplicationInterface(), scheme), name, password);
100 : }
101 :
102 0 : User *User::get(const Transaction &a, const Scheme &scheme, const BytesView &key) {
103 0 : for (auto &it : scheme.getFields()) {
104 0 : if (it.second.getType() == db::Type::Bytes && it.second.getTransform() == db::Transform::PublicKey && it.second.isIndexed()) {
105 0 : auto d = Worker(scheme, a).asSystem().select(db::Query().select(it.second.getName(), Value(key)));
106 0 : if (d.isArray() && d.size() == 1) {
107 0 : return new User(std::move(d.getValue(0)), scheme);
108 : }
109 0 : break;
110 0 : }
111 : }
112 0 : return nullptr;
113 : }
114 :
115 175 : User *User::get(const Transaction &a, uint64_t oid) {
116 175 : auto s = a.getAdapter().getApplicationInterface()->getUserScheme();
117 175 : return get(a, *s, oid);
118 : }
119 :
120 175 : User *User::get(const Transaction &a, const Scheme &s, uint64_t oid) {
121 175 : auto d = Worker(s, a).asSystem().get(oid);
122 175 : if (d.isDictionary()) {
123 175 : return new User(std::move(d), s);
124 : }
125 0 : return nullptr;
126 175 : }
127 :
128 800 : User::User(Value &&d, const Scheme &s) : Object(std::move(d), s) { }
129 :
130 0 : bool User::validatePassword(const StringView &passwd) const {
131 0 : auto & fields = _scheme.getFields();
132 0 : auto it = _scheme.getFields().find("password");
133 0 : if (it != fields.end() && it->second.getTransform() == Transform::Password) {
134 0 : auto f = static_cast<const FieldPassword *>(it->second.getSlot());
135 0 : return stappler::valid::validatePassord(passwd, getBytes("password"), f->salt);
136 : }
137 0 : return false;
138 : }
139 :
140 0 : void User::setPassword(const StringView &passwd) {
141 0 : auto & fields = _scheme.getFields();
142 0 : auto it = _scheme.getFields().find("password");
143 0 : if (it != fields.end() && it->second.getTransform() == Transform::Password) {
144 0 : auto f = static_cast<const FieldPassword *>(it->second.getSlot());
145 0 : setBytes(stappler::valid::makePassword<Interface>(passwd, f->salt), "password");
146 : }
147 0 : }
148 :
149 1575 : bool User::isAdmin() const {
150 1575 : return getBool("isAdmin");
151 : }
152 :
153 1550 : StringView User::getName() const {
154 1550 : return getString("name");
155 : }
156 :
157 : }
|