Exemplo n.º 1
0
            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
                }));
            }
Exemplo n.º 2
0
            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);
            }
Exemplo n.º 3
0
        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);
        }
Exemplo n.º 4
0
        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
            }));
        }