aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/clickhouse/src/Interpreters/Session.h
blob: 81ef987b428acfc06a2e94abe8fffff761c5b363 (plain) (blame)
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
115
116
117
118
119
120
121
122
123
124
#pragma once

#include <Common/SettingsChanges.h>
#include <Access/AuthenticationData.h>
#include <Interpreters/ClientInfo.h>
#include <Interpreters/Context_fwd.h>
#include <Interpreters/SessionTracker.h>

#include <chrono>
#include <memory>
#include <optional>

namespace Poco::Net { class SocketAddress; }

namespace DB
{
class Credentials;
class AuthenticationData;
struct NamedSessionData;
class NamedSessionsStorage;
struct User;
using UserPtr = std::shared_ptr<const User>;
class SessionLog;

/** Represents user-session from the server perspective,
 *  basically it is just a smaller subset of Context API, simplifies Context management.
 *
 * Holds session context, facilitates acquisition of NamedSession and proper creation of query contexts.
 */
class Session
{
public:
    /// Stops using named sessions. The method must be called at the server shutdown.
    static void shutdownNamedSessions();

    Session(const ContextPtr & global_context_, ClientInfo::Interface interface_, bool is_secure = false, const std::string & certificate = "");
    ~Session();

    Session(const Session &&) = delete;
    Session & operator=(const Session &&) = delete;
    Session(const Session &) = delete;
    Session & operator=(const Session &) = delete;

    /// Provides information about the authentication type of a specified user.
    AuthenticationType getAuthenticationType(const String & user_name) const;

    /// Same as getAuthenticationType, but adds LoginFailure event in case of error.
    AuthenticationType getAuthenticationTypeOrLogInFailure(const String & user_name) const;

    /// Sets the current user, checks the credentials and that the specified address is allowed to connect from.
    /// The function throws an exception if there is no such user or password is wrong.
    void authenticate(const String & user_name, const String & password, const Poco::Net::SocketAddress & address);
    void authenticate(const Credentials & credentials_, const Poco::Net::SocketAddress & address_);

    /// Writes a row about login failure into session log (if enabled)
    void onAuthenticationFailure(const std::optional<String> & user_name, const Poco::Net::SocketAddress & address_, const Exception & e);

    /// Returns a reference to the session's ClientInfo.
    const ClientInfo & getClientInfo() const;

    /// Modify the session's ClientInfo.
    void setClientInfo(const ClientInfo & client_info);
    void setClientName(const String & client_name);
    void setClientInterface(ClientInfo::Interface interface);
    void setClientVersion(UInt64 client_version_major, UInt64 client_version_minor, UInt64 client_version_patch, unsigned client_tcp_protocol_version);
    void setClientConnectionId(uint32_t connection_id);
    void setHttpClientInfo(ClientInfo::HTTPMethod http_method, const String & http_user_agent, const String & http_referer);
    void setForwardedFor(const String & forwarded_for);
    void setQuotaClientKey(const String & quota_key);
    void setConnectionClientVersion(UInt64 client_version_major, UInt64 client_version_minor, UInt64 client_version_patch, unsigned client_tcp_protocol_version);

    const OpenTelemetry::TracingContext & getClientTraceContext() const;
    OpenTelemetry::TracingContext & getClientTraceContext();

    /// Makes a session context, can be used one or zero times.
    /// The function also assigns an user to this context.
    ContextMutablePtr makeSessionContext();
    ContextMutablePtr makeSessionContext(const String & session_name_, std::chrono::steady_clock::duration timeout_, bool session_check_);
    ContextMutablePtr sessionContext() { return session_context; }
    ContextPtr sessionContext() const { return session_context; }

    ContextPtr  sessionOrGlobalContext() const { return session_context ? session_context : global_context; }

    /// Makes a query context, can be used multiple times, with or without makeSession() called earlier.
    /// The query context will be created from a copy of a session context if it exists, or from a copy of
    /// a global context otherwise. In the latter case the function also assigns an user to this context.
    ContextMutablePtr makeQueryContext() const { return makeQueryContext(getClientInfo()); }
    ContextMutablePtr makeQueryContext(const ClientInfo & query_client_info) const;
    ContextMutablePtr makeQueryContext(ClientInfo && query_client_info) const;

    /// Releases the currently used session ID so it becomes available for reuse by another session.
    void releaseSessionID();

    /// Closes and removes session
    void closeSession(const String & session_id);

private:
    std::shared_ptr<SessionLog> getSessionLog() const;
    ContextMutablePtr makeQueryContextImpl(const ClientInfo * client_info_to_copy, ClientInfo * client_info_to_move) const;
    void recordLoginSucess(ContextPtr login_context) const;


    mutable bool notified_session_log_about_login = false;
    const UUID auth_id;
    const ContextPtr global_context;

    /// ClientInfo that will be copied to a session context when it's created.
    std::optional<ClientInfo> prepared_client_info;

    mutable UserPtr user;
    std::optional<UUID> user_id;

    ContextMutablePtr session_context;
    mutable bool query_context_created = false;

    std::shared_ptr<NamedSessionData> named_session;
    bool named_session_created = false;

    SessionTracker::SessionTrackerHandle session_tracker_handle;

    Poco::Logger * log = nullptr;
};

}