1 ////////////////////////////////////////////////////////////////////////////
3 // Copyright 2016 Realm Inc.
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
17 ////////////////////////////////////////////////////////////////////////////
19 #ifndef REALM_OS_SYNC_USER_HPP
20 #define REALM_OS_SYNC_USER_HPP
24 #include <unordered_map>
28 #include "util/atomic_shared_ptr.hpp"
30 #include <realm/util/optional.hpp>
36 // A superclass that bindings can inherit from in order to store information
37 // upon a `SyncUser` object.
38 class SyncUserContext {
40 virtual ~SyncUserContext() = default;
43 using SyncUserContextFactory = std::function<std::shared_ptr<SyncUserContext>()>;
45 // A struct that uniquely identifies a user. Consists of ROS identity and auth server URL.
46 struct SyncUserIdentifier {
48 std::string auth_server_url;
50 bool operator==(const SyncUserIdentifier& other) const
52 return user_id == other.user_id && auth_server_url == other.auth_server_url;
56 // A `SyncUser` represents a single user account. Each user manages the sessions that
57 // are associated with it.
59 friend class SyncSession;
61 enum class TokenType {
72 // Don't use this directly; use the `SyncManager` APIs. Public for use with `make_shared`.
73 SyncUser(std::string refresh_token,
75 util::Optional<std::string> server_url,
76 util::Optional<std::string> local_identity=none,
77 TokenType token_type=TokenType::Normal);
79 // Return a list of all sessions belonging to this user.
80 std::vector<std::shared_ptr<SyncSession>> all_sessions();
82 // Return a session for a given on disk path.
83 // In most cases, bindings shouldn't expose this to consumers, since the on-disk
84 // path for a synced Realm is an opaque implementation detail. This API is retained
85 // for testing purposes, and for bindings for consumers that are servers or tools.
86 std::shared_ptr<SyncSession> session_for_on_disk_path(const std::string& path);
88 // Update the user's refresh token. If the user is logged out, it will log itself back in.
89 // Note that this is called by the SyncManager, and should not be directly called.
90 void update_refresh_token(std::string token);
92 // Log the user out and mark it as such. This will also close its associated Sessions.
95 // Whether the user has administrator privileges.
96 bool is_admin() const noexcept
98 return m_token_type == TokenType::Admin || m_is_admin;
101 TokenType token_type() const noexcept
106 // Specify whether the user has administrator privileges.
107 // Note that this is an internal flag meant for bindings to communicate information
108 // originating from the server. It is *NOT* possible to unilaterally change a user's
109 // administrator status from the client through this or any other API.
110 void set_is_admin(bool);
112 std::string identity() const noexcept
117 const std::string& server_url() const noexcept
122 const std::string& local_identity() const noexcept
124 return m_local_identity;
127 std::string refresh_token() const;
130 std::shared_ptr<SyncUserContext> binding_context() const
132 return m_binding_context.load();
135 // Register a session to this user.
136 // A registered session will be bound at the earliest opportunity: either
137 // immediately, or upon the user becoming Active.
138 // Note that this is called by the SyncManager, and should not be directly called.
139 void register_session(std::shared_ptr<SyncSession>);
141 // Optionally set a context factory. If so, must be set before any sessions are created.
142 static void set_binding_context_factory(SyncUserContextFactory factory);
144 // Internal APIs. Do not call.
145 void register_management_session(const std::string&);
146 void register_permission_session(const std::string&);
149 static SyncUserContextFactory s_binding_context_factory;
150 static std::mutex s_binding_context_factory_mutex;
154 util::AtomicSharedPtr<SyncUserContext> m_binding_context;
156 // A locally assigned UUID intended to provide a level of indirection for various features.
157 std::string m_local_identity;
159 std::weak_ptr<SyncSession> m_management_session;
160 std::weak_ptr<SyncSession> m_permission_session;
162 // The auth server URL associated with this user. Set upon creation. The empty string for
164 std::string m_server_url;
166 // Mark the user as invalid, since a fatal user-related error was encountered.
169 mutable std::mutex m_mutex;
171 // The token type of the user.
172 // FIXME: remove this flag once bindings take responsible for admin token users
173 TokenType m_token_type;
177 // The user's refresh token.
178 std::string m_refresh_token;
179 // Set by the server. The unique ID of the user account on the Realm Object Server.
180 std::string m_identity;
182 // Sessions are owned by the SyncManager, but the user keeps a map of weak references
184 std::unordered_map<std::string, std::weak_ptr<SyncSession>> m_sessions;
186 // Waiting sessions are those that should be asked to connect once this user is logged in.
187 std::unordered_map<std::string, std::weak_ptr<SyncSession>> m_waiting_sessions;
193 template<> struct hash<realm::SyncUserIdentifier> {
194 size_t operator()(realm::SyncUserIdentifier const&) const;
198 #endif // REALM_OS_SYNC_USER_HPP