private BWebServiceResponse OnRequest_Internal(HttpListenerContext _Context, Action <string> _ErrorMessageAction = null) { bIsInternalCall = BWebUtilities.DoesContextContainHeader(out List <string> ICHVs, out string _, _Context, "internal-call-secret") && BUtility.CheckAndGetFirstStringFromList(ICHVs, out string ICH) && ICH == CommonData.INTERNAL_CALL_PRIVATE_KEY; if (_Context.Request.HttpMethod != "DELETE") { _ErrorMessageAction?.Invoke("User_DeleteUserAccessMethod_ForUser: DELETE method is accepted. But received request method: " + _Context.Request.HttpMethod); return(BWebResponse.MethodNotAllowed("DELETE methods is accepted. But received request method: " + _Context.Request.HttpMethod)); } RequestedUserID = RestfulUrlParameters[RestfulUrlParameter_UsersKey]; RequestedAuthMethodKey = WebUtility.UrlDecode(RestfulUrlParameters[RestfulUrlParameter_AccessMethodKey]); if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, UserDBEntry.DBSERVICE_USERS_TABLE(), RequestedUserID, _ErrorMessageAction)) { return(BWebResponse.InternalError("Atomic operation control has failed.")); } var Result = DeleteAccessMethodForUser(_Context, out bool bSetClearanceForApiKey, out string ApiKey, _ErrorMessageAction); Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, UserDBEntry.DBSERVICE_USERS_TABLE(), RequestedUserID, _ErrorMessageAction); if (bSetClearanceForApiKey) { Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_API_KEY + ":" + ApiKey, _ErrorMessageAction); } return(Result); }
public static bool GetProcessedFile( WebServiceBaseTimeoutable _Request, ENodeType _FileType, IBDatabaseServiceInterface _DatabaseService, IBFileServiceInterface _FileService, string _CadFileStorageBucketName, string _ModelID, int _RevisionIndex, out BWebServiceResponse _SuccessResponse, out BWebServiceResponse _FailureResponse, Action <string> _ErrorMessageAction = null) { _SuccessResponse = BWebResponse.InternalError(""); if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(_Request.InnerProcessor, ModelDBEntry.DBSERVICE_MODELS_TABLE(), _ModelID, _ErrorMessageAction)) { _FailureResponse = BWebResponse.InternalError("Atomic operation control has failed."); return(false); } var bResult = GetProcessedFile_Internal( _FileType, _DatabaseService, _FileService, _CadFileStorageBucketName, _ModelID, _RevisionIndex, out _SuccessResponse, out _FailureResponse, _ErrorMessageAction); Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(_Request.InnerProcessor, ModelDBEntry.DBSERVICE_MODELS_TABLE(), _ModelID, _ErrorMessageAction); return(bResult); }
private BWebServiceResponse OnRequest_Internal(HttpListenerContext _Context, Action <string> _ErrorMessageAction = null) { if (_Context.Request.HttpMethod != "POST" && _Context.Request.HttpMethod != "DELETE") { _ErrorMessageAction?.Invoke("User_UpdateDeleteBaseRight_ForUser: POST and DELETE methods are accepted. But received request method: " + _Context.Request.HttpMethod); return(BWebResponse.MethodNotAllowed("POST and DELETE methods are accepted. But received request method: " + _Context.Request.HttpMethod)); } RequestedUserID = RestfulUrlParameters[RestfulUrlParameter_UsersKey]; RequestedBaseRightWildcard = WebUtility.UrlDecode(RestfulUrlParameters[RestfulUrlParameter_BaseAccessRightsKey]); RequestedBaseRightWildcard_Regex = BUtility.WildCardToRegular(RequestedBaseRightWildcard); if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, UserDBEntry.DBSERVICE_USERS_TABLE(), RequestedUserID, _ErrorMessageAction)) { return(BWebResponse.InternalError("Atomic operation control has failed.")); } BWebServiceResponse Result; if (_Context.Request.HttpMethod == "POST") { Result = UpdateBaseRightForUser(_Context, _ErrorMessageAction); } else { Result = DeleteBaseRightForUser(_Context, _ErrorMessageAction); } Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, UserDBEntry.DBSERVICE_USERS_TABLE(), RequestedUserID, _ErrorMessageAction); return(Result); }
private BWebServiceResponse OnRequest_Internal(HttpListenerContext _Context, Action <string> _ErrorMessageAction = null) { if (_Context.Request.HttpMethod != "GET" && _Context.Request.HttpMethod != "PUT") { _ErrorMessageAction?.Invoke("User_AddListBaseRights_ForUser: GET and PUT methods are accepted. But received request method: " + _Context.Request.HttpMethod); return(BWebResponse.MethodNotAllowed("GET and PUT methods are accepted. But received request method: " + _Context.Request.HttpMethod)); } RequestedUserID = RestfulUrlParameters[RestfulUrlParameter_UsersKey]; if (_Context.Request.HttpMethod == "GET") { return(ListBaseRightsForUser(_ErrorMessageAction)); } //else { if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, UserDBEntry.DBSERVICE_USERS_TABLE(), RequestedUserID, _ErrorMessageAction)) { return(BWebResponse.InternalError("Atomic operation control has failed.")); } var Result = AddUpdateBaseRightsForUser(_Context, _ErrorMessageAction); Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, UserDBEntry.DBSERVICE_USERS_TABLE(), RequestedUserID, _ErrorMessageAction); return(Result); } }
private BWebServiceResponse OnRequest_Internal(HttpListenerContext _Context, Action <string> _ErrorMessageAction = null) { if (_Context.Request.HttpMethod != "GET" && _Context.Request.HttpMethod != "PUT") { _ErrorMessageAction?.Invoke("User_CreateListAccessMethods_ForUser: GET and PUT methods are accepted. But received request method: " + _Context.Request.HttpMethod); return(BWebResponse.MethodNotAllowed("GET and PUT methods are accepted. But received request method: " + _Context.Request.HttpMethod)); } RequestedUserID = RestfulUrlParameters[RestfulUrlParameter_UsersKey]; if (_Context.Request.HttpMethod == "GET") { return(ListAccessMethodsForUser(_ErrorMessageAction)); } //else { if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, UserDBEntry.DBSERVICE_USERS_TABLE(), RequestedUserID, _ErrorMessageAction)) { return(BWebResponse.InternalError("Atomic operation control has failed.")); } var Result = CreateAccessMethodForUser(_Context, out bool bSetClearanceForApiKey, out string ApiKey, _ErrorMessageAction); Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, UserDBEntry.DBSERVICE_USERS_TABLE(), RequestedUserID, _ErrorMessageAction); if (bSetClearanceForApiKey) { Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_API_KEY + ":" + ApiKey, _ErrorMessageAction); } return(Result); } }
private BWebServiceResponse OnRequest_Internal(HttpListenerContext _Context, Action <string> _ErrorMessageAction) { AuthorizedUser = ServiceUtilities.Common.Methods.GetAuthorizedRequester(_Context, _ErrorMessageAction); if (!AuthorizedUser.bParseSuccessful) { return(BWebResponse.InternalError(AuthorizedUser.ParseErrorMessage)); } if (_Context.Request.HttpMethod != "DELETE") { _ErrorMessageAction?.Invoke("Model_RemoveModelShare: DELETE method is accepted. But received request method: " + _Context.Request.HttpMethod); return(BWebResponse.MethodNotAllowed("DELETE method is accepted. But received request method: " + _Context.Request.HttpMethod)); } if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, ModelDBEntry.DBSERVICE_MODELS_TABLE(), RequestedModelID, _ErrorMessageAction)) { return(BWebResponse.InternalError("Atomic operation control has failed.")); } try { return(ProcessRequestLocked(_Context, _ErrorMessageAction)); } finally { Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, ModelDBEntry.DBSERVICE_MODELS_TABLE(), RequestedModelID, _ErrorMessageAction); } }
public void SetClearanceForObtained(Action <string> _ErrorMessageAction = null) { var WaitFor = new ManualResetEvent(false); var ParallelOperationsStack = new Stack <bool>(); int ParallelOperationsNumber = ClearanceObtainedFor.Count * AttributeTables.Length; for (var i = 0; i < ParallelOperationsNumber; i++) { ParallelOperationsStack.Push(true); } lock (ClearanceObtainedFor) { foreach (var MetadataKey in ClearanceObtainedFor) { for (var j = 0; j < AttributeTables.Length; j++) { var Table = AttributeTables[j]; BTaskWrapper.Run(() => { if (RequestOwnerProcessor.OwnerProcessor.TryGetTarget(out WebServiceBaseTimeoutableProcessor Processor)) { Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers( Processor, Table, MetadataKey, _ErrorMessageAction); } lock (ParallelOperationsStack) { ParallelOperationsStack.TryPop(out bool _); if (ParallelOperationsStack.Count == 0) { try { WaitFor.Set(); } catch (Exception) { } } } }); } } ClearanceObtainedFor.Clear(); } try { if (ParallelOperationsNumber > 0) { WaitFor.WaitOne(); } WaitFor.Close(); } catch (Exception) { } }
private bool UpdateUsersSharedModelsFields(List <string> _RelevantIdList, string _ModelID, Controller_Rights_Internal.EChangeUserRightsForModelType _Action, Action <string> _ErrorMessageAction) { foreach (var ChangeUserID in _RelevantIdList) { if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, UserDBEntry.DBSERVICE_USERS_TABLE(), ChangeUserID, _ErrorMessageAction)) { _ErrorMessageAction?.Invoke("PubSub_To_AuthService->UpdateUsersSharedModelsFields: Atomic operation control has failed for " + UserDBEntry.KEY_NAME_USER_ID + ": " + ChangeUserID); return(false); //Retry } try { if (!DatabaseService.GetItem( UserDBEntry.DBSERVICE_USERS_TABLE(), UserDBEntry.KEY_NAME_USER_ID, new BPrimitiveType(ChangeUserID), UserDBEntry.Properties, out JObject UserObject, _ErrorMessageAction)) { _ErrorMessageAction?.Invoke("PubSub_To_AuthService->UpdateUsersSharedModelsFields: Get user database entry operation has failed. User ID: " + ChangeUserID); return(false); //Retry } else if (UserObject != null) { bool bUpdateDB = false; var UserDeserialized = JsonConvert.DeserializeObject <UserDBEntry>(UserObject.ToString()); if (_Action == Controller_Rights_Internal.EChangeUserRightsForModelType.Add) { if (!UserDeserialized.UserSharedModels.Contains(_ModelID)) { UserDeserialized.UserSharedModels.Add(_ModelID); bUpdateDB = true; } } else if (_Action == Controller_Rights_Internal.EChangeUserRightsForModelType.Delete) { if (UserDeserialized.UserSharedModels.Contains(_ModelID)) { UserDeserialized.UserSharedModels.Remove(_ModelID); bUpdateDB = true; } } if (bUpdateDB) { if (!DatabaseService.UpdateItem(//Fire and forget is not suitable here since there are following calls after DB update which will change the DB structure UserDBEntry.DBSERVICE_USERS_TABLE(), UserDBEntry.KEY_NAME_USER_ID, new BPrimitiveType(ChangeUserID), JObject.Parse(JsonConvert.SerializeObject(UserDeserialized)), out JObject _, EBReturnItemBehaviour.DoNotReturn, null, _ErrorMessageAction)) { _ErrorMessageAction?.Invoke("PubSub_To_AuthService->UpdateUsersSharedModelsFields: Update user database entry operation has failed. User ID: " + ChangeUserID); return(false); //Retry } } } }
private BWebServiceResponse OnRequest_Internal(HttpListenerContext _Context, Action <string> _ErrorMessageAction) { AuthorizedUser = ServiceUtilities.Common.Methods.GetAuthorizedRequester(_Context, _ErrorMessageAction); if (!AuthorizedUser.bParseSuccessful) { return(BWebResponse.InternalError(AuthorizedUser.ParseErrorMessage)); } if (_Context.Request.HttpMethod != "GET" && _Context.Request.HttpMethod != "POST" && _Context.Request.HttpMethod != "DELETE") { _ErrorMessageAction?.Invoke("Model_GetUpdateDeleteRevision: GET, POST and DELETE methods are accepted. But received request method: " + _Context.Request.HttpMethod); return(BWebResponse.MethodNotAllowed("GET, POST and DELETE methods are accepted. But received request method: " + _Context.Request.HttpMethod)); } var RequestedModelName = WebUtility.UrlDecode(RestfulUrlParameters[RestfulUrlParameter_ModelsKey]); if (!CommonMethods.TryGettingModelID( DatabaseService, RequestedModelName, out RequestedModelID, out BWebServiceResponse FailureResponse, _ErrorMessageAction)) { return(FailureResponse); } if (!int.TryParse(RestfulUrlParameters[RestfulUrlParameter_RevisionsKey], out RequestedRevisionIndex)) { return(BWebResponse.BadRequest("Revision index must be an integer.")); } if (_Context.Request.HttpMethod == "GET") { return(GetRevisionInfo(_ErrorMessageAction)); } else { if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, ModelDBEntry.DBSERVICE_MODELS_TABLE(), RequestedModelID, _ErrorMessageAction)) { return(BWebResponse.InternalError("Atomic operation control has failed.")); } BWebServiceResponse Result; if (_Context.Request.HttpMethod == "DELETE") { Result = DeleteRevision(_Context, _ErrorMessageAction); } else { Result = UpdateRevisionInfo(_Context, _ErrorMessageAction); } Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, ModelDBEntry.DBSERVICE_MODELS_TABLE(), RequestedModelID, _ErrorMessageAction); return(Result); } }
public BWebServiceResponse OnRequest_Interruptable(HttpListenerContext _Context, Action <string> _ErrorMessageAction) { CachedContext = _Context; var Result = OnRequestCallback?.Invoke(_Context, _ErrorMessageAction); Controller_DeliveryEnsurer.Get().WaitUntilActionsCompleted(_Context, _ErrorMessageAction); if (OwnerProcessor.TryGetTarget(out WebServiceBaseTimeoutableProcessor StrongOwner)) { Controller_AtomicDBOperation.Get().WaitUntilSetClearancesCompleted(StrongOwner, _ErrorMessageAction); } return(Result ?? BWebResponse.InternalError("WebServiceBaseTimeoutableDeliveryEnsurerUserProcessor has failed.")); }
public static bool GetProcessedFileNode( WebServiceBaseTimeoutable _Request, ENodeType _FileType, IBDatabaseServiceInterface _DatabaseService, IBFileServiceInterface _FileService, string _CadFileStorageBucketName, string _ModelID, int _RevisionIndex, bool _bRootNodeRequested, ulong _NodeID, out BWebServiceResponse _SuccessResponse, out BWebServiceResponse _FailureResponse, Action <string> _ErrorMessageAction = null) { _SuccessResponse = BWebResponse.InternalError(""); uint StartIndex = 0, Size = 0; if (!_bRootNodeRequested) { Convert.UniqueIDToStartIndexAndSize(_NodeID, out StartIndex, out Size); if (StartIndex == 0 || Size == 0) { _FailureResponse = BWebResponse.BadRequest("Invalid Node ID."); return(false); } } if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(_Request.InnerProcessor, ModelDBEntry.DBSERVICE_MODELS_TABLE(), _ModelID, _ErrorMessageAction)) { _FailureResponse = BWebResponse.InternalError("Atomic operation control has failed."); return(false); } var bResult = GetProcessedFileNode_Internal( _FileType, _DatabaseService, _FileService, _CadFileStorageBucketName, _ModelID, _RevisionIndex, _bRootNodeRequested, StartIndex, Size, out _SuccessResponse, out _FailureResponse, _ErrorMessageAction); Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(_Request.InnerProcessor, ModelDBEntry.DBSERVICE_MODELS_TABLE(), _ModelID, _ErrorMessageAction); return(bResult); }
private BWebServiceResponse OnRequest_Internal(HttpListenerContext _Context, Action <string> _ErrorMessageAction = null) { if (_Context.Request.HttpMethod != "GET" && _Context.Request.HttpMethod != "POST" && _Context.Request.HttpMethod != "DELETE") { _ErrorMessageAction?.Invoke("User_GetUpdateDeleteUser: GET, POST and DELETE methods are accepted. But received request method: " + _Context.Request.HttpMethod); return(BWebResponse.MethodNotAllowed("GET, POST and DELETE methods are accepted. But received request method: " + _Context.Request.HttpMethod)); } RequestedUserID = RestfulUrlParameters[RestfulUrlParameter_UsersKey]; if (_Context.Request.HttpMethod == "GET") { return(GetUserInfo(_ErrorMessageAction)); } else if (_Context.Request.HttpMethod == "DELETE") { if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, UserDBEntry.DBSERVICE_USERS_TABLE(), RequestedUserID, _ErrorMessageAction)) { return(BWebResponse.InternalError("Atomic operation control has failed.")); } var Result = DeleteUser(_Context, out bool bSetClearanceForApiKeys, out List <string> ApiKeys, _ErrorMessageAction); Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, UserDBEntry.DBSERVICE_USERS_TABLE(), RequestedUserID, _ErrorMessageAction); if (bSetClearanceForApiKeys) { foreach (var ApiKey in ApiKeys) { Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_API_KEY + ":" + ApiKey, _ErrorMessageAction); } } return(Result); } //Atomicness handled inside the function return(UpdateUserInfo(_Context, _ErrorMessageAction)); }
private BWebServiceResponse UpdateUserInfo(HttpListenerContext _Context, Action <string> _ErrorMessageAction) { var UpdateFieldsUserEntry = new JObject(); var UpdateFieldsAuthEntry = new JObject(); string NewEmailChange = null; string NewUserNameChange = null; using (var InputStream = _Context.Request.InputStream) { using (var ResponseReader = new StreamReader(InputStream)) { try { var ParsedBody = JObject.Parse(ResponseReader.ReadToEnd()); foreach (var Child in ParsedBody) { if (UserDBEntry.UpdatableProperties.Contains(Child.Key)) { if (!UserDBEntry.UpdatablePropertiesValidityCheck[Child.Key](Child.Value)) { return(BWebResponse.BadRequest("Given field " + Child.Key + " has invalid value.")); } UpdateFieldsUserEntry[Child.Key] = Child.Value; } if (AuthDBEntry.UpdatableProperties.Contains(Child.Key)) { UpdateFieldsAuthEntry[Child.Key] = Child.Value; } if (Child.Key == UserDBEntry.USER_EMAIL_PROPERTY) { NewEmailChange = ((string)Child.Value).ToLower(); if (NewEmailChange.EndsWith(Controller_SSOAccessToken.EMAIL_USER_NAME_POSTFIX)) { return(BWebResponse.BadRequest("Email address cannot end with " + Controller_SSOAccessToken.EMAIL_USER_NAME_POSTFIX)); } } else if (Child.Key == UserDBEntry.USER_NAME_PROPERTY) { NewUserNameChange = (string)Child.Value; if (NewUserNameChange.EndsWith(Controller_SSOAccessToken.EMAIL_USER_NAME_POSTFIX)) { return(BWebResponse.BadRequest("Username cannot end with " + Controller_SSOAccessToken.EMAIL_USER_NAME_POSTFIX)); } } } } catch (Exception e) { _ErrorMessageAction?.Invoke("User_GetUpdateDeleteUser->UpdateUserInfo: Read request body stage has failed. Exception: " + e.Message + ", Trace: " + e.StackTrace); return(BWebResponse.BadRequest("Malformed request body. Request must be a valid json form.")); } } } if (UpdateFieldsUserEntry.Count == 0) { return(BWebResponse.BadRequest("Request does not contain any matching field with the expected structure.")); } bool bNewEmailAtomicnessSet = false, bNewUsernameAtomicnessSet = false; try { if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, UserDBEntry.DBSERVICE_USERS_TABLE(), RequestedUserID, _ErrorMessageAction)) { return(BWebResponse.InternalError("Atomic operation control has failed.")); } if (!DatabaseService.GetItem( UserDBEntry.DBSERVICE_USERS_TABLE(), UserDBEntry.KEY_NAME_USER_ID, new BPrimitiveType(RequestedUserID), UserDBEntry.Properties, out JObject UserObject, _ErrorMessageAction)) { return(BWebResponse.InternalError("Database fetch-user-info operation has failed.")); } if (UserObject == null) { return(BWebResponse.NotFound("User does not exist.")); } var bEmailExistInUserObject = UserObject.ContainsKey(UserDBEntry.USER_EMAIL_PROPERTY); var bUsernameExistInUserObject = UserObject.ContainsKey(UserDBEntry.USER_NAME_PROPERTY); if (NewEmailChange != null && bEmailExistInUserObject && (string)UserObject[UserDBEntry.USER_EMAIL_PROPERTY] == NewEmailChange) { NewEmailChange = null; UpdateFieldsUserEntry.Remove(UserDBEntry.USER_EMAIL_PROPERTY); UpdateFieldsAuthEntry.Remove(AuthDBEntry.USER_EMAIL_PROPERTY); } else if (NewEmailChange != null) { if (bEmailExistInUserObject && ((string)UserObject[UserDBEntry.USER_EMAIL_PROPERTY]).EndsWith(Controller_SSOAccessToken.EMAIL_USER_NAME_POSTFIX)) { return(BWebResponse.BadRequest("E-mail address cannot be changed for this account type.")); } if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_USER_EMAIL + ":" + NewEmailChange, _ErrorMessageAction)) { return(BWebResponse.InternalError("Atomic operation control has failed.")); } bNewEmailAtomicnessSet = true; if (!DatabaseService.GetItem( UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_USER_EMAIL, new BPrimitiveType(NewEmailChange), UniqueUserFieldsDBEntry.Properties, out JObject ExistenceCheck, _ErrorMessageAction)) { return(BWebResponse.InternalError("Database fetch-uniqueness-info operation has failed.")); } if (ExistenceCheck != null) { return(BWebResponse.Conflict("A user with same user e-mail already exists.")); } } if (NewUserNameChange != null && UserObject.ContainsKey(UserDBEntry.USER_NAME_PROPERTY) && (string)UserObject[UserDBEntry.USER_NAME_PROPERTY] == NewUserNameChange) { NewUserNameChange = null; UpdateFieldsUserEntry.Remove(UserDBEntry.USER_NAME_PROPERTY); UpdateFieldsAuthEntry.Remove(AuthDBEntry.USER_NAME_PROPERTY); } else if (NewUserNameChange != null) { if (bUsernameExistInUserObject && ((string)UserObject[UserDBEntry.USER_NAME_PROPERTY]).EndsWith(Controller_SSOAccessToken.EMAIL_USER_NAME_POSTFIX)) { return(BWebResponse.BadRequest("Username cannot be changed for this account type.")); } if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_USER_NAME + ":" + NewUserNameChange, _ErrorMessageAction)) { return(BWebResponse.InternalError("Atomic operation control has failed.")); } bNewUsernameAtomicnessSet = true; if (!DatabaseService.GetItem( UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_USER_NAME, new BPrimitiveType(NewUserNameChange), UniqueUserFieldsDBEntry.Properties, out JObject ExistenceCheck, _ErrorMessageAction)) { return(BWebResponse.InternalError("Database fetch-uniqueness-info operation has failed.")); } if (ExistenceCheck != null) { return(BWebResponse.Conflict("A user with same username already exists.")); } } return(UpdateUserInfo_Internal( _Context, NewEmailChange, NewUserNameChange, UserObject, UpdateFieldsUserEntry, UpdateFieldsAuthEntry, _ErrorMessageAction)); } finally { Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, UserDBEntry.DBSERVICE_USERS_TABLE(), RequestedUserID, _ErrorMessageAction); if (bNewEmailAtomicnessSet) { Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_USER_EMAIL + ":" + NewEmailChange, _ErrorMessageAction); } if (bNewUsernameAtomicnessSet) { Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_USER_NAME + ":" + NewUserNameChange, _ErrorMessageAction); } } }
private BWebServiceResponse DeleteUser(HttpListenerContext _Context, out bool _bSetClearanceForApiKeys, out List <string> _ApiKeys, Action <string> _ErrorMessageAction) { _bSetClearanceForApiKeys = false; _ApiKeys = new List <string>(); var UserKey = new BPrimitiveType(RequestedUserID); if (!DatabaseService.GetItem( UserDBEntry.DBSERVICE_USERS_TABLE(), UserDBEntry.KEY_NAME_USER_ID, UserKey, UserDBEntry.Properties, out JObject UserObject, _ErrorMessageAction)) { return(BWebResponse.InternalError("Database fetch-user-info operation has failed.")); } if (UserObject == null) { return(BWebResponse.NotFound("User does not exist.")); } var UserData = JsonConvert.DeserializeObject <UserDBEntry>(UserObject.ToString()); if (UserData.AuthMethods != null && UserData.AuthMethods.Count > 0) { foreach (var AMethod in UserData.AuthMethods) { string OldField = null; BPrimitiveType AuthMethodKey = null; switch (AMethod.Method) { case AuthMethod.Methods.USER_EMAIL_PASSWORD_METHOD: { AuthMethodKey = new BPrimitiveType(AMethod.UserEmail + AMethod.PasswordMD5); OldField = AMethod.UserEmail; break; } case AuthMethod.Methods.USER_NAME_PASSWORD_METHOD: { AuthMethodKey = new BPrimitiveType(AMethod.UserName + AMethod.PasswordMD5); OldField = AMethod.UserName; break; } case AuthMethod.Methods.API_KEY_METHOD: { AuthMethodKey = new BPrimitiveType(AMethod.ApiKey); _bSetClearanceForApiKeys = true; _ApiKeys.Add(AMethod.ApiKey); if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_API_KEY + ":" + AMethod.ApiKey, _ErrorMessageAction)) { return(BWebResponse.InternalError("Atomic operation control has failed.")); } break; } } if (AuthMethodKey != null) { Controller_DeliveryEnsurer.Get().DB_DeleteItem_FireAndForget( _Context, AuthDBEntry.DBSERVICE_AUTHMETHODS_TABLE(), AuthDBEntry.KEY_NAME_AUTH_DB_ENTRY, AuthMethodKey); MemoryService.DeleteKey(CommonData.MemoryQueryParameters, AuthDBEntry.KEY_NAME_AUTH_DB_ENTRY + AuthMethodKey.AsString, _ErrorMessageAction); } } } MemoryService.DeleteKey(CommonData.MemoryQueryParameters, UserBaseAccessMEntry.M_KEY_NAME_USER_ID + RequestedUserID, _ErrorMessageAction); Controller_DeliveryEnsurer.Get().DB_DeleteItem_FireAndForget( _Context, UserDBEntry.DBSERVICE_USERS_TABLE(), UserDBEntry.KEY_NAME_USER_ID, UserKey); Controller_UserActions.Get().BroadcastUserAction(new Action_UserDeleted ( RequestedUserID, UserData.UserEmail, UserData.UserName, UserData.UserModels, UserData.UserSharedModels ), _ErrorMessageAction); if (UserData.UserEmail != null && UserData.UserEmail.Length > 0) { Controller_DeliveryEnsurer.Get().DB_DeleteItem_FireAndForget( _Context, UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_USER_EMAIL, new BPrimitiveType(UserData.UserEmail)); } if (UserData.UserName != null && UserData.UserName.Length > 0) { Controller_DeliveryEnsurer.Get().DB_DeleteItem_FireAndForget( _Context, UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_USER_NAME, new BPrimitiveType(UserData.UserName)); } foreach (var ApiKey in _ApiKeys) { Controller_DeliveryEnsurer.Get().DB_DeleteItem_FireAndForget( _Context, UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_API_KEY, new BPrimitiveType(ApiKey)); } return(BWebResponse.StatusOK("User has been deleted.")); }
private BWebServiceResponse CreateAccessMethodForUser(HttpListenerContext _Context, out bool _bSetClearanceForApiKey, out string _ApiKey, Action <string> _ErrorMessageAction) { _bSetClearanceForApiKey = false; _ApiKey = null; AuthMethod NewMethod = null; using (var InputStream = _Context.Request.InputStream) { using (var ResponseReader = new StreamReader(InputStream)) { try { NewMethod = JsonConvert.DeserializeObject <AuthMethod>(ResponseReader.ReadToEnd()); } catch (Exception e) { _ErrorMessageAction?.Invoke("User_CreateListAccessMethods_ForUser->CreateAccessMethodForUser: Read request body stage has failed. Exception: " + e.Message + ", Trace: " + e.StackTrace); return(BWebResponse.BadRequest("Malformed request body. Request must be a valid json form.")); } } } if (NewMethod == null) { return(BWebResponse.BadRequest("Request body does not contain all mandatory information or some fields are invalid.")); } BPrimitiveType AuthMethodKey = null; if (NewMethod.Method == AuthMethod.Methods.USER_EMAIL_PASSWORD_METHOD) { if (NewMethod.UserEmail == null || NewMethod.PasswordMD5 == null || NewMethod.UserEmail.Length == 0 || NewMethod.PasswordMD5.Length == 0) { return(BWebResponse.BadRequest("Request body does not contain all fields.")); } AuthMethodKey = new BPrimitiveType(NewMethod.UserEmail + NewMethod.PasswordMD5); } else if (NewMethod.Method == AuthMethod.Methods.USER_NAME_PASSWORD_METHOD) { if (NewMethod.UserName == null || NewMethod.PasswordMD5 == null || NewMethod.UserName.Length == 0 || NewMethod.PasswordMD5.Length == 0) { return(BWebResponse.BadRequest("Request body does not contain all fields.")); } AuthMethodKey = new BPrimitiveType(NewMethod.UserName + NewMethod.PasswordMD5); } else if (NewMethod.Method == AuthMethod.Methods.API_KEY_METHOD) { int ExistenceTrial = 0; while (ExistenceTrial < 3) { if (!BUtility.CalculateStringMD5(BUtility.RandomString(32, false), out NewMethod.ApiKey, _ErrorMessageAction)) { return(BWebResponse.InternalError("Hashing error.")); } NewMethod.ApiKey = NewMethod.ApiKey.ToUpper(); if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_API_KEY + ":" + NewMethod.ApiKey, _ErrorMessageAction)) { return(BWebResponse.InternalError("Atomic operation control has failed.")); } if (!DatabaseService.UpdateItem( UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_API_KEY, new BPrimitiveType(NewMethod.ApiKey), new JObject() { [UserDBEntry.KEY_NAME_USER_ID] = RequestedUserID }, out JObject _, EBReturnItemBehaviour.DoNotReturn, DatabaseService.BuildAttributeNotExistCondition(UniqueUserFieldsDBEntry.KEY_NAME_API_KEY), _ErrorMessageAction)) { Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_API_KEY + ":" + NewMethod.ApiKey, _ErrorMessageAction); ExistenceTrial++; } else { _bSetClearanceForApiKey = true; _ApiKey = NewMethod.ApiKey; break; } }
static void Main() { Console.WriteLine("Initializing the service..."); #if (Debug || DEBUG) if (!ServicesDebugOnlyUtilities.CalledFromMain()) { return; } #endif // In case of a cloud component dependency or environment variable is added/removed; // Relative terraform script and microservice-dependency-map.cs must be updated as well. /* * Common initialization step */ if (!BServiceInitializer.Initialize(out BServiceInitializer ServInit, new string[][] { new string[] { "GOOGLE_CLOUD_PROJECT_ID" }, new string[] { "GOOGLE_APPLICATION_CREDENTIALS", "GOOGLE_PLAIN_CREDENTIALS" }, new string[] { "DEPLOYMENT_BRANCH_NAME" }, new string[] { "DEPLOYMENT_BUILD_NUMBER" }, new string[] { "REDIS_ENDPOINT" }, new string[] { "REDIS_PORT" }, new string[] { "REDIS_PASSWORD" }, new string[] { "SSO_SUPER_ADMINS" }, new string[] { "AZURE_AD_APP_ID" }, new string[] { "AZURE_AD_CLIENT_SECRET" }, new string[] { "AZURE_AD_FETCH_USERS_CLIENT_ID" }, new string[] { "AZURE_AD_FETCH_USERS_CLIENT_SECRET" }, new string[] { "AZURE_AD_FETCH_USERS_APP_OBJECT_ID" }, new string[] { "AZURE_OAUTH2_TOKEN_REQUEST_URL" }, new string[] { "INTERNAL_CALL_PRIVATE_KEY" } })) { return; } bool bInitSuccess = true; bInitSuccess &= ServInit.WithTracingService(); bInitSuccess &= ServInit.WithDatabaseService(); bInitSuccess &= ServInit.WithPubSubService(); bInitSuccess &= ServInit.WithMemoryService(); if (!bInitSuccess) { return; } Resources_DeploymentManager.Get().SetDeploymentBranchNameAndBuildNumber(ServInit.RequiredEnvironmentVariables["DEPLOYMENT_BRANCH_NAME"], ServInit.RequiredEnvironmentVariables["DEPLOYMENT_BUILD_NUMBER"]); Controller_SSOAccessToken.SetLocalServerPort(ServInit.ServerPort); Controller_Rights_Internal.Get().SetLocalServerPort(ServInit.ServerPort); CommonData.MemoryQueryParameters = new BMemoryQueryParameters() { Domain = Resources_DeploymentManager.Get().GetDeploymentBranchNameEscapedLoweredWithDash().ToUpper(), SubDomain = "COMMON_DATA", Identifier = "MEMORY_SERVICE_DATA" }; var InternalCallPrivateKey = ServInit.RequiredEnvironmentVariables["INTERNAL_CALL_PRIVATE_KEY"]; CommonData.INTERNAL_CALL_PRIVATE_KEY = InternalCallPrivateKey; Console.WriteLine(InternalCallPrivateKey); Controller_DeliveryEnsurer.Get().SetDatabaseService(ServInit.DatabaseService); Controller_DeliveryEnsurer.Get().SetServiceIdentifier("auth-service", Actions.EAction.ACTION_AUTH_SERVICE_DELIVERY_ENSURER); Controller_AtomicDBOperation.Get().SetMemoryService(ServInit.MemoryService, CommonData.MemoryQueryParameters); Controller_Rights_Internal.Get().SetMemoryService(ServInit.MemoryService); Manager_PubSubService.Get().Setup(ServInit.PubSubService); var InitializerThread = new Thread(() => { Thread.CurrentThread.IsBackground = true; ServInit.PubSubService.Subscribe(CommonData.MemoryQueryParameters, Manager_PubSubService.Get().OnMessageReceived_Internal, (string Message) => { ServInit.LoggingService.WriteLogs(BLoggingServiceMessageUtility.Single(EBLoggingServiceLogType.Error, Message), ServInit.ProgramID, "PubSubService"); }); Controller_AtomicDBOperation.Get().StartTimeoutCheckOperation(WebServiceBaseTimeoutableProcessor.OnTimeoutNotificationReceived); }); InitializerThread.Start(); var AzureAD_AppID = ServInit.RequiredEnvironmentVariables["AZURE_AD_APP_ID"]; var AzureAD_ClientSecret = ServInit.RequiredEnvironmentVariables["AZURE_AD_CLIENT_SECRET"]; var SSOSuperAdmins = new List <string>(); var SAsJsonString = ServInit.RequiredEnvironmentVariables["SSO_SUPER_ADMINS"]; try { var SAsJArray = JArray.Parse(SAsJsonString); foreach (var SAsToken in SAsJArray) { if (SAsToken.Type == JTokenType.String) { SSOSuperAdmins.Add(((string)SAsToken).ToLower()); } } } catch (Exception) { } var AzureFetchUsersClientID = ServInit.RequiredEnvironmentVariables["AZURE_AD_FETCH_USERS_CLIENT_ID"]; var AzureFetchUsersClientSecret = ServInit.RequiredEnvironmentVariables["AZURE_AD_FETCH_USERS_CLIENT_SECRET"]; var AzureFetchUsersAppObjectID = ServInit.RequiredEnvironmentVariables["AZURE_AD_FETCH_USERS_APP_OBJECT_ID"]; var AzureOAuth2TokenRequestUrl = ServInit.RequiredEnvironmentVariables["AZURE_OAUTH2_TOKEN_REQUEST_URL"]; /* * Web-http service initialization */ var WebServiceEndpoints = new List <BWebPrefixStructure>() { new BWebPrefixStructure(new string[] { "/auth/internal/pubsub*" }, () => new InternalCalls.PubSub_To_AuthService(InternalCallPrivateKey, ServInit.DatabaseService)), new BWebPrefixStructure(new string[] { "/auth/internal/cleanup*" }, () => new InternalCalls.CleanupCall(InternalCallPrivateKey, ServInit.DatabaseService, ServInit.MemoryService)), new BWebPrefixStructure(new string[] { "/auth/internal/fetch_user_ids_from_emails*" }, () => new InternalCalls.FetchUserIDsFromEmailsRequest(InternalCallPrivateKey, ServInit.DatabaseService)), new BWebPrefixStructure(new string[] { "/auth/internal/set*" }, () => new InternalCalls.SetCall(InternalCallPrivateKey, ServInit.MemoryService)), new BWebPrefixStructure(new string[] { "/auth/internal/create_test_user*" }, () => new InternalCalls.CreateTestUser(InternalCallPrivateKey, ServInit.DatabaseService, ServInit.ServerPort)), new BWebPrefixStructure(new string[] { "/auth/internal/delete_test_user*" }, () => new InternalCalls.DeleteTestUser(InternalCallPrivateKey, ServInit.ServerPort)), new BWebPrefixStructure(new string[] { "/auth/internal/synchronize_users_with_azure*" }, () => new InternalCalls.SynchronizeUsersWithAzureAD(InternalCallPrivateKey, AzureOAuth2TokenRequestUrl, AzureFetchUsersClientID, AzureFetchUsersClientSecret, AzureFetchUsersAppObjectID, ServInit.DatabaseService, SSOSuperAdmins)), new BWebPrefixStructure(new string[] { "/auth/login/azure/token_refresh" }, () => new SSOAzureTokenRefreshRequest(ServInit.DatabaseService, ServInit.MemoryService, AzureAD_AppID, AzureAD_ClientSecret, SSOSuperAdmins) /*For token refresh requests via Azure AD SSO Service*/), new BWebPrefixStructure(new string[] { "/auth/login/azure/*" }, () => new SSOAzureLoginCallback(ServInit.DatabaseService, ServInit.MemoryService, AzureAD_AppID, AzureAD_ClientSecret, SSOSuperAdmins) /*For auto-redirect from Azure AD SSO Service*/), new BWebPrefixStructure(new string[] { "/auth/login/azure*" }, () => new SSOAzureLoginRequest(ServInit.DatabaseService, ServInit.MemoryService, AzureAD_AppID, AzureAD_ClientSecret, SSOSuperAdmins) /*For login request via Azure AD SSO Service*/), new BWebPrefixStructure(new string[] { "/auth/login" }, () => new LoginRequest(ServInit.DatabaseService, ServInit.MemoryService)), new BWebPrefixStructure(new string[] { "/auth/access_check" }, () => new AccessCheckRequest(ServInit.DatabaseService, ServInit.MemoryService, AzureAD_AppID, AzureAD_ClientSecret, SSOSuperAdmins)), new BWebPrefixStructure(new string[] { "/auth/list_registered_email_addresses" }, () => new ListRegisteredUserEmails(ServInit.DatabaseService)), new BWebPrefixStructure(new string[] { "/auth/users/*/access_methods/*" }, () => new User_DeleteUserAccessMethod_ForUser(ServInit.DatabaseService, ServInit.MemoryService, "users", "access_methods")), new BWebPrefixStructure(new string[] { "/auth/users/*/access_methods" }, () => new User_CreateListAccessMethods_ForUser(ServInit.DatabaseService, ServInit.MemoryService, "users")), new BWebPrefixStructure(new string[] { "/auth/users/*/base_access_rights/*" }, () => new User_UpdateDeleteBaseRight_ForUser(ServInit.DatabaseService, ServInit.MemoryService, "users", "base_access_rights")), new BWebPrefixStructure(new string[] { "/auth/users/*/base_access_rights" }, () => new User_AddListBaseRights_ForUser(ServInit.DatabaseService, ServInit.MemoryService, "users")), new BWebPrefixStructure(new string[] { "/auth/users/*" }, () => new User_GetUpdateDeleteUser(ServInit.DatabaseService, ServInit.MemoryService, "users")), new BWebPrefixStructure(new string[] { "/auth/users" }, () => new User_CreateListUsers(ServInit.DatabaseService)) }; var BWebService = new BWebService(WebServiceEndpoints.ToArray(), ServInit.ServerPort, ServInit.TracingService); BWebService.Run((string Message) => { ServInit.LoggingService.WriteLogs(BLoggingServiceMessageUtility.Single(EBLoggingServiceLogType.Info, Message), ServInit.ProgramID, "WebService"); }); var ApiPassThroughEndpoint = Environment.GetEnvironmentVariable("API_PASSTHROUGH_ENDPOINT"); if (ApiPassThroughEndpoint != null) { //Needed by MicroserviceLocalRunner new InternalCalls.SetCall(InternalCallPrivateKey, ServInit.MemoryService).Process_SetApiPassthroughPublicEndpoint( (string Message) => { ServInit.LoggingService.WriteLogs(BLoggingServiceMessageUtility.Single(EBLoggingServiceLogType.Error, Message), ServInit.ProgramID, "WebService"); }, ApiPassThroughEndpoint); } var CadFileServiceEndpoint = Environment.GetEnvironmentVariable("CAD_FILE_SERVICE_ENDPOINT"); if (CadFileServiceEndpoint != null) { //Needed by MicroserviceLocalRunner new InternalCalls.SetCall(InternalCallPrivateKey, ServInit.MemoryService).Process_SetCADFileServicePublicEndpoint( (string Message) => { ServInit.LoggingService.WriteLogs(BLoggingServiceMessageUtility.Single(EBLoggingServiceLogType.Error, Message), ServInit.ProgramID, "WebService"); }, CadFileServiceEndpoint); } /* * Make main thread sleep forever */ Thread.Sleep(Timeout.Infinite); }
static void Main() { System.Console.WriteLine("Initializing the service..."); //#if (Debug || DEBUG) // if (!ServicesDebugOnlyUtilities.CalledFromMain()) return; //#endif // In case of a cloud component dependency or environment variable is added/removed; /* * Common initialization step */ if (!BServiceInitializer.Initialize(out BServiceInitializer ServInit, new string[][] { new string[] { "GOOGLE_CLOUD_PROJECT_ID" }, new string[] { "GOOGLE_APPLICATION_CREDENTIALS", "GOOGLE_PLAIN_CREDENTIALS" }, new string[] { "DEPLOYMENT_BRANCH_NAME" }, new string[] { "DEPLOYMENT_BUILD_NUMBER" }, new string[] { "REDIS_ENDPOINT" }, new string[] { "REDIS_PORT" }, new string[] { "REDIS_PASSWORD" }, new string[] { "CAD_FILE_STORAGE_BUCKET" }, new string[] { "AUTH_SERVICE_ENDPOINT" }, new string[] { "CAD_PROCESS_SERVICE_ENDPOINT" }, new string[] { "INTERNAL_CALL_PRIVATE_KEY" } })) { return; } bool bInitSuccess = true; bInitSuccess &= ServInit.WithDatabaseService(); bInitSuccess &= ServInit.WithFileService(); bInitSuccess &= ServInit.WithPubSubService(); bInitSuccess &= ServInit.WithTracingService(); bInitSuccess &= ServInit.WithMemoryService(); if (!bInitSuccess) { return; } Resources_DeploymentManager.Get().SetDeploymentBranchNameAndBuildNumber(ServInit.RequiredEnvironmentVariables["DEPLOYMENT_BRANCH_NAME"], ServInit.RequiredEnvironmentVariables["DEPLOYMENT_BUILD_NUMBER"]); CommonData.MemoryQueryParameters = new BMemoryQueryParameters() { Domain = Resources_DeploymentManager.Get().GetDeploymentBranchNameEscapedLoweredWithDash().ToUpper(), SubDomain = "COMMON_DATA", Identifier = "MEMORY_SERVICE_DATA" }; var AuthServiceEndpoint = ServInit.RequiredEnvironmentVariables["AUTH_SERVICE_ENDPOINT"]; var CadFileStorageBucketName = ServInit.RequiredEnvironmentVariables["CAD_FILE_STORAGE_BUCKET"]; var CadProcessServiceEndpoint = ServInit.RequiredEnvironmentVariables["CAD_PROCESS_SERVICE_ENDPOINT"]; Controller_DeliveryEnsurer.Get().SetDatabaseService(ServInit.DatabaseService); Controller_DeliveryEnsurer.Get().SetFileService(ServInit.FileService); Controller_DeliveryEnsurer.Get().SetServiceIdentifier("cad-file-service", Actions.EAction.ACTION_CAD_FILE_SERVICE_DELIVERY_ENSURER); Controller_AtomicDBOperation.Get().SetMemoryService(ServInit.MemoryService, CommonData.MemoryQueryParameters); Manager_PubSubService.Get().Setup(ServInit.PubSubService); var InitializerThread = new Thread(() => { Thread.CurrentThread.IsBackground = true; ServInit.PubSubService.Subscribe(CommonData.MemoryQueryParameters, Manager_PubSubService.Get().OnMessageReceived_Internal, (string Message) => { ServInit.LoggingService.WriteLogs(BLoggingServiceMessageUtility.Single(EBLoggingServiceLogType.Error, Message), ServInit.ProgramID, "PubSubService"); }); Controller_AtomicDBOperation.Get().StartTimeoutCheckOperation(WebServiceBaseTimeoutableProcessor.OnTimeoutNotificationReceived); }); InitializerThread.Start(); var InternalCallPrivateKey = ServInit.RequiredEnvironmentVariables["INTERNAL_CALL_PRIVATE_KEY"]; /* * Web-http service initialization */ var WebServiceEndpoints = new List <BWebPrefixStructure>() { new BWebPrefixStructure(new string[] { "/3d/models/internal/pubsub*" }, () => new InternalCalls.PubSub_To_CadFileService(InternalCallPrivateKey, ServInit.DatabaseService, ServInit.FileService, CadFileStorageBucketName, CadProcessServiceEndpoint)), new BWebPrefixStructure(new string[] { "/3d/models/internal/cleanup*" }, () => new InternalCalls.CleanupCall(InternalCallPrivateKey, ServInit.DatabaseService, ServInit.MemoryService)), new BWebPrefixStructure(new string[] { "/3d/models/internal/globally_shared_models*" }, () => new ListGloballySharedModelIds.ForInternal(InternalCallPrivateKey, ServInit.DatabaseService)), new BWebPrefixStructure(new string[] { "/3d/models/internal/check_models_exist*" }, () => new InternalCalls.CheckModelsExist(InternalCallPrivateKey, ServInit.DatabaseService)), new BWebPrefixStructure(new string[] { "/3d/models/get_models_by/user_id/*/metadata_key/*/metadata_values/*" }, () => new GetModelsBy_MetadataKeyValueUserPair(ServInit.DatabaseService, "user_id", "metadata_key", "metadata_values")), new BWebPrefixStructure(new string[] { "/3d/models/get_models_by/user_id/*/metadata_key/*" }, () => new GetModelsBy_MetadataKeyUserPair(ServInit.DatabaseService, "user_id", "metadata_key")), new BWebPrefixStructure(new string[] { "/3d/models/*/revisions/*/unreal/hierarchy_geometry_metadata" }, () => new Model_GetUnrealHierarchyMetadataGeometry(ServInit.FileService, ServInit.DatabaseService, "models", "revisions", CadFileStorageBucketName)), new BWebPrefixStructure(new string[] { "/3d/models/*/revisions/*/unreal/hierarchy_geometry" }, () => new Model_GetUnrealHierarchyGeometry(ServInit.FileService, ServInit.DatabaseService, "models", "revisions", CadFileStorageBucketName)), new BWebPrefixStructure(new string[] { "/3d/models/*/revisions/*/unreal/hierarchy" }, () => new Model_GetUnrealHierarchy(ServInit.FileService, ServInit.DatabaseService, "models", "revisions", CadFileStorageBucketName)), new BWebPrefixStructure(new string[] { "/3d/models/*/revisions/*/unreal/geometry_files/*" }, () => new Model_GetUnrealGeometry(ServInit.FileService, ServInit.DatabaseService, "models", "revisions", "geometry_files", CadFileStorageBucketName)), new BWebPrefixStructure(new string[] { "/3d/models/*/revisions/*/raw" }, () => new Model_GetUpdateDeleteRaw_ForRevision(ServInit.FileService, ServInit.DatabaseService, "models", "revisions", CadFileStorageBucketName, CadProcessServiceEndpoint)), new BWebPrefixStructure(new string[] { "/3d/models/*/revisions/*/hierarchy/nodes/*" }, () => new Model_GetHierarchyNode_ForRevision(ServInit.FileService, ServInit.DatabaseService, "models", "revisions", "nodes", CadFileStorageBucketName)), new BWebPrefixStructure(new string[] { "/3d/models/*/revisions/*/hierarchy" }, () => new Model_GetHierarchyFile_ForRevision(ServInit.FileService, ServInit.DatabaseService, "models", "revisions", CadFileStorageBucketName)), new BWebPrefixStructure(new string[] { "/3d/models/*/revisions/*/geometry/nodes/*" }, () => new Model_GetGeometryNode_ForRevision(ServInit.FileService, ServInit.DatabaseService, "models", "revisions", "nodes", CadFileStorageBucketName)), new BWebPrefixStructure(new string[] { "/3d/models/*/revisions/*/geometry" }, () => new Model_GetGeometryFile_ForRevision(ServInit.FileService, ServInit.DatabaseService, "models", "revisions", CadFileStorageBucketName)), new BWebPrefixStructure(new string[] { "/3d/models/*/revisions/*/metadata/nodes/*" }, () => new Model_GetMetadataNode_ForRevision(ServInit.FileService, ServInit.DatabaseService, "models", "revisions", "keys", CadFileStorageBucketName)), new BWebPrefixStructure(new string[] { "/3d/models/*/revisions/*/metadata" }, () => new Model_GetMetadataFile_ForRevision(ServInit.FileService, ServInit.DatabaseService, "models", "revisions", CadFileStorageBucketName)), new BWebPrefixStructure(new string[] { "/3d/models/*/revisions/*" }, () => new Model_GetUpdateDeleteRevision(ServInit.DatabaseService, "models", "revisions", CadFileStorageBucketName)), new BWebPrefixStructure(new string[] { "/3d/models/*/revisions" }, () => new Model_AddListRevisions(ServInit.DatabaseService, "models")), new BWebPrefixStructure(new string[] { "/3d/models/*/sharing" }, () => new Model_ChangeSharingWithUsers(InternalCallPrivateKey, AuthServiceEndpoint, ServInit.DatabaseService, "models")), new BWebPrefixStructure(new string[] { "/3d/models/*/remove_sharing_from/user_id/*" }, () => new Model_RemoveModelShare(ServInit.DatabaseService, "models", "user_id")), new BWebPrefixStructure(new string[] { "/3d/models/globally_shared" }, () => new ListGloballySharedModelIds.ForUsers(ServInit.DatabaseService)), new BWebPrefixStructure(new string[] { "/3d/models/*" }, () => new Model_GetUpdateDeleteModel(ServInit.DatabaseService, "models")), new BWebPrefixStructure(new string[] { "/3d/models" }, () => new Model_AddListModels(ServInit.DatabaseService)) }; var BWebService = new BWebService(WebServiceEndpoints.ToArray(), ServInit.ServerPort /*, ServInit.TracingService*/); BWebService.Run((string Message) => { ServInit.LoggingService.WriteLogs(BLoggingServiceMessageUtility.Single(EBLoggingServiceLogType.Info, Message), ServInit.ProgramID, "WebService"); }); /* * Make main thread sleep forever */ Thread.Sleep(Timeout.Infinite); }
public static bool GenerateNonExistentUniqueID( WebServiceBaseTimeoutable _Request, IBDatabaseServiceInterface _DatabaseService, string _TableName, string _TableKeyName, string[] _TableEntryMustHaveProperties, EGetClearance _GetClearance, out string _GeneratedUniqueID, out BWebServiceResponse _FailureResponse, Action <string> _ErrorMessageAction = null) { _GeneratedUniqueID = null; _FailureResponse = BWebResponse.InternalError(""); int ExistenceTrial = 0; while (_GeneratedUniqueID == null && ExistenceTrial < 3) { if (!BUtility.CalculateStringMD5(BUtility.RandomString(32, false), out _GeneratedUniqueID, _ErrorMessageAction)) { _FailureResponse = BWebResponse.InternalError("Hashing operation has failed."); return(false); } if (_GetClearance == EGetClearance.Yes && !Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(_Request.InnerProcessor, _TableName, _GeneratedUniqueID, _ErrorMessageAction)) { _FailureResponse = BWebResponse.InternalError("Atomic operation control has failed."); return(false); } if (!_DatabaseService.GetItem( _TableName, _TableKeyName, new BPrimitiveType(_GeneratedUniqueID), _TableEntryMustHaveProperties, out JObject ExistenceCheck, _ErrorMessageAction)) { _FailureResponse = BWebResponse.InternalError("Database existence check operation has failed."); return(false); } if (ExistenceCheck != null) { if (_GetClearance == EGetClearance.Yes) { Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(_Request.InnerProcessor, _TableName, _GeneratedUniqueID, _ErrorMessageAction); } _GeneratedUniqueID = null; ExistenceTrial++; } else { break; } } if (_GeneratedUniqueID == null) { _FailureResponse = BWebResponse.InternalError("Unique model ID generation operation has failed."); return(false); } return(true); }
//TODO: If SSO is enabled for user; when it loses access to the tenant, delete all rights but keep the models and user. private BWebServiceResponse DeleteAccessMethodForUser(HttpListenerContext _Context, out bool _bSetClearanceForApiKey, out string _ApiKey, Action <string> _ErrorMessageAction) { _bSetClearanceForApiKey = false; _ApiKey = null; var UserKey = new BPrimitiveType(RequestedUserID); if (!DatabaseService.GetItem( UserDBEntry.DBSERVICE_USERS_TABLE(), UserDBEntry.KEY_NAME_USER_ID, UserKey, UserDBEntry.Properties, out JObject UserObject, _ErrorMessageAction)) { return(BWebResponse.InternalError("Database fetch-user-info operation has failed.")); } if (UserObject == null) { return(BWebResponse.NotFound("User does not exist.")); } if (!UserObject.ContainsKey(UserDBEntry.AUTH_METHODS_PROPERTY)) { return(BWebResponse.NotFound("User does not have any auth method.")); } bool bFound = false; var AuthMethodsArray = (JArray)UserObject[UserDBEntry.AUTH_METHODS_PROPERTY]; for (var i = (AuthMethodsArray.Count - 1); i >= 0; i--) { var MethodObject = (JObject)AuthMethodsArray[i]; var Method = JsonConvert.DeserializeObject <AuthMethod>(MethodObject.ToString()); string AuthMethodKey = null; switch (Method.Method) { case AuthMethod.Methods.USER_EMAIL_PASSWORD_METHOD: { if (!bIsInternalCall && Method.UserEmail.EndsWith(Controller_SSOAccessToken.EMAIL_USER_NAME_POSTFIX)) { return(BWebResponse.BadRequest("This auth method cannot be deleted.")); } AuthMethodKey = Method.UserEmail + Method.PasswordMD5; break; } case AuthMethod.Methods.USER_NAME_PASSWORD_METHOD: { AuthMethodKey = Method.UserName + Method.PasswordMD5; break; } case AuthMethod.Methods.API_KEY_METHOD: { AuthMethodKey = Method.ApiKey; _bSetClearanceForApiKey = true; _ApiKey = Method.ApiKey; if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_API_KEY + ":" + Method.ApiKey, _ErrorMessageAction)) { return(BWebResponse.InternalError("Atomic operation control has failed.")); } break; } } if (AuthMethodKey == RequestedAuthMethodKey) { AuthMethodsArray.RemoveAt(i); bFound = true; } } if (!bFound) { return(BWebResponse.NotFound("Auth method does not exist.")); } //Update UserDBEntry Controller_DeliveryEnsurer.Get().DB_UpdateItem_FireAndForget( _Context, UserDBEntry.DBSERVICE_USERS_TABLE(), UserDBEntry.KEY_NAME_USER_ID, UserKey, UserObject); //Delete AuthDBEntry Controller_DeliveryEnsurer.Get().DB_DeleteItem_FireAndForget( _Context, AuthDBEntry.DBSERVICE_AUTHMETHODS_TABLE(), AuthDBEntry.KEY_NAME_AUTH_DB_ENTRY, new BPrimitiveType(RequestedAuthMethodKey)); if (_bSetClearanceForApiKey) { //Delete ApiKey from UniqueUserFields Controller_DeliveryEnsurer.Get().DB_DeleteItem_FireAndForget( _Context, UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_API_KEY, new BPrimitiveType(_ApiKey)); } //Delete from cache MemoryService.DeleteKey( CommonData.MemoryQueryParameters, AuthDBEntry.KEY_NAME_AUTH_DB_ENTRY + RequestedAuthMethodKey, _ErrorMessageAction); return(BWebResponse.StatusOK("Access method has been deleted.")); }
private BWebServiceResponse UpdateModelInfo(HttpListenerContext _Context, Action <string> _ErrorMessageAction) { if (!CommonMethods.TryParsingRequestFor( _Context, out JObject UpdateFieldsModelEntry, false, out ModelDBEntry _, out BWebServiceResponse FailureResponse, _ErrorMessageAction)) { return(FailureResponse); } if (!CommonMethods.TryGettingModelInfo( DatabaseService, RequestedModelID, out JObject _, true, out ModelDBEntry Model, out FailureResponse, _ErrorMessageAction)) { return(FailureResponse); } //If there is a change in the model name bool bGetClearanceForModelName_New = false; bool bGetClearanceForModelName_Old = false; string ModelUniqueName_New = null; string ModelUniqueName_Old = null; try { if (UpdateFieldsModelEntry.ContainsKey(ModelDBEntry.MODEL_UNIQUE_NAME_PROPERTY) && Model.ModelName != (string)UpdateFieldsModelEntry[ModelDBEntry.MODEL_UNIQUE_NAME_PROPERTY]) { ModelUniqueName_New = (string)UpdateFieldsModelEntry[ModelDBEntry.MODEL_UNIQUE_NAME_PROPERTY]; if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, UniqueFileFieldsDBEntry.DBSERVICE_UNIQUEFILEFIELDS_TABLE(), UniqueFileFieldsDBEntry.KEY_NAME_MODEL_UNIQUE_NAME + ":" + ModelUniqueName_New, _ErrorMessageAction)) { return(BWebResponse.InternalError("Atomic operation control has failed.")); } bGetClearanceForModelName_New = true; ModelUniqueName_Old = Model.ModelName; if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, UniqueFileFieldsDBEntry.DBSERVICE_UNIQUEFILEFIELDS_TABLE(), UniqueFileFieldsDBEntry.KEY_NAME_MODEL_UNIQUE_NAME + ":" + ModelUniqueName_Old, _ErrorMessageAction)) { return(BWebResponse.InternalError("Atomic operation control has failed.")); } bGetClearanceForModelName_Old = true; //Put the new one if (!DatabaseService.UpdateItem( UniqueFileFieldsDBEntry.DBSERVICE_UNIQUEFILEFIELDS_TABLE(), UniqueFileFieldsDBEntry.KEY_NAME_MODEL_UNIQUE_NAME, new BPrimitiveType(ModelUniqueName_New), new JObject() { [ModelDBEntry.KEY_NAME_MODEL_ID] = RequestedModelID }, out JObject _, EBReturnItemBehaviour.DoNotReturn, DatabaseService.BuildAttributeNotExistCondition(UniqueFileFieldsDBEntry.KEY_NAME_MODEL_UNIQUE_NAME), _ErrorMessageAction)) { if (!DatabaseService.GetItem( UniqueFileFieldsDBEntry.DBSERVICE_UNIQUEFILEFIELDS_TABLE(), UniqueFileFieldsDBEntry.KEY_NAME_MODEL_UNIQUE_NAME, new BPrimitiveType(ModelUniqueName_New), UniqueFileFieldsDBEntry.Properties, out JObject ModelIDResponse, _ErrorMessageAction) || !ModelIDResponse.ContainsKey(ModelDBEntry.KEY_NAME_MODEL_ID)) { return(BWebResponse.InternalError("Model ID could not be retrieved upon conflict.")); } var Result = JObject.Parse(BWebResponse.Error_Conflict_String("Attribute " + UniqueFileFieldsDBEntry.KEY_NAME_MODEL_UNIQUE_NAME + " must be globally unique.")); Result[ModelDBEntry.KEY_NAME_MODEL_ID] = (string)ModelIDResponse[ModelDBEntry.KEY_NAME_MODEL_ID]; return(new BWebServiceResponse( BWebResponse.Error_Conflict_Code, new BStringOrStream(Result.ToString()), BWebResponse.Error_Conflict_ContentType)); } //Delete the old one Controller_DeliveryEnsurer.Get().DB_DeleteItem_FireAndForget( _Context, UniqueFileFieldsDBEntry.DBSERVICE_UNIQUEFILEFIELDS_TABLE(), UniqueFileFieldsDBEntry.KEY_NAME_MODEL_UNIQUE_NAME, new BPrimitiveType(ModelUniqueName_Old)); } var OldModelMetadataSet = Model.ModelMetadata; Model.Merge(UpdateFieldsModelEntry); var NewModelMetadataSet = Model.ModelMetadata; if (OldModelMetadataSet != NewModelMetadataSet) { var MetaLocator = Controller_AttributeTables.MetadataLocator.ItIsModelMetadata(RequestedModelID); //First remove all metadata sets Controller_AttributeTables.Get().AddRemoveMetadataSets_AttributesTables( InnerDeliveryEnsurerUserProcessor, Model.ModelOwnerUserID, MetaLocator, OldModelMetadataSet, Controller_AttributeTables.EAddRemove.Remove, Controller_AttributeTables.EKillProcedureIfGetClearanceFails.No, out BWebServiceResponse _, _ErrorMessageAction); //Then add new metadata sets Controller_AttributeTables.Get().AddRemoveMetadataSets_AttributesTables( InnerDeliveryEnsurerUserProcessor, Model.ModelOwnerUserID, MetaLocator, NewModelMetadataSet, Controller_AttributeTables.EAddRemove.Add, Controller_AttributeTables.EKillProcedureIfGetClearanceFails.No, out BWebServiceResponse _, _ErrorMessageAction); } Model.MRVLastUpdateTime = CommonMethods.GetTimeAsCreationTime(); Controller_DeliveryEnsurer.Get().DB_UpdateItem_FireAndForget( _Context, ModelDBEntry.DBSERVICE_MODELS_TABLE(), ModelDBEntry.KEY_NAME_MODEL_ID, new BPrimitiveType(RequestedModelID), JObject.Parse(JsonConvert.SerializeObject(Model))); Controller_ModelActions.Get().BroadcastModelAction(new Action_ModelUpdated ( RequestedModelID, Model.ModelOwnerUserID, Model.ModelSharedWithUserIDs, AuthorizedUser.UserID, UpdateFieldsModelEntry ), _ErrorMessageAction); return(BWebResponse.StatusOK("Model has been successfully updated.")); } finally { if (bGetClearanceForModelName_New) { Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, UniqueFileFieldsDBEntry.DBSERVICE_UNIQUEFILEFIELDS_TABLE(), UniqueFileFieldsDBEntry.KEY_NAME_MODEL_UNIQUE_NAME + ":" + ModelUniqueName_New, _ErrorMessageAction); } if (bGetClearanceForModelName_Old) { Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, UniqueFileFieldsDBEntry.DBSERVICE_UNIQUEFILEFIELDS_TABLE(), UniqueFileFieldsDBEntry.KEY_NAME_MODEL_UNIQUE_NAME + ":" + ModelUniqueName_Old, _ErrorMessageAction); } } }
private void Cleanup_UniqueFileFields(Action <string> _ErrorMessageAction) { if (!DatabaseService.ScanTable( UniqueFileFieldsDBEntry.DBSERVICE_UNIQUEFILEFIELDS_TABLE(), out List <JObject> UniqueFieldsEntries, _ErrorMessageAction)) { _ErrorMessageAction?.Invoke("Cleanup_UniqueFileFields: Table does not exist or ScanTable operation has failed."); return; } if (UniqueFieldsEntries.Count == 0) { return; } foreach (var Current in UniqueFieldsEntries) { if (!Current.ContainsKey(ModelDBEntry.KEY_NAME_MODEL_ID)) { continue; } if (!Current.ContainsKey(UniqueFileFieldsDBEntry.KEY_NAME_MODEL_UNIQUE_NAME)) { continue; } var ModelUniqueName = (string)Current[UniqueFileFieldsDBEntry.KEY_NAME_MODEL_UNIQUE_NAME]; var ModelID = (string)Current[ModelDBEntry.KEY_NAME_MODEL_ID]; var Casted = JsonConvert.DeserializeObject <UniqueFileFieldsDBEntry>(Current.ToString()); try { if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, ModelDBEntry.DBSERVICE_MODELS_TABLE(), ModelID, _ErrorMessageAction)) { continue; } bool bDeleteEntry = false; if (!DatabaseService.GetItem( ModelDBEntry.DBSERVICE_MODELS_TABLE(), ModelDBEntry.KEY_NAME_MODEL_ID, new BPrimitiveType(ModelID), ModelDBEntry.Properties, out JObject ModelObject, _ErrorMessageAction)) { continue; } if (ModelObject == null) { //Model does not exist bDeleteEntry = true; } else { var Model = JsonConvert.DeserializeObject <ModelDBEntry>(ModelObject.ToString()); bDeleteEntry = ModelUniqueName != Model.ModelName; } if (bDeleteEntry) { DatabaseService.DeleteItem( UniqueFileFieldsDBEntry.DBSERVICE_UNIQUEFILEFIELDS_TABLE(), UniqueFileFieldsDBEntry.KEY_NAME_MODEL_UNIQUE_NAME, new BPrimitiveType(ModelUniqueName), out JObject _, EBReturnItemBehaviour.DoNotReturn, _ErrorMessageAction); } } finally { Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, ModelDBEntry.DBSERVICE_MODELS_TABLE(), ModelID, _ErrorMessageAction); } } }
private void Cleanup_AuthMethods(Action <string> _ErrorMessageAction = null) { if (!DatabaseService.ScanTable( AuthDBEntry.DBSERVICE_AUTHMETHODS_TABLE(), out List <JObject> AuthEntries, _ErrorMessageAction)) { _ErrorMessageAction?.Invoke("Cleanup_AuthMethods: Table does not exist or ScanTable operation has failed."); return; } if (AuthEntries.Count == 0) { return; } foreach (var Current in AuthEntries) { var Casted = JsonConvert.DeserializeObject <AuthDBEntry>(Current.ToString()); var EntryKey = (string)Current[AuthDBEntry.KEY_NAME_AUTH_DB_ENTRY]; if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, UserDBEntry.DBSERVICE_USERS_TABLE(), Casted.UserID, _ErrorMessageAction)) { continue; } try { bool bDeleteEntry = false; if (!DatabaseService.GetItem( UserDBEntry.DBSERVICE_USERS_TABLE(), UserDBEntry.KEY_NAME_USER_ID, new BPrimitiveType(Casted.UserID), UserDBEntry.Properties, out JObject UserObject, _ErrorMessageAction)) { continue; } if (UserObject == null) { //User does not exist bDeleteEntry = true; } else { bool bFound = false; bool bSSOMethod = false; bool bSSORefreshTokenExpired = false; var User = JsonConvert.DeserializeObject <UserDBEntry>(UserObject.ToString()); for (var i = 0; i < User.AuthMethods.Count; i++) { var UserAuthMethod = User.AuthMethods[i]; var UserAuthMethodKey = ""; if (UserAuthMethod.Method == AuthMethod.Methods.USER_EMAIL_PASSWORD_METHOD) { if (UserAuthMethod.UserEmail == null || UserAuthMethod.PasswordMD5 == null || UserAuthMethod.UserEmail.Length == 0 || UserAuthMethod.PasswordMD5.Length == 0) { continue; } UserAuthMethodKey = UserAuthMethod.UserEmail + UserAuthMethod.PasswordMD5; if (UserAuthMethodKey == EntryKey) { bFound = true; //SSO Auth Method Expiry Check if (UserAuthMethod.UserEmail.EndsWith(Controller_SSOAccessToken.EMAIL_USER_NAME_POSTFIX)) { bSSOMethod = true; var QueryParameters = Controller_SSOAccessToken.MakeSSOQueryParameters(UserAuthMethod.PasswordMD5); if (Controller_SSOAccessToken.IsTokenExpiredOrInvalid(out Dictionary <string, BPrimitiveType> _Result, MemoryService, QueryParameters, _ErrorMessageAction) || _Result == null) { bSSORefreshTokenExpired = true; User.AuthMethods.RemoveAt(i); } } break; } } else { if (UserAuthMethod.Method == AuthMethod.Methods.USER_NAME_PASSWORD_METHOD) { if (UserAuthMethod.UserName == null || UserAuthMethod.PasswordMD5 == null || UserAuthMethod.UserName.Length == 0 || UserAuthMethod.PasswordMD5.Length == 0) { continue; } UserAuthMethodKey = UserAuthMethod.UserName + UserAuthMethod.PasswordMD5; } else if (UserAuthMethod.Method == AuthMethod.Methods.API_KEY_METHOD) { UserAuthMethodKey = UserAuthMethod.ApiKey; } if (UserAuthMethodKey == EntryKey) { bFound = true; break; } } } if (!bFound) { bDeleteEntry = true; } else if (bSSOMethod && bSSORefreshTokenExpired) { _ErrorMessageAction?.Invoke("Cleanup_AuthMethods: Expired sso auth method has been found. Deleting the entry."); bDeleteEntry = true; DatabaseService.UpdateItem( UserDBEntry.DBSERVICE_USERS_TABLE(), UserDBEntry.KEY_NAME_USER_ID, new BPrimitiveType(Casted.UserID), JObject.Parse(JsonConvert.SerializeObject(User)), out JObject _, EBReturnItemBehaviour.DoNotReturn, null, _ErrorMessageAction); } } if (bDeleteEntry) { DatabaseService.DeleteItem( AuthDBEntry.DBSERVICE_AUTHMETHODS_TABLE(), AuthDBEntry.KEY_NAME_AUTH_DB_ENTRY, new BPrimitiveType(EntryKey), out JObject _, EBReturnItemBehaviour.DoNotReturn, _ErrorMessageAction); MemoryService.DeleteKey( CommonData.MemoryQueryParameters, AuthDBEntry.KEY_NAME_AUTH_DB_ENTRY + EntryKey, _ErrorMessageAction); } } finally { Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, UserDBEntry.DBSERVICE_USERS_TABLE(), Casted.UserID, _ErrorMessageAction); } } }
private bool UpdateRightsForUsersUponChangeOnSharing(List <string> _RelevantIdList, Tuple <string, List <string> >[] _RightsRegex, Controller_Rights_Internal.EChangeUserRightsForModelType _Action, Action <string> _ErrorMessageAction = null) { var WaitFor = new ManualResetEvent(false); var InternalError = new BValue <bool>(false, EBProducerStatus.MultipleProducer); var DoneStack = new ConcurrentStack <bool>(); for (var i = 0; i < _RelevantIdList.Count; i++) { for (var j = 0; j < _RightsRegex.Length; j++) { DoneStack.Push(true); } } foreach (var ChangeForUserId in _RelevantIdList) { var CurrentUserID = ChangeForUserId; foreach (var PathRegex in _RightsRegex) { var CurrentPathRegex = PathRegex; BTaskWrapper.Run(() => { if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, UserDBEntry.DBSERVICE_USERS_TABLE(), CurrentUserID, _ErrorMessageAction)) { _ErrorMessageAction?.Invoke("PubSub_To_AuthService->UpdateRightsForUsersUponChangeOnSharing: Atomic operation control has failed for " + UserDBEntry.KEY_NAME_USER_ID + ": " + CurrentUserID); InternalError.Set(true); try { WaitFor.Set(); } catch (Exception) { } return; } try { if (!Controller_Rights_Internal.Get().ChangeBaseUserRight( out bool _bInternalErrorOccured, true,/*important to set to true*/ _Action, CurrentUserID, CurrentPathRegex.Item1.Replace("{shareeUserId}", ChangeForUserId, StringComparison.InvariantCulture), _ErrorMessageAction, CurrentPathRegex.Item2)) { if (_bInternalErrorOccured) { InternalError.Set(true); try { WaitFor.Set(); } catch (Exception) { } return; } } } finally { Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, UserDBEntry.DBSERVICE_USERS_TABLE(), CurrentUserID, _ErrorMessageAction); } DoneStack.TryPop(out bool _); if (DoneStack.Count == 0) { try { WaitFor.Set(); } catch (Exception) { } } }); } } try { if (_RelevantIdList.Count > 0) { WaitFor.WaitOne(); } WaitFor.Close(); } catch (Exception) { } //Retry if internal error occured return(InternalError.Get() == false); }
private BWebServiceResponse CreateModel(HttpListenerContext _Context, Action <string> _ErrorMessageAction) { if (!CommonMethods.TryParsingRequestFor( _Context, out JObject _, true, out ModelDBEntry NewModelObject, out BWebServiceResponse FailureResponse, _ErrorMessageAction)) { return(FailureResponse); } NewModelObject.ModelOwnerUserID = AuthorizedUser.UserID; if (!CommonMethods.GenerateNonExistentUniqueID( this, DatabaseService, ModelDBEntry.DBSERVICE_MODELS_TABLE(), ModelDBEntry.KEY_NAME_MODEL_ID, ModelDBEntry.MustHaveProperties, CommonMethods.EGetClearance.Yes, out string ModelID, out BWebServiceResponse _FailureResponse, _ErrorMessageAction)) { return(_FailureResponse); } bool bGetClearanceForModelName = false; try { if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, UniqueFileFieldsDBEntry.DBSERVICE_UNIQUEFILEFIELDS_TABLE(), UniqueFileFieldsDBEntry.KEY_NAME_MODEL_UNIQUE_NAME + ":" + NewModelObject.ModelName, _ErrorMessageAction)) { return(BWebResponse.InternalError("Atomic operation control has failed.")); } bGetClearanceForModelName = true; if (!DatabaseService.UpdateItem( UniqueFileFieldsDBEntry.DBSERVICE_UNIQUEFILEFIELDS_TABLE(), UniqueFileFieldsDBEntry.KEY_NAME_MODEL_UNIQUE_NAME, new BPrimitiveType(NewModelObject.ModelName), new JObject() { [ModelDBEntry.KEY_NAME_MODEL_ID] = ModelID }, out JObject _, EBReturnItemBehaviour.DoNotReturn, DatabaseService.BuildAttributeNotExistCondition(UniqueFileFieldsDBEntry.KEY_NAME_MODEL_UNIQUE_NAME), _ErrorMessageAction)) { if (!DatabaseService.GetItem( UniqueFileFieldsDBEntry.DBSERVICE_UNIQUEFILEFIELDS_TABLE(), UniqueFileFieldsDBEntry.KEY_NAME_MODEL_UNIQUE_NAME, new BPrimitiveType(NewModelObject.ModelName), UniqueFileFieldsDBEntry.Properties, out JObject ModelIDResponse, _ErrorMessageAction) || !ModelIDResponse.ContainsKey(ModelDBEntry.KEY_NAME_MODEL_ID)) { return(BWebResponse.InternalError("Model ID could not be retrieved upon conflict.")); } var Result = JObject.Parse(BWebResponse.Error_Conflict_String("Attribute " + UniqueFileFieldsDBEntry.KEY_NAME_MODEL_UNIQUE_NAME + " must be globally unique.")); Result[ModelDBEntry.KEY_NAME_MODEL_ID] = (string)ModelIDResponse[ModelDBEntry.KEY_NAME_MODEL_ID]; return(new BWebServiceResponse( BWebResponse.Error_Conflict_Code, new BStringOrStream(Result.ToString()), BWebResponse.Error_Conflict_ContentType)); } if (!Controller_AttributeTables.Get().AddRemoveMetadataSets_AttributesTables( InnerDeliveryEnsurerUserProcessor, NewModelObject.ModelOwnerUserID, Controller_AttributeTables.MetadataLocator.ItIsModelMetadata(ModelID), NewModelObject.ModelMetadata, Controller_AttributeTables.EAddRemove.Add, Controller_AttributeTables.EKillProcedureIfGetClearanceFails.Yes, out _FailureResponse, _ErrorMessageAction)) { return(_FailureResponse); } NewModelObject.CreationTime = CommonMethods.GetTimeAsCreationTime(); NewModelObject.MRVLastUpdateTime = NewModelObject.CreationTime; Controller_DeliveryEnsurer.Get().DB_PutItem_FireAndForget( _Context, ModelDBEntry.DBSERVICE_MODELS_TABLE(), ModelDBEntry.KEY_NAME_MODEL_ID, new BPrimitiveType(ModelID), JObject.Parse(JsonConvert.SerializeObject(NewModelObject))); Controller_ModelActions.Get().BroadcastModelAction(new Action_ModelCreated ( ModelID, AuthorizedUser.UserID, new List <string>(), AuthorizedUser.AuthMethodKey ), _ErrorMessageAction); return(BWebResponse.StatusCreated("Model has been created.", new JObject() { [ModelDBEntry.KEY_NAME_MODEL_ID] = ModelID })); } finally { Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, ModelDBEntry.DBSERVICE_MODELS_TABLE(), ModelID, _ErrorMessageAction); if (bGetClearanceForModelName) { Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, UniqueFileFieldsDBEntry.DBSERVICE_UNIQUEFILEFIELDS_TABLE(), UniqueFileFieldsDBEntry.KEY_NAME_MODEL_UNIQUE_NAME + ":" + NewModelObject.ModelName, _ErrorMessageAction); } } }
private void Cleanup_UniqueUserFields(Action <string> _ErrorMessageAction = null) { if (!DatabaseService.ScanTable( UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), out List <JObject> UniqueFieldsEntries, _ErrorMessageAction)) { _ErrorMessageAction?.Invoke("Cleanup_UniqueUserFields: Table does not exist or ScanTable operation has failed."); return; } if (UniqueFieldsEntries.Count == 0) { return; } foreach (var Current in UniqueFieldsEntries) { if (!Current.ContainsKey(UserDBEntry.KEY_NAME_USER_ID)) { continue; } var UserID = (string)Current[UserDBEntry.KEY_NAME_USER_ID]; var EntryKeyName = ""; if (Current.ContainsKey(UniqueUserFieldsDBEntry.KEY_NAME_USER_EMAIL)) { EntryKeyName = UniqueUserFieldsDBEntry.KEY_NAME_USER_EMAIL; } else if (Current.ContainsKey(UniqueUserFieldsDBEntry.KEY_NAME_USER_NAME)) { EntryKeyName = UniqueUserFieldsDBEntry.KEY_NAME_USER_NAME; } else if (Current.ContainsKey(UniqueUserFieldsDBEntry.KEY_NAME_API_KEY)) { EntryKeyName = UniqueUserFieldsDBEntry.KEY_NAME_API_KEY; } else { continue; } var EntryKeyValue = (string)Current[EntryKeyName]; var ClearanceFullEntryKey = EntryKeyName + ":" + EntryKeyValue; bool bRelease_UserEntry = false; bool bRelease_UniqueFieldEntry = false; try { if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, UserDBEntry.DBSERVICE_USERS_TABLE(), UserID, _ErrorMessageAction)) { continue; } bRelease_UserEntry = true; if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), ClearanceFullEntryKey, _ErrorMessageAction)) { continue; } bRelease_UniqueFieldEntry = true; bool bDeleteEntry = false; if (!DatabaseService.GetItem( UserDBEntry.DBSERVICE_USERS_TABLE(), UserDBEntry.KEY_NAME_USER_ID, new BPrimitiveType(UserID), UserDBEntry.Properties, out JObject UserObject, _ErrorMessageAction)) { continue; } if (UserObject == null) { //User does not exist bDeleteEntry = true; } else { var User = JsonConvert.DeserializeObject <UserDBEntry>(UserObject.ToString()); switch (EntryKeyName) { case UniqueUserFieldsDBEntry.KEY_NAME_USER_EMAIL: bDeleteEntry = EntryKeyValue != User.UserEmail; break; case UniqueUserFieldsDBEntry.KEY_NAME_USER_NAME: bDeleteEntry = EntryKeyValue != User.UserName; break; case UniqueUserFieldsDBEntry.KEY_NAME_API_KEY: bool bFound = false; foreach (var UserAuthMethod in User.AuthMethods) { if (UserAuthMethod.Method == AuthMethod.Methods.API_KEY_METHOD) { if (UserAuthMethod.ApiKey == EntryKeyValue) { bFound = true; break; } } } if (!bFound) { bDeleteEntry = true; } break; } } if (bDeleteEntry) { DatabaseService.DeleteItem( UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), EntryKeyName, new BPrimitiveType(EntryKeyValue), out JObject _, EBReturnItemBehaviour.DoNotReturn, _ErrorMessageAction); } } finally { if (bRelease_UniqueFieldEntry) { Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), ClearanceFullEntryKey, _ErrorMessageAction); } if (bRelease_UserEntry) { Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, UserDBEntry.DBSERVICE_USERS_TABLE(), UserID, _ErrorMessageAction); } } } }
public bool GetClearanceForAll( WebServiceBaseTimeoutableDeliveryEnsurerUserProcessor _RequestOwnerProcessor, List <Metadata> _MetadataList, Action <string> _ErrorMessageAction = null) { RequestOwnerProcessor = _RequestOwnerProcessor; int ParallelOperationsNumber = _MetadataList.Count * AttributeTables.Length; var ParallelOperationsStack = new Stack <bool>(ParallelOperationsNumber); for (var i = 0; i < ParallelOperationsNumber; i++) { ParallelOperationsStack.Push(true); } int FailedClearanceOps = 0; var WaitFor = new ManualResetEvent(false); for (var i = 0; i < _MetadataList.Count; i++) { var Data = _MetadataList[i]; for (var j = 0; j < AttributeTables.Length; j++) { var Table = AttributeTables[j]; BTaskWrapper.Run(() => { if (!RequestOwnerProcessor.OwnerProcessor.TryGetTarget(out WebServiceBaseTimeoutableProcessor Processor) || !Controller_AtomicDBOperation.Get().GetClearanceForDBOperation( Processor, Table, Data.MetadataKey, _ErrorMessageAction)) { Interlocked.Increment(ref FailedClearanceOps); return; } lock (ClearanceObtainedFor) { ClearanceObtainedFor.Add(Data.MetadataKey); } lock (ParallelOperationsStack) { ParallelOperationsStack.TryPop(out bool _); if (ParallelOperationsStack.Count == 0) { try { WaitFor.Set(); } catch (Exception) { } } } }); } } try { if (ParallelOperationsNumber > 0) { WaitFor.WaitOne(); } WaitFor.Close(); } catch (Exception) { } return(FailedClearanceOps == 0); }
private void Cleanup_UserModels(HttpListenerContext _Context, Action <string> _ErrorMessageAction = null) { if (!DatabaseService.ScanTable( UserDBEntry.DBSERVICE_USERS_TABLE(), out List <JObject> UserEntries, _ErrorMessageAction)) { _ErrorMessageAction?.Invoke("Cleanup_UserModels: Table does not exist or ScanTable operation has failed."); return; } if (UserEntries.Count == 0) { return; } //Get cad file service endpoint from internal set state if (!InternalSetState.GetValueFromMemoryService( out string CADFileServiceEndpoint, InternalSetState.CAD_FILE_SERVICE_ENDPOINT_PROPERTY, MemoryService, (string _Message) => { _ErrorMessageAction?.Invoke("Cleanup_UserModels: Unable to get CadFileServiceEndpoint: " + _Message); })) { return; } foreach (var UserJObject in UserEntries) { var UserID = (string)UserJObject[UserDBEntry.KEY_NAME_USER_ID]; if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, UserDBEntry.DBSERVICE_USERS_TABLE(), UserID, _ErrorMessageAction)) { continue; } try { var UserID_Primitive = new BPrimitiveType(UserID); var UserDeserialized = JsonConvert.DeserializeObject <UserDBEntry>(UserJObject.ToString()); var UserModelIDsJArray = new JArray(); var UserSharedModelIDsJArray = new JArray(); foreach (var CurrentModel in UserDeserialized.UserModels) { UserModelIDsJArray.Add(CurrentModel); } foreach (var CurrentSharedModel in UserDeserialized.UserSharedModels) { UserSharedModelIDsJArray.Add(CurrentSharedModel); } var RequestObject = new JObject() { ["userModelIds"] = UserModelIDsJArray, ["userSharedModelIds"] = UserSharedModelIDsJArray }; // 3d/models/internal/check_models_exist will return CheckedUserModelIDs and CheckedUserSharedModelIDs list List <string> CheckedUserModelIDs = new List <string>(); List <string> CheckedUserSharedModelIDs = new List <string>(); GetTracingService()?.On_FromServiceToService_Sent(_Context, _ErrorMessageAction); var Result = BWebServiceExtraUtilities.InterServicesRequest(new BWebServiceExtraUtilities.InterServicesRequestRequest() { DestinationServiceUrl = CADFileServiceEndpoint + "/3d/models/internal/check_models_exist?secret=" + InternalCallPrivateKey, RequestMethod = "POST", bWithAuthToken = true, UseContextHeaders = _Context, ContentType = "application/json", Content = new BStringOrStream(RequestObject.ToString()), ExcludeHeaderKeysForRequest = null }, false, _ErrorMessageAction); GetTracingService()?.On_FromServiceToService_Received(_Context, _ErrorMessageAction); string ResponseContentAsString = ""; JObject ResponseContentAsJson = null; try { ResponseContentAsString = Result.Content.String; ResponseContentAsJson = JObject.Parse(ResponseContentAsString); var ArrayUserModelsTmp = (JArray)ResponseContentAsJson["checkedUserModelIds"]; if (ArrayUserModelsTmp != null) { foreach (var Tmp in ArrayUserModelsTmp) { CheckedUserModelIDs.Add((string)Tmp); } } var ArraySharedUserModelsTmp = (JArray)ResponseContentAsJson["checkedUserSharedModelIds"]; if (ArraySharedUserModelsTmp != null) { foreach (var Tmp in ArraySharedUserModelsTmp) { CheckedUserSharedModelIDs.Add((string)Tmp); } } } catch (Exception e) { _ErrorMessageAction?.Invoke("Cleanup_UserModels: Error occurred during reading response/parsing json: " + e.Message + ", trace: " + e.StackTrace + ", response content: " + ResponseContentAsString + ", response code: " + Result.ResponseCode); continue; } if (!Result.bSuccess || Result.ResponseCode >= 400) { _ErrorMessageAction?.Invoke("Cleanup_UserModels: Request did not end up with success. Response content: " + ResponseContentAsString + ", response code: " + Result.ResponseCode); continue; } UserDeserialized.UserModels = new List <string>(CheckedUserModelIDs); UserDeserialized.UserSharedModels = new List <string>(CheckedUserSharedModelIDs); if (!DatabaseService.UpdateItem(//Fire and forget is not suitable here since there are following calls after DB update which will change the DB structure UserDBEntry.DBSERVICE_USERS_TABLE(), UserDBEntry.KEY_NAME_USER_ID, UserID_Primitive, JObject.Parse(JsonConvert.SerializeObject(UserDeserialized)), out JObject _, EBReturnItemBehaviour.DoNotReturn, null, _ErrorMessageAction)) { continue; } } finally { Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, UserDBEntry.DBSERVICE_USERS_TABLE(), UserID, _ErrorMessageAction); } } }
private BWebServiceResponse CreateUser(HttpListenerContext _Context, Action <string> _ErrorMessageAction) { var NewUserParameters = new JObject(); bool bIsInternalCall = BWebUtilities.DoesContextContainHeader(out List <string> ICHVs, out string _, _Context, "internal-call-secret") && BUtility.CheckAndGetFirstStringFromList(ICHVs, out string ICH) && ICH == CommonData.INTERNAL_CALL_PRIVATE_KEY; using (var InputStream = _Context.Request.InputStream) { using (var ResponseReader = new StreamReader(InputStream)) { try { var ParsedBody = JObject.Parse(ResponseReader.ReadToEnd()); var PropertiesList = new List <string>(); foreach (var Child in ParsedBody) { PropertiesList.Add(Child.Key); } foreach (var MustHaveProperty in UserDBEntry.MustHaveProperties) { if (!PropertiesList.Contains(MustHaveProperty)) { return(BWebResponse.BadRequest("Request body must contain all necessary fields.")); } } foreach (var Child in ParsedBody) { if (UserDBEntry.UpdatableProperties.Contains(Child.Key)) { if (!UserDBEntry.UpdatablePropertiesValidityCheck[Child.Key](Child.Value)) { return(BWebResponse.BadRequest("Given field " + Child.Key + " has invalid value.")); } NewUserParameters[Child.Key] = Child.Value; } } } catch (Exception e) { _ErrorMessageAction?.Invoke("User_CreateListUsers->UpdateUserInfo: Read request body stage has failed. Exception: " + e.Message + ", Trace: " + e.StackTrace); return(BWebResponse.BadRequest("Malformed request body. Request must be a valid json form.")); } } } int ExistenceTrial = 0; string NewUserID = null; while (NewUserID == null && ExistenceTrial < 3) { if (!UserDBEntry.GenerateUserID(out NewUserID, _ErrorMessageAction)) { return(BWebResponse.InternalError("User ID generation has failed.")); } if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, UserDBEntry.DBSERVICE_USERS_TABLE(), NewUserID, _ErrorMessageAction)) { return(BWebResponse.InternalError("Atomic operation control has failed.")); } if (!DatabaseService.GetItem( UserDBEntry.DBSERVICE_USERS_TABLE(), UserDBEntry.KEY_NAME_USER_ID, new BPrimitiveType(NewUserID), UserDBEntry.MustHaveProperties, out JObject ExistenceCheck, _ErrorMessageAction)) { return(BWebResponse.InternalError("Database existence check operation has failed.")); } if (ExistenceCheck != null) { Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, UserDBEntry.DBSERVICE_USERS_TABLE(), NewUserID, _ErrorMessageAction); NewUserID = null; ExistenceTrial++; } else { break; } } if (NewUserID == null) { return(BWebResponse.InternalError("Unique ID generation operation has failed.")); } //For other elements to be created without any elements var NewUserObject = JsonConvert.DeserializeObject <UserDBEntry>(NewUserParameters.ToString()); bool bEmailAtomicnessSet = false, bUsernameAtomicnessSet = false; try { if (NewUserObject.UserEmail != null && NewUserObject.UserEmail.Length > 0) { NewUserObject.UserEmail = NewUserObject.UserEmail.ToLower(); if (!bIsInternalCall && NewUserObject.UserEmail.EndsWith(Controller_SSOAccessToken.EMAIL_USER_NAME_POSTFIX)) { return(BWebResponse.BadRequest("E-mail address cannot end with " + Controller_SSOAccessToken.EMAIL_USER_NAME_POSTFIX)); } if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_USER_EMAIL + ":" + NewUserObject.UserEmail, _ErrorMessageAction)) { return(BWebResponse.InternalError("Atomic operation control has failed.")); } bEmailAtomicnessSet = true; if (!DatabaseService.GetItem( UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_USER_EMAIL, new BPrimitiveType(NewUserObject.UserEmail), UniqueUserFieldsDBEntry.Properties, out JObject _ExistenceCheck, _ErrorMessageAction)) { return(BWebResponse.InternalError("Database operation failed.")); } if (_ExistenceCheck != null) { return(BWebResponse.Conflict("A user with same user e-mail already exists.")); } } if (NewUserObject.UserName != null && NewUserObject.UserName.Length > 0) { if (!bIsInternalCall && NewUserObject.UserName.EndsWith(Controller_SSOAccessToken.EMAIL_USER_NAME_POSTFIX)) { return(BWebResponse.BadRequest("Username cannot end with " + Controller_SSOAccessToken.EMAIL_USER_NAME_POSTFIX)); } if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_USER_NAME + ":" + NewUserObject.UserName, _ErrorMessageAction)) { return(BWebResponse.InternalError("Atomic operation control has failed.")); } bUsernameAtomicnessSet = true; if (!DatabaseService.GetItem( UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_USER_NAME, new BPrimitiveType(NewUserObject.UserName), UniqueUserFieldsDBEntry.Properties, out JObject _ExistenceCheck, _ErrorMessageAction)) { return(BWebResponse.InternalError("Database operation failed.")); } if (_ExistenceCheck != null) { return(BWebResponse.Conflict("A user with same username already exists.")); } } if (!Controller_Rights_Internal.Get().PerformGetRequestToGetGloballySharedModelIds(out List <string> GloballySharedModelIds, _ErrorMessageAction)) { return(BWebResponse.InternalError("Get-globally-shared-models operation failed.")); } NewUserObject.UserSharedModels = GloballySharedModelIds; if (!DatabaseService.UpdateItem( UserDBEntry.DBSERVICE_USERS_TABLE(), UserDBEntry.KEY_NAME_USER_ID, new BPrimitiveType(NewUserID), JObject.Parse(JsonConvert.SerializeObject(NewUserObject)), out JObject _, EBReturnItemBehaviour.DoNotReturn, DatabaseService.BuildAttributeNotExistCondition(UserDBEntry.KEY_NAME_USER_ID), _ErrorMessageAction)) { return(BWebResponse.InternalError("Database operation failed.")); } if (!Controller_Rights_Internal.Get().GetUserDefaultRights(out JArray DefaultRights, NewUserID, _ErrorMessageAction)) { Controller_DeliveryEnsurer.Get().DB_DeleteItem_FireAndForget( _Context, UserDBEntry.DBSERVICE_USERS_TABLE(), UserDBEntry.KEY_NAME_USER_ID, new BPrimitiveType(NewUserID)); return(BWebResponse.InternalError("Default rights obtaining operation has failed.")); } if (!Controller_Rights_Internal.Get().GrantUserWithRights(true, NewUserID, DefaultRights, _ErrorMessageAction)) { Controller_DeliveryEnsurer.Get().DB_DeleteItem_FireAndForget( _Context, UserDBEntry.DBSERVICE_USERS_TABLE(), UserDBEntry.KEY_NAME_USER_ID, new BPrimitiveType(NewUserID)); return(BWebResponse.InternalError("Right granting operation has failed.")); } if (NewUserObject.UserEmail != null && NewUserObject.UserEmail.Length > 0) { Controller_DeliveryEnsurer.Get().DB_UpdateItem_FireAndForget( _Context, UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_USER_EMAIL, new BPrimitiveType(NewUserObject.UserEmail), new JObject() { [UserDBEntry.KEY_NAME_USER_ID] = NewUserID }); } if (NewUserObject.UserName != null && NewUserObject.UserName.Length > 0) { Controller_DeliveryEnsurer.Get().DB_UpdateItem_FireAndForget( _Context, UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_USER_NAME, new BPrimitiveType(NewUserObject.UserName), new JObject() { [UserDBEntry.KEY_NAME_USER_ID] = NewUserID }); } Controller_UserActions.Get().BroadcastUserAction(new Action_UserCreated( NewUserID, NewUserObject.UserEmail, NewUserObject.UserName ), _ErrorMessageAction); } finally { Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, UserDBEntry.DBSERVICE_USERS_TABLE(), NewUserID, _ErrorMessageAction); if (bEmailAtomicnessSet) { Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_USER_EMAIL + ":" + NewUserObject.UserEmail, _ErrorMessageAction); } if (bUsernameAtomicnessSet) { Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_USER_NAME + ":" + NewUserObject.UserName, _ErrorMessageAction); } } return(BWebResponse.StatusCreated("User has been created.", new JObject() { [UserDBEntry.KEY_NAME_USER_ID] = NewUserID })); }