protected override BWebServiceResponse Process(HttpListenerContext _Context, Action <string> _ErrorMessageAction = null) { if (_Context.Request.HttpMethod != "POST") { _ErrorMessageAction?.Invoke("DeleteTestUser: POST method is accepted. But received request method: " + _Context.Request.HttpMethod); return(BWebResponse.MethodNotAllowed("POST method is accepted. But received request method: " + _Context.Request.HttpMethod)); } JObject ParsedBody; using (var InputStream = _Context.Request.InputStream) { using (var ResponseReader = new StreamReader(InputStream)) { try { ParsedBody = JObject.Parse(ResponseReader.ReadToEnd()); } catch (Exception e) { _ErrorMessageAction?.Invoke("DeleteTestUser-> 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 (!ParsedBody.ContainsKey(AuthDBEntry.USER_ID_PROPERTY)) { _ErrorMessageAction?.Invoke("DeleteTestUser-> Request does not have required fields."); return(BWebResponse.BadRequest("Request does not have required fields.")); } var UserId = (string)ParsedBody[AuthDBEntry.USER_ID_PROPERTY]; if (!DeleteUser(UserId, _ErrorMessageAction)) { return(BWebResponse.InternalError("User delete process has been failed.")); } return(BWebResponse.StatusCreated("Test user has been deleted.", new JObject() { [AuthDBEntry.USER_ID_PROPERTY] = UserId })); }
private BWebServiceResponse OnRequest_CreateTestUser(HttpListenerContext _Context, Action <string> _ErrorMessageAction) { string OptionalName = BUtility.RandomString(12, true) + "_test"; string EmailWithoutPostfix = OptionalName + "@test.com"; var AccumulatedSSOMethodRightsOrDefault = new JArray() { JObject.Parse(JsonConvert.SerializeObject( new AccessScope() { WildcardPath = "*", AccessRights = new List <string>() { "GET", "POST", "PUT", "DELETE" } })) }; if (!CreateUser(out string _UserID, EmailWithoutPostfix, _ErrorMessageAction, OptionalName)) { return(BWebResponse.InternalError("User creation process has been failed.")); } if (!CreateAuthMethod(out string _ApiKey, _UserID, _ErrorMessageAction)) { return(BWebResponse.InternalError("Auth method creation process has been failed.")); } if (!Controller_Rights_Internal.Get().GrantUserWithRights(false, _UserID, AccumulatedSSOMethodRightsOrDefault, _ErrorMessageAction)) { return(BWebResponse.InternalError("Grant user with rights process has been failed.")); } return(BWebResponse.StatusCreated("User has been created.", new JObject() { [UserDBEntry.KEY_NAME_USER_ID] = _UserID, [AuthMethod.API_KEY_PROPERTY] = _ApiKey, [AuthMethod.USER_EMAIL_PROPERTY] = EmailWithoutPostfix })); }
private BWebServiceResponse AddUpdateBaseRightsForUser(HttpListenerContext _Context, Action <string> _ErrorMessageAction) { var NewBaseScopeListFromRequest = new List <AccessScope>(); using (var InputStream = _Context.Request.InputStream) { using (var ResponseReader = new StreamReader(InputStream)) { try { var NewScopes = JArray.Parse(ResponseReader.ReadToEnd()); foreach (JObject NewScope in NewScopes) { var ConvertedScope = JsonConvert.DeserializeObject <AccessScope>(NewScope.ToString()); for (int i = ConvertedScope.AccessRights.Count - 1; i >= 0; i--) { ConvertedScope.AccessRights[i] = ConvertedScope.AccessRights[i].ToUpper(); if (!AccessScopeLibrary.ACCESS_RIGHTS.Contains(ConvertedScope.AccessRights[i])) { ConvertedScope.AccessRights.RemoveAt(i); } } if (ConvertedScope.AccessRights.Count > 0) { ConvertedScope.AccessRights = ConvertedScope.AccessRights.Distinct().ToList(); NewBaseScopeListFromRequest.Add(ConvertedScope); } } } catch (Exception e) { _ErrorMessageAction?.Invoke("User_AddListBaseRights_ForUser->AddUpdateBaseRightsForUser: 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 (NewBaseScopeListFromRequest.Count == 0) { return(BWebResponse.BadRequest("Request does not contain any valid base scope. Access rights can be: " + AccessScopeLibrary.GetPossibleAccessRightsText())); } 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 NewBaseAccessScopeAsJArray = new JArray(); var NewBaseAccessScopeAsList = new List <AccessScope>(); bool bUpdateOccurredForUserEntry = false; if (UserObject.ContainsKey(UserDBEntry.BASE_ACCESS_SCOPE_PROPERTY)) { var BaseAccessScopeAsArray = (JArray)UserObject[UserDBEntry.BASE_ACCESS_SCOPE_PROPERTY]; foreach (var NewScope in NewBaseScopeListFromRequest) { bool bNewScopeFoundInExisting = false; NewScope.AccessRights.Sort(); foreach (JObject ExistingScopeObject in BaseAccessScopeAsArray) { bool bChangeOccurredForScope = false; var ExistingScope = JsonConvert.DeserializeObject <AccessScope>(ExistingScopeObject.ToString()); ExistingScope.AccessRights.Sort(); if (!bNewScopeFoundInExisting && ExistingScope.WildcardPath == NewScope.WildcardPath) { bNewScopeFoundInExisting = true; if (NewScope.AccessRights.Count != ExistingScope.AccessRights.Count) { bUpdateOccurredForUserEntry = true; NewBaseAccessScopeAsList.Add(NewScope); NewBaseAccessScopeAsJArray.Add(JObject.Parse(JsonConvert.SerializeObject(NewScope))); break; } else { bool bLocalChangeExists = false; for (int i = 0; i < NewScope.AccessRights.Count; i++) { if (NewScope.AccessRights[i] != ExistingScope.AccessRights[i]) { bLocalChangeExists = true; break; } } if (bLocalChangeExists) { bUpdateOccurredForUserEntry = true; bChangeOccurredForScope = true; NewBaseAccessScopeAsList.Add(NewScope); NewBaseAccessScopeAsJArray.Add(JObject.Parse(JsonConvert.SerializeObject(NewScope))); } } } if (!bChangeOccurredForScope) { NewBaseAccessScopeAsList.Add(ExistingScope); NewBaseAccessScopeAsJArray.Add(ExistingScopeObject); } } if (!bNewScopeFoundInExisting) { NewBaseAccessScopeAsList.Add(NewScope); NewBaseAccessScopeAsJArray.Add(JObject.Parse(JsonConvert.SerializeObject(NewScope))); bUpdateOccurredForUserEntry = true; } } } if (bUpdateOccurredForUserEntry) { UserObject[UserDBEntry.BASE_ACCESS_SCOPE_PROPERTY] = NewBaseAccessScopeAsJArray; MemoryService.SetKeyValue(CommonData.MemoryQueryParameters, new Tuple <string, BPrimitiveType>[] { new Tuple <string, BPrimitiveType>( UserBaseAccessMEntry.M_KEY_NAME_USER_ID + RequestedUserID, new BPrimitiveType(JsonConvert.SerializeObject(new UserBaseAccessMEntry() { BaseAccessScope = NewBaseAccessScopeAsList }))) }, _ErrorMessageAction); Controller_DeliveryEnsurer.Get().DB_UpdateItem_FireAndForget( _Context, UserDBEntry.DBSERVICE_USERS_TABLE(), UserDBEntry.KEY_NAME_USER_ID, UserKey, UserObject); } return(BWebResponse.StatusCreated("New base rights have been added.")); }
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 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 })); }
private BWebServiceResponse AddRevision(HttpListenerContext _Context, Action <string> _ErrorMessageAction) { if (!CommonMethods.TryParsingRequestFor( _Context, out JObject _, true, out Revision NewRevisionObject, out BWebServiceResponse FailureResponse, _ErrorMessageAction)) { return(FailureResponse); } if (!CommonMethods.TryGettingModelInfo( DatabaseService, RequestedModelID, out JObject _, true, out ModelDBEntry Model, out FailureResponse, _ErrorMessageAction)) { return(FailureResponse); } var UpperCaseNewRevisionName = NewRevisionObject.RevisionName.ToUpper(); int BiggestExistingIndex = -1; foreach (var CurrentRev in Model.ModelRevisions) { if (CurrentRev.RevisionName.ToUpper() == UpperCaseNewRevisionName) { return(BWebResponse.Conflict("A revision with same " + Revision.REVISION_NAME_PROPERTY + " already exists.")); } BiggestExistingIndex = BiggestExistingIndex < CurrentRev.RevisionIndex ? CurrentRev.RevisionIndex : BiggestExistingIndex; } int NewRevisionIndex = BiggestExistingIndex + 1; NewRevisionObject.RevisionIndex = NewRevisionIndex; NewRevisionObject.CreationTime = CommonMethods.GetTimeAsCreationTime(); Model.MRVLastUpdateTime = NewRevisionObject.CreationTime; Model.ModelRevisions.Add(NewRevisionObject); 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_ModelRevisionCreated ( RequestedModelID, NewRevisionObject.RevisionIndex, Model.ModelOwnerUserID, Model.ModelSharedWithUserIDs, AuthorizedUser.UserID ), _ErrorMessageAction); return(BWebResponse.StatusCreated("Revision has been created.", new JObject() { [Revision.REVISION_INDEX_PROPERTY] = NewRevisionIndex })); }