Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }
Пример #4
0
        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);
            }
        }
Пример #5
0
        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);
            }
        }
Пример #6
0
        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);
            }
        }
Пример #7
0
                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) { }
                }
Пример #8
0
 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
                     }
                 }
             }
         }
Пример #9
0
        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);
            }
        }
Пример #10
0
        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."));
        }
Пример #11
0
        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);
        }
Пример #12
0
        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));
        }
Пример #13
0
        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);
                }
            }
        }
Пример #14
0
        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."));
        }
Пример #15
0
        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;
                    }
                }
Пример #16
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);
        }
Пример #17
0
        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);
        }
Пример #18
0
        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);
        }
Пример #19
0
        //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."));
        }
Пример #20
0
        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);
                }
            }
        }
Пример #21
0
            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);
                    }
                }
            }
Пример #22
0
            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);
                    }
                }
            }
Пример #23
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);
            }
Пример #24
0
        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);
                }
            }
        }
Пример #25
0
            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);
                        }
                    }
                }
            }
Пример #26
0
                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);
                }
Пример #27
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);
                    }
                }
            }
Пример #28
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
            }));
        }