using Sockeye.Biz; namespace Sockeye.Api.ControllerHelpers { /// /// Contains the current status of the server /// is injected everywhere for routes and others to check /// public class ApiServerState { //private ILogger log = Sockeye.Util.ApplicationLogging.CreateLogger(); public enum ServerState { ///Unknown state, used for parsing UNKNOWN = 0, ///No access for anyone API completely locked down. Not set by user but rather by internal server operations like importing or backup. Closed = 1, ///Access only to SuperUser account for migration from Rockfish MigrateMode = 2, ///Access only to API Operations routes. Can be set by Ops user OpsOnly = 3, ///Open for all users (default). Can be set by Ops user Open = 4 } private ServerState _currentState = ServerState.Closed; private ServerState _priorState = ServerState.Closed; private string _reason = string.Empty; private string _priorReason = string.Empty; private bool SYSTEM_LOCK = false;//really this is a license lock but not called that public ApiServerState() { } internal void SetSystemLock(string reason) { //Lock down the server for license related issue //Only SuperUser account (id=1) can login or do anything, treats as if server was set to closed even if they change it to open //only way to reset it is to fetch a valid license // This is set to locked in TWO ways: // 1) By CoreJobSweeper *if* the user count is mismatched to the license likely due to Users messing directly with the DB //trying to circumvent licensing // 2) By License::InitializeAsync upon finding user count mismatch or expired license key // and initializeasync is called on boot up or when a new key is downloaded and installed only // var msg = $"{reason}\r\nLogin as SuperUser to start evaluation / install license"; SetState(ServerState.OpsOnly, msg); SYSTEM_LOCK = true; } //WARNING: if in future this is used for anything other than a license then it will need to see if locked for another reason before unlocking //recommend putting a code number in the reason then looking to see if it has the matching code internal void ClearSystemLock() { SYSTEM_LOCK = false; SetState(ServerState.Open, ""); } /// /// Set the server state /// /// /// public void SetState(ServerState newState, string reason) { //No changes allowed during a system lock if (SYSTEM_LOCK) return; _reason = reason;//keep the reason even if the state doesn't change if (newState == _currentState) return; //Here we will likely need to trigger a notification to users if the state is going to be shutting down or is shut down _priorState = _currentState;//keep the prior state so it can be resumed easily _priorReason = _reason;//keep the original reason _currentState = newState; } /// /// Get the current state of the server /// /// public ServerState GetState() { return _currentState; } /// /// Get the current reason for the state of the server /// /// public string Reason { get { if (_currentState == ServerState.Open) { return ""; } else { return $"\"{_reason}\""; // if (_currentState == ServerState.Closed) // return $"{ Sockeye.Biz.TranslationBiz.GetDefaultTranslationAsync("ErrorAPI2000").Result}\r\n{_reason}"; // else //opsonly // return $"{ Sockeye.Biz.TranslationBiz.GetDefaultTranslationAsync("ErrorAPI2001").Result}\r\n{_reason}"; } } } //get the api error code associated with the server state public ApiErrorCode ApiErrorCode { get { switch (_currentState) { case ServerState.Open: throw new System.NotSupportedException("ApiServerState:ApiErrorCode - No error code is associated with server state OPEN"); case ServerState.OpsOnly: return ApiErrorCode.API_OPS_ONLY; case ServerState.Closed: return ApiErrorCode.API_CLOSED; } throw new System.NotSupportedException("ApiServerState:ApiErrorCode - No error code is associated with server state UNKNOWN"); } } public void SetOpsOnly(string reason) { //No changes allowed during a system lock if (SYSTEM_LOCK) return; SetState(ServerState.OpsOnly, reason); } public void SetClosed(string reason) { //No changes allowed during a system lock if (SYSTEM_LOCK) return; SetState(ServerState.Closed, reason); } public void SetOpen() { //No changes allowed during a system lock if (SYSTEM_LOCK) return; SetState(ServerState.Open, string.Empty); } public void ResumePriorState() { //No changes allowed during a system lock if (SYSTEM_LOCK) return; SetState(_priorState, _priorReason); } public bool IsOpsOnly { get { return _currentState == ServerState.OpsOnly && !SYSTEM_LOCK; } } public bool IsOpen { get { return _currentState != ServerState.Closed && _currentState != ServerState.OpsOnly && !SYSTEM_LOCK; } } public bool IsClosed { get { return _currentState == ServerState.Closed || SYSTEM_LOCK; } } // public bool IsOpenOrOpsOnly // { // get // { // return (IsOpen || IsOpsOnly) && !SYSTEM_LOCK; // } // } public bool IsSystemLocked { get { return SYSTEM_LOCK; } } }//eoc }//eons