]> git.stg.codes - stg.git/blob - projects/stargazer/plugins/authorization/ao/ao.cpp
Add async pool (to replace EVENT_LOOP).
[stg.git] / projects / stargazer / plugins / authorization / ao / ao.cpp
1 /*
2  *    This program is free software; you can redistribute it and/or modify
3  *    it under the terms of the GNU General Public License as published by
4  *    the Free Software Foundation; either version 2 of the License, or
5  *    (at your option) any later version.
6  *
7  *    This program is distributed in the hope that it will be useful,
8  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *    GNU General Public License for more details.
11  *
12  *    You should have received a copy of the GNU General Public License
13  *    along with this program; if not, write to the Free Software
14  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15  */
16
17 /*
18  *    Author : Boris Mikhailenko <stg34@stargazer.dp.ua>
19  */
20
21 #include "ao.h"
22
23 #include "stg/user.h"
24 #include "stg/users.h"
25 #include "stg/user_property.h"
26 #include "stg/common.h"
27
28 #include <algorithm> // for_each
29 #include <functional> // mem_fun_ref
30 #include <csignal>
31 #include <cassert>
32
33 #include <unistd.h>
34
35 extern "C" STG::Plugin* GetPlugin()
36 {
37     static AUTH_AO plugin;
38     return &plugin;
39 }
40 //-----------------------------------------------------------------------------
41 //-----------------------------------------------------------------------------
42 //-----------------------------------------------------------------------------
43 std::string AUTH_AO::GetVersion() const
44 {
45 return "Always Online authorizator v.1.0";
46 }
47 //-----------------------------------------------------------------------------
48 AUTH_AO::AUTH_AO()
49     : users(NULL),
50       isRunning(false),
51       onAddUserNotifier(*this),
52       onDelUserNotifier(*this),
53       logger(STG::PluginLogger::get("auth_ao"))
54 {
55 }
56 //-----------------------------------------------------------------------------
57 int AUTH_AO::Start()
58 {
59 printfd(__FILE__, "AUTH_AO::Start()\n");
60 GetUsers();
61
62 users->AddNotifierUserAdd(&onAddUserNotifier);
63 users->AddNotifierUserDel(&onDelUserNotifier);
64
65 std::for_each(userList.begin(), userList.end(), [this](auto user){ UpdateUserAuthorization(user); });
66
67 isRunning = true;
68
69 return 0;
70 }
71 //-----------------------------------------------------------------------------
72 int AUTH_AO::Stop()
73 {
74 printfd(__FILE__, "AUTH_AO::Stop()\n");
75 if (!isRunning)
76     return 0;
77
78 users->DelNotifierUserAdd(&onAddUserNotifier);
79 users->DelNotifierUserDel(&onDelUserNotifier);
80
81 auto it = userList.begin();
82 while (it != userList.end())
83     {
84     if ((*it)->IsAuthorizedBy(this))
85         users->Unauthorize((*it)->GetLogin(), this);
86     UnSetUserNotifiers(*it);
87     ++it;
88     }
89 isRunning = false;
90 return 0;
91 }
92 //-----------------------------------------------------------------------------
93 void AUTH_AO::SetUserNotifiers(UserPtr u)
94 {
95 // ---------- AlwaysOnline -------------------
96 CHG_BEFORE_NOTIFIER<int> BeforeChgAONotifier(*this, u);
97 CHG_AFTER_NOTIFIER<int>  AfterChgAONotifier(*this, u);
98
99 BeforeChgAONotifierList.push_front(BeforeChgAONotifier);
100 AfterChgAONotifierList.push_front(AfterChgAONotifier);
101
102 u->GetProperties().alwaysOnline.AddBeforeNotifier(&BeforeChgAONotifierList.front());
103 u->GetProperties().alwaysOnline.AddAfterNotifier(&AfterChgAONotifierList.front());
104 // ---------- AlwaysOnline end ---------------
105
106 // ---------- IP -------------------
107 CHG_BEFORE_NOTIFIER<STG::UserIPs> BeforeChgIPNotifier(*this, u);
108 CHG_AFTER_NOTIFIER<STG::UserIPs>  AfterChgIPNotifier(*this, u);
109
110 BeforeChgIPNotifierList.push_front(BeforeChgIPNotifier);
111 AfterChgIPNotifierList.push_front(AfterChgIPNotifier);
112
113 u->GetProperties().ips.AddBeforeNotifier(&BeforeChgIPNotifierList.front());
114 u->GetProperties().ips.AddAfterNotifier(&AfterChgIPNotifierList.front());
115 // ---------- IP end ---------------
116 }
117 //-----------------------------------------------------------------------------
118 void AUTH_AO::UnSetUserNotifiers(UserPtr u)
119 {
120 // ---      AlwaysOnline        ---
121 auto aoBIter = find_if(BeforeChgAONotifierList.begin(),
122                        BeforeChgAONotifierList.end(),
123                        [u](auto notifier){ return notifier.GetUser() == u; });
124
125 if (aoBIter != BeforeChgAONotifierList.end())
126     {
127     aoBIter->GetUser()->GetProperties().alwaysOnline.DelBeforeNotifier(&(*aoBIter));
128     BeforeChgAONotifierList.erase(aoBIter);
129     }
130
131 auto aoAIter = find_if(AfterChgAONotifierList.begin(),
132                        AfterChgAONotifierList.end(),
133                        [u](auto notifier){ return notifier.GetUser() == u; });
134
135 if (aoAIter != AfterChgAONotifierList.end())
136     {
137     aoAIter->GetUser()->GetProperties().alwaysOnline.DelAfterNotifier(&(*aoAIter));
138     AfterChgAONotifierList.erase(aoAIter);
139     }
140 // ---      AlwaysOnline end    ---
141
142 // ---          IP              ---
143 auto ipBIter = std::find_if(BeforeChgIPNotifierList.begin(),
144                             BeforeChgIPNotifierList.end(),
145                             [u](auto notifier){ return notifier.GetUser() == u; });
146
147 if (ipBIter != BeforeChgIPNotifierList.end())
148     {
149     ipBIter->GetUser()->GetProperties().ips.DelBeforeNotifier(&(*ipBIter));
150     BeforeChgIPNotifierList.erase(ipBIter);
151     }
152
153 auto ipAIter = find_if(AfterChgIPNotifierList.begin(),
154                        AfterChgIPNotifierList.end(),
155                        [u](auto notifier){ return notifier.GetUser() == u; });
156
157 if (ipAIter != AfterChgIPNotifierList.end())
158     {
159     ipAIter->GetUser()->GetProperties().ips.DelAfterNotifier(&(*ipAIter));
160     AfterChgIPNotifierList.erase(ipAIter);
161     }
162 // ---          IP end          ---
163 }
164 //-----------------------------------------------------------------------------
165 void AUTH_AO::GetUsers()
166 {
167 UserPtr u;
168 int h = users->OpenSearch();
169 assert(h && "USERS::OpenSearch is always correct");
170
171 while (!users->SearchNext(h, &u))
172     {
173     userList.push_back(u);
174     SetUserNotifiers(u);
175     }
176
177 users->CloseSearch(h);
178 }
179 //-----------------------------------------------------------------------------
180 void AUTH_AO::UpdateUserAuthorization(ConstUserPtr u) const
181 {
182 if (u->GetProperties().alwaysOnline)
183     {
184     auto ips = u->GetProperties().ips.get();
185     if (ips.onlyOneIP())
186         {
187         users->Authorize(u->GetLogin(), ips[0].ip, 0xFFffFFff, this);
188         }
189     }
190 }
191 //-----------------------------------------------------------------------------
192 void AUTH_AO::AddUser(UserPtr u)
193 {
194 SetUserNotifiers(u);
195 userList.push_back(u);
196 UpdateUserAuthorization(u);
197 }
198 //-----------------------------------------------------------------------------
199 void AUTH_AO::DelUser(UserPtr u)
200 {
201 if (u->IsAuthorizedBy(this))
202     users->Unauthorize(u->GetLogin(), this);
203 UnSetUserNotifiers(u);
204 userList.erase(std::remove(userList.begin(), userList.end(), u), userList.end());
205 }
206 //-----------------------------------------------------------------------------
207 int AUTH_AO::SendMessage(const STG::Message &, uint32_t) const
208 {
209 errorStr = "Authorization modele \'AlwaysOnline\' does not support sending messages";
210 return -1;
211 }
212 //-----------------------------------------------------------------------------
213 template <typename varParamType>
214 void CHG_BEFORE_NOTIFIER<varParamType>::notify(const varParamType &, const varParamType &)
215 {
216 //EVENT_LOOP_SINGLETON::GetInstance().Enqueue(auth, &AUTH_AO::Unauthorize, user);
217 if (user->IsAuthorizedBy(&auth))
218     auth.users->Unauthorize(user->GetLogin(), &auth);
219 }
220 //-----------------------------------------------------------------------------
221 template <typename varParamType>
222 void CHG_AFTER_NOTIFIER<varParamType>::notify(const varParamType &, const varParamType &)
223 {
224 //EVENT_LOOP_SINGLETON::GetInstance().Enqueue(auth, &AUTH_AO::UpdateUserAuthorization, user);
225 auth.UpdateUserAuthorization(user);
226 }
227 //-----------------------------------------------------------------------------