//TODO: If SSO is enabled for user; when it loses access to the tenant, delete all rights but keep the models and user. private BWebServiceResponse DeleteAccessMethodForUser(HttpListenerContext _Context, out bool _bSetClearanceForApiKey, out string _ApiKey, Action <string> _ErrorMessageAction) { _bSetClearanceForApiKey = false; _ApiKey = null; var UserKey = new BPrimitiveType(RequestedUserID); if (!DatabaseService.GetItem( UserDBEntry.DBSERVICE_USERS_TABLE(), UserDBEntry.KEY_NAME_USER_ID, UserKey, UserDBEntry.Properties, out JObject UserObject, _ErrorMessageAction)) { return(BWebResponse.InternalError("Database fetch-user-info operation has failed.")); } if (UserObject == null) { return(BWebResponse.NotFound("User does not exist.")); } if (!UserObject.ContainsKey(UserDBEntry.AUTH_METHODS_PROPERTY)) { return(BWebResponse.NotFound("User does not have any auth method.")); } bool bFound = false; var AuthMethodsArray = (JArray)UserObject[UserDBEntry.AUTH_METHODS_PROPERTY]; for (var i = (AuthMethodsArray.Count - 1); i >= 0; i--) { var MethodObject = (JObject)AuthMethodsArray[i]; var Method = JsonConvert.DeserializeObject <AuthMethod>(MethodObject.ToString()); string AuthMethodKey = null; switch (Method.Method) { case AuthMethod.Methods.USER_EMAIL_PASSWORD_METHOD: { if (!bIsInternalCall && Method.UserEmail.EndsWith(Controller_SSOAccessToken.EMAIL_USER_NAME_POSTFIX)) { return(BWebResponse.BadRequest("This auth method cannot be deleted.")); } AuthMethodKey = Method.UserEmail + Method.PasswordMD5; break; } case AuthMethod.Methods.USER_NAME_PASSWORD_METHOD: { AuthMethodKey = Method.UserName + Method.PasswordMD5; break; } case AuthMethod.Methods.API_KEY_METHOD: { AuthMethodKey = Method.ApiKey; _bSetClearanceForApiKey = true; _ApiKey = Method.ApiKey; if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_API_KEY + ":" + Method.ApiKey, _ErrorMessageAction)) { return(BWebResponse.InternalError("Atomic operation control has failed.")); } break; } } if (AuthMethodKey == RequestedAuthMethodKey) { AuthMethodsArray.RemoveAt(i); bFound = true; } } if (!bFound) { return(BWebResponse.NotFound("Auth method does not exist.")); } //Update UserDBEntry Controller_DeliveryEnsurer.Get().DB_UpdateItem_FireAndForget( _Context, UserDBEntry.DBSERVICE_USERS_TABLE(), UserDBEntry.KEY_NAME_USER_ID, UserKey, UserObject); //Delete AuthDBEntry Controller_DeliveryEnsurer.Get().DB_DeleteItem_FireAndForget( _Context, AuthDBEntry.DBSERVICE_AUTHMETHODS_TABLE(), AuthDBEntry.KEY_NAME_AUTH_DB_ENTRY, new BPrimitiveType(RequestedAuthMethodKey)); if (_bSetClearanceForApiKey) { //Delete ApiKey from UniqueUserFields Controller_DeliveryEnsurer.Get().DB_DeleteItem_FireAndForget( _Context, UniqueUserFieldsDBEntry.DBSERVICE_UNIQUEUSERFIELDS_TABLE(), UniqueUserFieldsDBEntry.KEY_NAME_API_KEY, new BPrimitiveType(_ApiKey)); } //Delete from cache MemoryService.DeleteKey( CommonData.MemoryQueryParameters, AuthDBEntry.KEY_NAME_AUTH_DB_ENTRY + RequestedAuthMethodKey, _ErrorMessageAction); return(BWebResponse.StatusOK("Access method has been deleted.")); }
private void Cleanup_UserModels(HttpListenerContext _Context, Action <string> _ErrorMessageAction = null) { if (!DatabaseService.ScanTable( UserDBEntry.DBSERVICE_USERS_TABLE(), out List <JObject> UserEntries, _ErrorMessageAction)) { _ErrorMessageAction?.Invoke("Cleanup_UserModels: Table does not exist or ScanTable operation has failed."); return; } if (UserEntries.Count == 0) { return; } //Get cad file service endpoint from internal set state if (!InternalSetState.GetValueFromMemoryService( out string CADFileServiceEndpoint, InternalSetState.CAD_FILE_SERVICE_ENDPOINT_PROPERTY, MemoryService, (string _Message) => { _ErrorMessageAction?.Invoke("Cleanup_UserModels: Unable to get CadFileServiceEndpoint: " + _Message); })) { return; } foreach (var UserJObject in UserEntries) { var UserID = (string)UserJObject[UserDBEntry.KEY_NAME_USER_ID]; if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, UserDBEntry.DBSERVICE_USERS_TABLE(), UserID, _ErrorMessageAction)) { continue; } try { var UserID_Primitive = new BPrimitiveType(UserID); var UserDeserialized = JsonConvert.DeserializeObject <UserDBEntry>(UserJObject.ToString()); var UserModelIDsJArray = new JArray(); var UserSharedModelIDsJArray = new JArray(); foreach (var CurrentModel in UserDeserialized.UserModels) { UserModelIDsJArray.Add(CurrentModel); } foreach (var CurrentSharedModel in UserDeserialized.UserSharedModels) { UserSharedModelIDsJArray.Add(CurrentSharedModel); } var RequestObject = new JObject() { ["userModelIds"] = UserModelIDsJArray, ["userSharedModelIds"] = UserSharedModelIDsJArray }; // 3d/models/internal/check_models_exist will return CheckedUserModelIDs and CheckedUserSharedModelIDs list List <string> CheckedUserModelIDs = new List <string>(); List <string> CheckedUserSharedModelIDs = new List <string>(); GetTracingService()?.On_FromServiceToService_Sent(_Context, _ErrorMessageAction); var Result = BWebServiceExtraUtilities.InterServicesRequest(new BWebServiceExtraUtilities.InterServicesRequestRequest() { DestinationServiceUrl = CADFileServiceEndpoint + "/3d/models/internal/check_models_exist?secret=" + InternalCallPrivateKey, RequestMethod = "POST", bWithAuthToken = true, UseContextHeaders = _Context, ContentType = "application/json", Content = new BStringOrStream(RequestObject.ToString()), ExcludeHeaderKeysForRequest = null }, false, _ErrorMessageAction); GetTracingService()?.On_FromServiceToService_Received(_Context, _ErrorMessageAction); string ResponseContentAsString = ""; JObject ResponseContentAsJson = null; try { ResponseContentAsString = Result.Content.String; ResponseContentAsJson = JObject.Parse(ResponseContentAsString); var ArrayUserModelsTmp = (JArray)ResponseContentAsJson["checkedUserModelIds"]; if (ArrayUserModelsTmp != null) { foreach (var Tmp in ArrayUserModelsTmp) { CheckedUserModelIDs.Add((string)Tmp); } } var ArraySharedUserModelsTmp = (JArray)ResponseContentAsJson["checkedUserSharedModelIds"]; if (ArraySharedUserModelsTmp != null) { foreach (var Tmp in ArraySharedUserModelsTmp) { CheckedUserSharedModelIDs.Add((string)Tmp); } } } catch (Exception e) { _ErrorMessageAction?.Invoke("Cleanup_UserModels: Error occurred during reading response/parsing json: " + e.Message + ", trace: " + e.StackTrace + ", response content: " + ResponseContentAsString + ", response code: " + Result.ResponseCode); continue; } if (!Result.bSuccess || Result.ResponseCode >= 400) { _ErrorMessageAction?.Invoke("Cleanup_UserModels: Request did not end up with success. Response content: " + ResponseContentAsString + ", response code: " + Result.ResponseCode); continue; } UserDeserialized.UserModels = new List <string>(CheckedUserModelIDs); UserDeserialized.UserSharedModels = new List <string>(CheckedUserSharedModelIDs); if (!DatabaseService.UpdateItem(//Fire and forget is not suitable here since there are following calls after DB update which will change the DB structure UserDBEntry.DBSERVICE_USERS_TABLE(), UserDBEntry.KEY_NAME_USER_ID, UserID_Primitive, JObject.Parse(JsonConvert.SerializeObject(UserDeserialized)), out JObject _, EBReturnItemBehaviour.DoNotReturn, null, _ErrorMessageAction)) { continue; } } finally { Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, UserDBEntry.DBSERVICE_USERS_TABLE(), UserID, _ErrorMessageAction); } } }
private BWebServiceResponse 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); }
private void Cleanup_AuthMethods(Action <string> _ErrorMessageAction = null) { if (!DatabaseService.ScanTable( AuthDBEntry.DBSERVICE_AUTHMETHODS_TABLE(), out List <JObject> AuthEntries, _ErrorMessageAction)) { _ErrorMessageAction?.Invoke("Cleanup_AuthMethods: Table does not exist or ScanTable operation has failed."); return; } if (AuthEntries.Count == 0) { return; } foreach (var Current in AuthEntries) { var Casted = JsonConvert.DeserializeObject <AuthDBEntry>(Current.ToString()); var EntryKey = (string)Current[AuthDBEntry.KEY_NAME_AUTH_DB_ENTRY]; if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, UserDBEntry.DBSERVICE_USERS_TABLE(), Casted.UserID, _ErrorMessageAction)) { continue; } try { bool bDeleteEntry = false; if (!DatabaseService.GetItem( UserDBEntry.DBSERVICE_USERS_TABLE(), UserDBEntry.KEY_NAME_USER_ID, new BPrimitiveType(Casted.UserID), UserDBEntry.Properties, out JObject UserObject, _ErrorMessageAction)) { continue; } if (UserObject == null) { //User does not exist bDeleteEntry = true; } else { bool bFound = false; bool bSSOMethod = false; bool bSSORefreshTokenExpired = false; var User = JsonConvert.DeserializeObject <UserDBEntry>(UserObject.ToString()); for (var i = 0; i < User.AuthMethods.Count; i++) { var UserAuthMethod = User.AuthMethods[i]; var UserAuthMethodKey = ""; if (UserAuthMethod.Method == AuthMethod.Methods.USER_EMAIL_PASSWORD_METHOD) { if (UserAuthMethod.UserEmail == null || UserAuthMethod.PasswordMD5 == null || UserAuthMethod.UserEmail.Length == 0 || UserAuthMethod.PasswordMD5.Length == 0) { continue; } UserAuthMethodKey = UserAuthMethod.UserEmail + UserAuthMethod.PasswordMD5; if (UserAuthMethodKey == EntryKey) { bFound = true; //SSO Auth Method Expiry Check if (UserAuthMethod.UserEmail.EndsWith(Controller_SSOAccessToken.EMAIL_USER_NAME_POSTFIX)) { bSSOMethod = true; var QueryParameters = Controller_SSOAccessToken.MakeSSOQueryParameters(UserAuthMethod.PasswordMD5); if (Controller_SSOAccessToken.IsTokenExpiredOrInvalid(out Dictionary <string, BPrimitiveType> _Result, MemoryService, QueryParameters, _ErrorMessageAction) || _Result == null) { bSSORefreshTokenExpired = true; User.AuthMethods.RemoveAt(i); } } break; } } else { if (UserAuthMethod.Method == AuthMethod.Methods.USER_NAME_PASSWORD_METHOD) { if (UserAuthMethod.UserName == null || UserAuthMethod.PasswordMD5 == null || UserAuthMethod.UserName.Length == 0 || UserAuthMethod.PasswordMD5.Length == 0) { continue; } UserAuthMethodKey = UserAuthMethod.UserName + UserAuthMethod.PasswordMD5; } else if (UserAuthMethod.Method == AuthMethod.Methods.API_KEY_METHOD) { UserAuthMethodKey = UserAuthMethod.ApiKey; } if (UserAuthMethodKey == EntryKey) { bFound = true; break; } } } if (!bFound) { bDeleteEntry = true; } else if (bSSOMethod && bSSORefreshTokenExpired) { _ErrorMessageAction?.Invoke("Cleanup_AuthMethods: Expired sso auth method has been found. Deleting the entry."); bDeleteEntry = true; DatabaseService.UpdateItem( UserDBEntry.DBSERVICE_USERS_TABLE(), UserDBEntry.KEY_NAME_USER_ID, new BPrimitiveType(Casted.UserID), JObject.Parse(JsonConvert.SerializeObject(User)), out JObject _, EBReturnItemBehaviour.DoNotReturn, null, _ErrorMessageAction); } } if (bDeleteEntry) { DatabaseService.DeleteItem( AuthDBEntry.DBSERVICE_AUTHMETHODS_TABLE(), AuthDBEntry.KEY_NAME_AUTH_DB_ENTRY, new BPrimitiveType(EntryKey), out JObject _, EBReturnItemBehaviour.DoNotReturn, _ErrorMessageAction); MemoryService.DeleteKey( CommonData.MemoryQueryParameters, AuthDBEntry.KEY_NAME_AUTH_DB_ENTRY + EntryKey, _ErrorMessageAction); } } finally { Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, UserDBEntry.DBSERVICE_USERS_TABLE(), Casted.UserID, _ErrorMessageAction); } } }
private 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); } } } }
private BWebServiceResponse DeleteBaseRightForUser(HttpListenerContext _Context, Action <string> _ErrorMessageAction) { 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.BASE_ACCESS_SCOPE_PROPERTY)) { return(BWebResponse.NotFound("User does not have any base rights.")); } var BaseAccessScopeAsArray = (JArray)UserObject[UserDBEntry.BASE_ACCESS_SCOPE_PROPERTY]; var NewBaseAccessScopeAsList = new List <AccessScope>(); //Check existence of access scope var ExistingAccessScopeIndex = -1; int j = 0; foreach (JObject BaseAccessScopeObject in BaseAccessScopeAsArray) { var Scope = JsonConvert.DeserializeObject <AccessScope>(BaseAccessScopeObject.ToString()); if (ExistingAccessScopeIndex == -1 && Scope.WildcardPath == RequestedBaseRightWildcard) { ExistingAccessScopeIndex = j; } else { NewBaseAccessScopeAsList.Add(Scope); } j++; } if (ExistingAccessScopeIndex == -1) { return(BWebResponse.NotFound("User does not have the given base right.")); } BaseAccessScopeAsArray.RemoveAt(ExistingAccessScopeIndex); UserObject[UserDBEntry.BASE_ACCESS_SCOPE_PROPERTY] = BaseAccessScopeAsArray; Controller_DeliveryEnsurer.Get().DB_UpdateItem_FireAndForget( _Context, UserDBEntry.DBSERVICE_USERS_TABLE(), UserDBEntry.KEY_NAME_USER_ID, UserKey, UserObject); MemoryService.SetKeyValue(CommonData.MemoryQueryParameters, new Tuple <string, BPrimitiveType>[] { new Tuple <string, BPrimitiveType>( UserBaseAccessMEntry.M_KEY_NAME_USER_ID + RequestedUserID, new BPrimitiveType(JsonConvert.SerializeObject(new UserBaseAccessMEntry() { BaseAccessScope = NewBaseAccessScopeAsList }))) }, _ErrorMessageAction); return(BWebResponse.StatusOK("Base right has been deleted.")); }
private BWebServiceResponse OnRequest_Internal(HttpListenerContext _Context, Action <string> _ErrorMessageAction = null) { if (_Context.Request.HttpMethod != "POST" && _Context.Request.HttpMethod != "DELETE") { _ErrorMessageAction?.Invoke("User_UpdateDeleteBaseRight_ForUser: POST and DELETE methods are accepted. But received request method: " + _Context.Request.HttpMethod); return(BWebResponse.MethodNotAllowed("POST and DELETE methods are accepted. But received request method: " + _Context.Request.HttpMethod)); } RequestedUserID = RestfulUrlParameters[RestfulUrlParameter_UsersKey]; RequestedBaseRightWildcard = WebUtility.UrlDecode(RestfulUrlParameters[RestfulUrlParameter_BaseAccessRightsKey]); RequestedBaseRightWildcard_Regex = BUtility.WildCardToRegular(RequestedBaseRightWildcard); if (!Controller_AtomicDBOperation.Get().GetClearanceForDBOperation(InnerProcessor, UserDBEntry.DBSERVICE_USERS_TABLE(), RequestedUserID, _ErrorMessageAction)) { return(BWebResponse.InternalError("Atomic operation control has failed.")); } BWebServiceResponse Result; if (_Context.Request.HttpMethod == "POST") { Result = UpdateBaseRightForUser(_Context, _ErrorMessageAction); } else { Result = DeleteBaseRightForUser(_Context, _ErrorMessageAction); } Controller_AtomicDBOperation.Get().SetClearanceForDBOperationForOthers(InnerProcessor, UserDBEntry.DBSERVICE_USERS_TABLE(), RequestedUserID, _ErrorMessageAction); return(Result); }
private BWebServiceResponse UpdateBaseRightForUser(HttpListenerContext _Context, Action <string> _ErrorMessageAction) { var NewRights = new List <string>(); using (var InputStream = _Context.Request.InputStream) { using (var ResponseReader = new StreamReader(InputStream)) { try { var NewRightsArray = JArray.Parse(ResponseReader.ReadToEnd()); foreach (string NewRight in NewRightsArray) { var NewRightCaseCorrected = NewRight.ToUpper(); if (AccessScopeLibrary.ACCESS_RIGHTS.Contains(NewRightCaseCorrected)) { NewRights.Add(NewRightCaseCorrected); } } NewRights = NewRights.Distinct().ToList(); NewRights.Sort(); } catch (Exception e) { _ErrorMessageAction?.Invoke("User_UpdateDeleteBaseRight_ForUser->UpdateBaseRightForUser: 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 (NewRights.Count == 0) { return(BWebResponse.BadRequest("Request does not contain any valid access right. Use DELETE method for deleting the scope. Access rights can be: " + AccessScopeLibrary.GetPossibleAccessRightsText())); } var UserKey = new BPrimitiveType(RequestedUserID); if (!DatabaseService.GetItem( UserDBEntry.DBSERVICE_USERS_TABLE(), UserDBEntry.KEY_NAME_USER_ID, UserKey, UserDBEntry.Properties, out JObject UserObject, _ErrorMessageAction)) { return(BWebResponse.InternalError("Database fetch-user-info operation has failed.")); } if (UserObject == null) { return(BWebResponse.NotFound("User does not exist.")); } if (!UserObject.ContainsKey(UserDBEntry.BASE_ACCESS_SCOPE_PROPERTY)) { return(BWebResponse.NotFound("User does not have any base rights.")); } var BaseAccessScopeAsArray = (JArray)UserObject[UserDBEntry.BASE_ACCESS_SCOPE_PROPERTY]; var BaseAccessScopeAsList = new List <AccessScope>(); //Check existence of access scope AccessScope ExistingAccessScope = null; int ExistingAccessScopeIndex = -1; int j = 0; foreach (JObject BaseAccessScopeObject in BaseAccessScopeAsArray) { var Scope = JsonConvert.DeserializeObject <AccessScope>(BaseAccessScopeObject.ToString()); BaseAccessScopeAsList.Add(Scope); if (ExistingAccessScopeIndex == -1 && Scope.WildcardPath == RequestedBaseRightWildcard) { ExistingAccessScope = Scope; ExistingAccessScopeIndex = j; } j++; } if (ExistingAccessScopeIndex == -1) { return(BWebResponse.NotFound("User does not have the given base right.")); } ExistingAccessScope.AccessRights.Sort(); //Check if requested rights are different bool bDifferent = false; if (ExistingAccessScope.AccessRights.Count == NewRights.Count) { for (var i = 0; i < ExistingAccessScope.AccessRights.Count; i++) { if (ExistingAccessScope.AccessRights[i] != NewRights[i]) { bDifferent = true; break; } } } else { bDifferent = true; } if (bDifferent) { ExistingAccessScope.AccessRights = NewRights; BaseAccessScopeAsArray[ExistingAccessScopeIndex] = JObject.Parse(JsonConvert.SerializeObject(ExistingAccessScope)); UserObject[UserDBEntry.BASE_ACCESS_SCOPE_PROPERTY] = BaseAccessScopeAsArray; Controller_DeliveryEnsurer.Get().DB_UpdateItem_FireAndForget( _Context, UserDBEntry.DBSERVICE_USERS_TABLE(), UserDBEntry.KEY_NAME_USER_ID, UserKey, UserObject); MemoryService.SetKeyValue(CommonData.MemoryQueryParameters, new Tuple <string, BPrimitiveType>[] { new Tuple <string, BPrimitiveType>( UserBaseAccessMEntry.M_KEY_NAME_USER_ID + RequestedUserID, new BPrimitiveType(JsonConvert.SerializeObject(new UserBaseAccessMEntry() { BaseAccessScope = BaseAccessScopeAsList }))) }, _ErrorMessageAction); } return(BWebResponse.StatusOK("Base right has been updated.")); }
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 })); }
public static bool FetchBaseAccessRights_ByUserID( IBDatabaseServiceInterface _DatabaseService, IBMemoryServiceInterface _MemoryService, string _UserID, out List <AccessScope> _AccessScopes, out BWebServiceResponse _FailureResponse, Action <string> _ErrorMessageAction = null) { _AccessScopes = null; _FailureResponse = new BWebServiceResponse(); var InMemoryResult = _MemoryService.GetKeyValue(CommonData.MemoryQueryParameters, UserBaseAccessMEntry.M_KEY_NAME_USER_ID + _UserID, _ErrorMessageAction); if (InMemoryResult != null) { try { _AccessScopes = JsonConvert.DeserializeObject <UserBaseAccessMEntry>(InMemoryResult.AsString).BaseAccessScope; return(true); } catch (Exception) { } } if (!_DatabaseService.GetItem( UserDBEntry.DBSERVICE_USERS_TABLE(), UserDBEntry.KEY_NAME_USER_ID, new BPrimitiveType(_UserID), UserDBEntry.Properties, out JObject UserObject, _ErrorMessageAction)) { _FailureResponse = BWebResponse.InternalError("Database fetch-user-info operation has failed."); return(false); } if (UserObject == null) { _FailureResponse = BWebResponse.NotFound("User does not exist."); return(false); } _AccessScopes = new List <AccessScope>(); if (UserObject.ContainsKey(UserDBEntry.BASE_ACCESS_SCOPE_PROPERTY)) { var BaseAccessScopeAsArray = (JArray)UserObject[UserDBEntry.BASE_ACCESS_SCOPE_PROPERTY]; foreach (JObject ScopeObject in BaseAccessScopeAsArray) { _AccessScopes.Add(JsonConvert.DeserializeObject <AccessScope>(ScopeObject.ToString())); } } _MemoryService.SetKeyValue(CommonData.MemoryQueryParameters, new Tuple <string, BPrimitiveType>[] { new Tuple <string, BPrimitiveType>( UserBaseAccessMEntry.M_KEY_NAME_USER_ID + _UserID, new BPrimitiveType(JsonConvert.SerializeObject(new UserBaseAccessMEntry() { BaseAccessScope = _AccessScopes }))) }, _ErrorMessageAction); return(true); }