Leosac  0.8.0
Open Source Access Control
APISession.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014-2016 Leosac
3 
4  This file is part of Leosac.
5 
6  Leosac is free software: you can redistribute it and/or modify
7  it under the terms of the GNU Affero General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  Leosac is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU Affero General Public License for more details.
15 
16  You should have received a copy of the GNU Affero General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "APISession.hpp"
21 #include "Exceptions.hpp"
22 #include "WSServer.hpp"
23 #include "core/CoreUtils.hpp"
25 #include "core/auth/Group.hpp"
26 #include "core/auth/Group_odb.h"
27 #include "core/auth/Token_odb.h"
28 #include "core/auth/User.hpp"
29 #include "core/auth/UserGroupMembership_odb.h"
30 #include "core/auth/User_odb.h"
31 #include "core/kernel.hpp"
32 #include "tools/GenGuid.h"
33 #include "tools/LogEntry.hpp"
35 #include "tools/version.hpp"
36 #include <odb/session.hxx>
37 
38 using namespace Leosac;
39 using namespace Leosac::Module;
40 using namespace Leosac::Module::WebSockAPI;
41 
43  : server_(server)
44  , auth_status_(AuthStatus::NONE)
45 {
46 }
47 
49 {
50  json ret;
51  ret["version"] = Tools::Version::get_full_version();
52  ret["version_short"] = Tools::Version::get_short_version();
53  return ret;
54 }
55 
57 {
58  json rep;
59  ASSERT_LOG(auth_status_ == AuthStatus::NONE, "Invalid auth status.");
60 
61  std::string username = req.at("username");
62  std::string password = req.at("password");
63 
64  auto token = server_.auth().authenticate_credentials(username, password);
65 
66  if (token)
67  {
68  rep["status"] = 0;
69  rep["user_id"] = token->owner()->id();
70  rep["token"] = token->token();
71  mark_authenticated(token);
72  }
73  else
74  {
75  rep["status"] = -1;
76  rep["message"] = "Invalid credentials";
77  }
78 
79  return rep;
80 }
81 
83 {
84  json rep;
85  ASSERT_LOG(auth_status_ == AuthStatus::NONE, "Invalid auth status.");
86 
87  auto token = server_.auth().authenticate_token(req.at("token"));
88  if (token)
89  {
90  rep["status"] = 0;
91  rep["user_id"] = token->owner()->id();
92  rep["username"] = token->owner()->username();
93  mark_authenticated(token);
94  }
95  else
96  {
97  rep["status"] = -1;
98  rep["message"] = "Invalid credentials";
99  }
100 
101  return rep;
102 }
103 
105 {
106  ASSERT_LOG(auth_status_ == AuthStatus::LOGGED_IN, "Invalid auth status");
107  ASSERT_LOG(current_auth_token_, "Logout called, but user has no current token.");
110  return {};
111 }
112 
114 {
115  json rep;
116  auto core_api = server_.core_utils()->core_api();
117 
118  rep["instance_name"] = core_api.instance_name();
119  rep["config_version"] = core_api.config_version();
120  rep["uptime"] = core_api.uptime();
121  rep["modules"] = core_api.modules_names();
122 
123  return rep;
124 }
125 
126 bool APISession::allowed(const std::string &cmd)
127 {
128  if (cmd == "get_leosac_version")
129  return true;
130  if (cmd == "create_auth_token" || cmd == "authenticate_with_token")
133 }
134 
136 {
138  {
139  odb::core::transaction t(server_.db()->begin());
141  // Reload token
142  try
143  {
144  server_.db()->reload(current_auth_token_);
145  }
146  catch (const odb::object_changed &e)
147  {
148  // Token doesn't exist anymore.
149  abort_session();
150  throw SessionAborted(nullptr);
151  }
152 
153  if (!current_auth_token_->is_valid())
154  {
155  abort_session();
157  }
158 
159  current_auth_token_->expire_in(std::chrono::minutes(20));
160  server_.db()->update(*current_auth_token_);
161  t.commit();
162  }
163 }
164 
166 {
168  current_auth_token_ = nullptr;
169 }
170 
172 {
174  return current_auth_token_->owner()->id();
175  return 0;
176 }
177 
179 {
181  return current_auth_token_->owner();
182  return nullptr;
183 }
184 
186 {
187  return current_auth_token_;
188 }
189 
191 {
193  current_auth_token_ = token;
194  security_ =
195  std::make_unique<UserSecurityContext>(server_.dbsrv(), token->owner()->id());
196 }
197 
199 {
201  current_auth_token_ = nullptr;
202  security_ = nullptr;
203 }
204 
206 {
207  static NullSecurityContext sc;
208  if (security_)
209  return *security_.get();
210  return sc;
211 }
Leosac::Module::WebSockAPI::APISession::json
nlohmann::json json
Definition: APISession.hpp:45
Leosac::Module::WebSockAPI::APISession::clear_authentication
void clear_authentication()
Definition: APISession.cpp:198
Leosac::Tools::Version::get_short_version
static std::string get_short_version()
Retrieve the short (X.Y.Z) version of Leosac.
Definition: version.cpp:85
Leosac::NullSecurityContext
A SecurityContext with no permission.
Definition: UserSecurityContext.hpp:98
Leosac::Tools::Version::get_full_version
static std::string get_full_version()
Returns the complete version string.
Definition: version.cpp:80
Leosac::Module::WebSockAPI::APISession::hook_before_request
void hook_before_request()
A hook that is called before a request processing method will be invoked.
Definition: APISession.cpp:135
Leosac::Module::WebSockAPI::APISession::get_leosac_version
json get_leosac_version(const json &)
Retrieve the current version number of Leosac.
Definition: APISession.cpp:48
Exceptions.hpp
Leosac::Module::WebSockAPI::APISession::current_user
Auth::UserPtr current_user() const
Retrieve the user associated with the session, or nullptr.
Definition: APISession.cpp:178
Leosac::Auth::TokenPtr
std::shared_ptr< Token > TokenPtr
Definition: AuthFwd.hpp:85
Leosac::Module::WebSockAPI::APIAuth::authenticate_token
Auth::TokenPtr authenticate_token(const std::string &token_str) const
Attempt to authenticate with an authentication token.
Definition: APIAuth.cpp:60
ASSERT_LOG
#define ASSERT_LOG(cond, msg)
Definition: log.hpp:190
Leosac::Auth::UserPtr
std::shared_ptr< User > UserPtr
Definition: AuthFwd.hpp:31
Leosac::Module::WebSockAPI::WSServer::auth
APIAuth & auth()
Retrieve the authentication helper.
Definition: WSServer.cpp:264
Leosac::db::MultiplexedSession
Acts like an odb::session, with the exception that it will save the current active session (if any) a...
Definition: MultiplexedSession.hpp:39
User.hpp
Leosac::Module::WebSockAPI::APISession::APISession
APISession(WSServer &server)
Definition: APISession.cpp:42
Leosac::Module::WebSockAPI::APISession::security_
std::unique_ptr< SecurityContext > security_
Definition: APISession.hpp:188
version.hpp
version handling
Leosac::Module::WebSockAPI::APISession::allowed
bool allowed(const std::string &cmd)
Is this API client allowed to perform the request cmd ?
Definition: APISession.cpp:126
Leosac::Module::WebSockAPI::APISession::mark_authenticated
void mark_authenticated(Auth::TokenPtr token)
Definition: APISession.cpp:190
Leosac::Module::WebSockAPI::APISession::current_user_id
Auth::UserId current_user_id() const
Retrieve the UserId of the user associated with this API session.
Definition: APISession.cpp:171
Leosac::Module::WebSockAPI::APIAuth::authenticate_credentials
Auth::TokenPtr authenticate_credentials(const std::string &username, const std::string &password) const
Attempt to authenticate with username/password credential and generate an authentication token.
Definition: APIAuth.cpp:82
Leosac::Module
All modules that provides features to Leosac shall be in this namespace.
Leosac::Module::WebSockAPI::APISession::logout
json logout(const json &req)
Log an user out.
Definition: APISession.cpp:104
Leosac::Module::WebSockAPI::APISession::system_overview
json system_overview(const json &req)
Presents an overview of the system to the end user.
Definition: APISession.cpp:113
Leosac
This is the header file for a generated source file, GitSHA1.cpp.
Definition: APIStatusCode.hpp:22
kernel.hpp
Group.hpp
Leosac::Module::WebSockAPI::APISession::server_
WSServer & server_
The API server.
Definition: APISession.hpp:180
Leosac::Module::WebSockAPI::WSServer
The implementation class that runs the websocket server.
Definition: WSServer.hpp:61
Leosac::Module::WebSockAPI::APISession::AuthStatus::NONE
@ NONE
GenGuid.h
Leosac::Module::WebSockAPI::SessionAborted
Definition: Exceptions.hpp:48
Leosac::Module::WebSockAPI::APISession::AuthStatus
AuthStatus
Enumeration describing the authentication status of a client.
Definition: APISession.hpp:50
Leosac::Module::WebSockAPI::APIAuth::invalidate_token
void invalidate_token(Auth::TokenPtr token) const
Invalidate the authentication token, removing it from the database.
Definition: APIAuth.cpp:49
WSServer.hpp
Leosac::Module::WebSockAPI::APISession::auth_status_
AuthStatus auth_status_
Definition: APISession.hpp:181
LogEntry.hpp
Leosac::Module::WebSockAPI::WSServer::core_utils
CoreUtilsPtr core_utils()
Retrieve the CoreUtils pointer.
Definition: WSServer.cpp:342
APISession.hpp
Leosac::Module::WebSockAPI::APISession::current_token
Auth::TokenPtr current_token() const
Retrieve the currently in-use token, or nullptr.
Definition: APISession.cpp:185
Leosac::Module::WebSockAPI::WSServer::db
DBPtr db()
Retrieve database handle.
Definition: WSServer.cpp:337
CoreUtils.hpp
MultiplexedSession.hpp
Leosac::Auth::UserId
unsigned long UserId
Definition: AuthFwd.hpp:34
Leosac::Module::WebSockAPI::APISession::AuthStatus::LOGGED_IN
@ LOGGED_IN
Leosac::Module::WebSockAPI::APISession::security_context
SecurityContext & security_context() const
Definition: APISession.cpp:205
Leosac::Module::WebSockAPI::APISession::authenticate_with_token
json authenticate_with_token(const json &req)
Attempt to authenticate with a (previously generated) authentication token.
Definition: APISession.cpp:82
Leosac::Module::WebSockAPI
Definition: ActionActionParam.hpp:28
Leosac::Module::WebSockAPI::WSServer::dbsrv
DBServicePtr dbsrv()
Retrieve database service pointer.
Definition: WSServer.cpp:454
Leosac::Module::WebSockAPI::APISession::create_auth_token
json create_auth_token(const json &req)
Generate an authentication token using the user credential, and logs the user in on success.
Definition: APISession.cpp:56
UserSecurityContext.hpp
Leosac::Module::WebSockAPI::APISession::current_auth_token_
Auth::TokenPtr current_auth_token_
The token we are authenticated with.
Definition: APISession.hpp:186
Leosac::Module::WebSockAPI::APISession::abort_session
void abort_session()
Abort the current websocket session.
Definition: APISession.cpp:165
Leosac::SecurityContext
A SecurityContext is used to query permission while doing an operation.
Definition: SecurityContext.hpp:40