203 lines
8.1 KiB
C++
203 lines
8.1 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef MOZILLA_IDENTITYCREDENTIALSTORAGESERVICE_H_
|
|
#define MOZILLA_IDENTITYCREDENTIALSTORAGESERVICE_H_
|
|
|
|
#include "ErrorList.h"
|
|
#include "mozilla/AlreadyAddRefed.h"
|
|
#include "mozilla/dom/FlippedOnce.h"
|
|
#include "mozilla/Monitor.h"
|
|
#include "mozilla/OriginAttributes.h"
|
|
#include "mozIStorageConnection.h"
|
|
#include "mozIStorageFunction.h"
|
|
#include "mozilla/dom/IPCIdentityCredential.h"
|
|
#include "nsIAsyncShutdown.h"
|
|
#include "nsIFile.h"
|
|
#include "nsIIdentityCredentialStorageService.h"
|
|
#include "nsIObserver.h"
|
|
#include "nsISupports.h"
|
|
#include "nsThreadUtils.h"
|
|
|
|
namespace mozilla {
|
|
|
|
class IdentityCredentialStorageService final
|
|
: public nsIIdentityCredentialStorageService,
|
|
public nsIObserver,
|
|
public nsIAsyncShutdownBlocker {
|
|
public:
|
|
NS_DECL_THREADSAFE_ISUPPORTS
|
|
NS_DECL_NSIIDENTITYCREDENTIALSTORAGESERVICE
|
|
NS_DECL_NSIOBSERVER
|
|
NS_DECL_NSIASYNCSHUTDOWNBLOCKER
|
|
|
|
// Returns the singleton instance. Used by the component manager
|
|
static already_AddRefed<IdentityCredentialStorageService> GetSingleton();
|
|
|
|
// Singletons shouldn't have copy constructors or assignment operators
|
|
IdentityCredentialStorageService(const IdentityCredentialStorageService&) =
|
|
delete;
|
|
IdentityCredentialStorageService& operator=(
|
|
const IdentityCredentialStorageService&) = delete;
|
|
|
|
private:
|
|
IdentityCredentialStorageService()
|
|
: mMonitor("mozilla::IdentityCredentialStorageService::mMonitor"),
|
|
mPendingWrites(0) {};
|
|
~IdentityCredentialStorageService() = default;
|
|
|
|
// Spins up the service. This includes firing off async work in a worker
|
|
// thread. This should always be called before other use of the service to
|
|
// prevent deadlock.
|
|
nsresult Init();
|
|
|
|
// Wait (non-blocking) until the service is fully initialized. We may be
|
|
// waiting for that async work started by Init().
|
|
nsresult WaitForInitialization();
|
|
|
|
// Utility function to grab the correct barrier this service needs to shut
|
|
// down by
|
|
already_AddRefed<nsIAsyncShutdownClient> GetAsyncShutdownBarrier() const;
|
|
|
|
// Called to indicate to the async shutdown service that we are all wrapped
|
|
// up. This also spins down the worker thread, since it is called after all
|
|
// disk database connections are closed.
|
|
void Finalize();
|
|
|
|
// Utility function to make sure a principal is an acceptable primary (RP)
|
|
// principal
|
|
static nsresult ValidatePrincipal(nsIPrincipal* aPrincipal);
|
|
|
|
// Helper functions to initialize the database connections. Also makes sure
|
|
// the tables are present and have up to date schemas. If file is nullptr,
|
|
// use the in-memory database "icsprivatedb". If retry is true, allow a retry
|
|
// on failure.
|
|
nsresult GetMemoryDatabaseConnection();
|
|
nsresult GetDiskDatabaseConnection();
|
|
static nsresult GetDatabaseConnectionInternal(
|
|
mozIStorageConnection** aDatabase, nsIFile* aFile, bool aRetry);
|
|
|
|
// Helper function for the Get*DatabaseConnection functions to ensure the
|
|
// tables are present and have up to date schemas.
|
|
static nsresult EnsureTable(mozIStorageConnection* aDatabase);
|
|
|
|
// Grab all data from the disk database and insert it into the memory
|
|
// database/ This is used at start up
|
|
nsresult LoadMemoryTableFromDisk();
|
|
nsresult LoadLightweightMemoryTableFromDisk();
|
|
nsresult LoadHeavyweightMemoryTableFromDisk();
|
|
|
|
// Used to (thread-safely) track how many operations have been launched to the
|
|
// worker thread so that we can wait for it to hit zero before close the disk
|
|
// database connection
|
|
void IncrementPendingWrites();
|
|
void DecrementPendingWrites();
|
|
|
|
// Helper functions for database writes.
|
|
// We have helper functions here for all operations we perform on the
|
|
// databases that invlolve writes. These are split out and take a connection
|
|
// as an argument because we have to write to both the memory database and
|
|
// the disk database, where we only read from the memory database after
|
|
// initialization. See nsIIdentityCredentialStorageService.idl for more info
|
|
// on these functions' semantics
|
|
|
|
// Upsert == Update or Insert! Uses some nice SQLite syntax to make this easy.
|
|
static nsresult UpsertData(mozIStorageConnection* aDatabaseConnection,
|
|
nsIPrincipal* aRPPrincipal,
|
|
nsIPrincipal* aIDPPrincipal,
|
|
nsACString const& aCredentialID, bool aRegistered,
|
|
bool aAllowLogout);
|
|
|
|
static nsresult DeleteData(mozIStorageConnection* aDatabaseConnection,
|
|
nsIPrincipal* aRPPrincipal,
|
|
nsIPrincipal* aIDPPrincipal,
|
|
nsACString const& aCredentialID);
|
|
|
|
static nsresult DisconnectData(mozIStorageConnection* aDatabaseConnection,
|
|
nsIPrincipal* aRPPrincipal,
|
|
nsIPrincipal* aIDPPrincipal);
|
|
|
|
static nsresult ClearData(mozIStorageConnection* aDatabaseConnection);
|
|
|
|
static nsresult UpsertLightweightData(
|
|
mozIStorageConnection* aDatabaseConnection,
|
|
const dom::IPCIdentityCredential& aData);
|
|
|
|
static nsresult DeleteLightweightData(
|
|
mozIStorageConnection* aDatabaseConnection,
|
|
const dom::IPCIdentityCredential& aData);
|
|
|
|
static nsresult DeleteDataFromOriginAttributesPattern(
|
|
mozIStorageConnection* aDatabaseConnection,
|
|
OriginAttributesPattern const& aOriginAttributesPattern);
|
|
|
|
static nsresult DeleteDataFromTimeRange(
|
|
mozIStorageConnection* aDatabaseConnection, int64_t aStart, int64_t aEnd);
|
|
|
|
static nsresult DeleteDataFromPrincipal(
|
|
mozIStorageConnection* aDatabaseConnection, nsIPrincipal* aPrincipal);
|
|
|
|
static nsresult DeleteDataFromBaseDomain(
|
|
mozIStorageConnection* aDatabaseConnection,
|
|
nsACString const& aBaseDomain);
|
|
|
|
// Database connections. Guaranteed to be non-null and working once
|
|
// initialized and not-yet finalized
|
|
RefPtr<mozIStorageConnection> mDiskDatabaseConnection; // Worker thread only
|
|
RefPtr<mozIStorageConnection>
|
|
mMemoryDatabaseConnection; // Main thread only after initialization,
|
|
// worker thread only before initialization.
|
|
|
|
// Worker thread. This should be a valid thread after Init() returns and be
|
|
// destroyed when we finalize
|
|
nsCOMPtr<nsISerialEventTarget> mBackgroundThread; // main thread only
|
|
|
|
// The database file handle. We can only create this in the main thread and
|
|
// need it in the worker to perform blocking disk IO. So we put it on this,
|
|
// since we pass this to the worker anyway
|
|
RefPtr<nsIFile> mDatabaseFile; // initialized in the main thread, read-only
|
|
// in worker thread
|
|
|
|
// Service state management. We protect these variables with a monitor. This
|
|
// monitor is also used to signal the completion of initialization and
|
|
// finalization performed in the worker thread.
|
|
Monitor mMonitor;
|
|
FlippedOnce<false> mInitialized MOZ_GUARDED_BY(mMonitor);
|
|
FlippedOnce<false> mErrored MOZ_GUARDED_BY(mMonitor);
|
|
FlippedOnce<false> mShuttingDown MOZ_GUARDED_BY(mMonitor);
|
|
FlippedOnce<false> mFinalized MOZ_GUARDED_BY(mMonitor);
|
|
uint32_t mPendingWrites MOZ_GUARDED_BY(mMonitor);
|
|
};
|
|
|
|
class OriginAttrsPatternMatchOriginSQLFunction final
|
|
: public mozIStorageFunction {
|
|
NS_DECL_ISUPPORTS
|
|
NS_DECL_MOZISTORAGEFUNCTION
|
|
|
|
explicit OriginAttrsPatternMatchOriginSQLFunction(
|
|
OriginAttributesPattern const& aPattern)
|
|
: mPattern(aPattern) {}
|
|
OriginAttrsPatternMatchOriginSQLFunction() = delete;
|
|
|
|
private:
|
|
~OriginAttrsPatternMatchOriginSQLFunction() = default;
|
|
|
|
OriginAttributesPattern mPattern;
|
|
};
|
|
|
|
class PrivateBrowsingOriginSQLFunction final : public mozIStorageFunction {
|
|
NS_DECL_ISUPPORTS
|
|
NS_DECL_MOZISTORAGEFUNCTION
|
|
|
|
PrivateBrowsingOriginSQLFunction() = default;
|
|
|
|
private:
|
|
~PrivateBrowsingOriginSQLFunction() = default;
|
|
};
|
|
|
|
} // namespace mozilla
|
|
|
|
#endif /* MOZILLA_IDENTITYCREDENTIALSTORAGESERVICE_H_ */
|