Files
POCloud-iOS/Pods/Realm/include/sync/sync_user.hpp
Patrick McDonagh 909925a334 Initial Commit
2018-05-25 12:56:07 -05:00

199 lines
6.3 KiB
C++

////////////////////////////////////////////////////////////////////////////
//
// Copyright 2016 Realm Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////
#ifndef REALM_OS_SYNC_USER_HPP
#define REALM_OS_SYNC_USER_HPP
#include <string>
#include <memory>
#include <unordered_map>
#include <vector>
#include <mutex>
#include "util/atomic_shared_ptr.hpp"
#include <realm/util/optional.hpp>
namespace realm {
class SyncSession;
// A superclass that bindings can inherit from in order to store information
// upon a `SyncUser` object.
class SyncUserContext {
public:
virtual ~SyncUserContext() = default;
};
using SyncUserContextFactory = std::function<std::shared_ptr<SyncUserContext>()>;
// A struct that uniquely identifies a user. Consists of ROS identity and auth server URL.
struct SyncUserIdentifier {
std::string user_id;
std::string auth_server_url;
bool operator==(const SyncUserIdentifier& other) const
{
return user_id == other.user_id && auth_server_url == other.auth_server_url;
}
};
// A `SyncUser` represents a single user account. Each user manages the sessions that
// are associated with it.
class SyncUser {
friend class SyncSession;
public:
enum class TokenType {
Normal,
Admin,
};
enum class State {
LoggedOut,
Active,
Error,
};
// Don't use this directly; use the `SyncManager` APIs. Public for use with `make_shared`.
SyncUser(std::string refresh_token,
std::string identity,
util::Optional<std::string> server_url,
util::Optional<std::string> local_identity=none,
TokenType token_type=TokenType::Normal);
// Return a list of all sessions belonging to this user.
std::vector<std::shared_ptr<SyncSession>> all_sessions();
// Return a session for a given on disk path.
// In most cases, bindings shouldn't expose this to consumers, since the on-disk
// path for a synced Realm is an opaque implementation detail. This API is retained
// for testing purposes, and for bindings for consumers that are servers or tools.
std::shared_ptr<SyncSession> session_for_on_disk_path(const std::string& path);
// Update the user's refresh token. If the user is logged out, it will log itself back in.
// Note that this is called by the SyncManager, and should not be directly called.
void update_refresh_token(std::string token);
// Log the user out and mark it as such. This will also close its associated Sessions.
void log_out();
// Whether the user has administrator privileges.
bool is_admin() const noexcept
{
return m_token_type == TokenType::Admin || m_is_admin;
}
TokenType token_type() const noexcept
{
return m_token_type;
}
// Specify whether the user has administrator privileges.
// Note that this is an internal flag meant for bindings to communicate information
// originating from the server. It is *NOT* possible to unilaterally change a user's
// administrator status from the client through this or any other API.
void set_is_admin(bool);
std::string const& identity() const noexcept
{
return m_identity;
}
const std::string& server_url() const noexcept
{
return m_server_url;
}
const std::string& local_identity() const noexcept
{
return m_local_identity;
}
std::string refresh_token() const;
State state() const;
std::shared_ptr<SyncUserContext> binding_context() const
{
return m_binding_context.load();
}
// Register a session to this user.
// A registered session will be bound at the earliest opportunity: either
// immediately, or upon the user becoming Active.
// Note that this is called by the SyncManager, and should not be directly called.
void register_session(std::shared_ptr<SyncSession>);
// Optionally set a context factory. If so, must be set before any sessions are created.
static void set_binding_context_factory(SyncUserContextFactory factory);
// Internal APIs. Do not call.
void register_management_session(const std::string&);
void register_permission_session(const std::string&);
private:
static SyncUserContextFactory s_binding_context_factory;
static std::mutex s_binding_context_factory_mutex;
State m_state;
util::AtomicSharedPtr<SyncUserContext> m_binding_context;
// A locally assigned UUID intended to provide a level of indirection for various features.
std::string m_local_identity;
std::weak_ptr<SyncSession> m_management_session;
std::weak_ptr<SyncSession> m_permission_session;
// The auth server URL associated with this user. Set upon creation. The empty string for
// auth token users.
std::string m_server_url;
// Mark the user as invalid, since a fatal user-related error was encountered.
void invalidate();
mutable std::mutex m_mutex;
// The token type of the user.
// FIXME: remove this flag once bindings take responsible for admin token users
TokenType m_token_type;
bool m_is_admin;
// The user's refresh token.
std::string m_refresh_token;
// Set by the server. The unique ID of the user account on the Realm Object Server.
std::string m_identity;
// Sessions are owned by the SyncManager, but the user keeps a map of weak references
// to them.
std::unordered_map<std::string, std::weak_ptr<SyncSession>> m_sessions;
// Waiting sessions are those that should be asked to connect once this user is logged in.
std::unordered_map<std::string, std::weak_ptr<SyncSession>> m_waiting_sessions;
};
}
namespace std {
template<> struct hash<realm::SyncUserIdentifier> {
size_t operator()(realm::SyncUserIdentifier const&) const;
};
}
#endif // REALM_OS_SYNC_USER_HPP