/// <summary> /// "Batch updates" the member profile by accepting an IContextDataObject. This can be used to simplify development with MVC. /// Recommend to use an instance of the MemberProfileData class. /// </summary> /// <param name="memberProfileData">MemeberProfileData instance class containing data.</param> /// <returns>true=success; false=failure</returns> public Boolean SetValues <TModel>(TModel memberProfileData) where TModel : IMemberProfileData { String logMethodName = ".SetValues<TModel>(TModel memberProfileData) where TModel : IMemberProfileData - "; _log.Debug(logMethodName + "Begin Method"); //Lazy load the current data first, we need to be able to know what the orignal state is before making changes. LoadProfileData(); MemberProfileData profile = new MemberProfileData(memberProfileData); profile.Id = this.Id; profile.MemberId = this.MemberId; profile.ProviderKeys = this.ProviderKeys; profile.LastModified = this.LastModified; profile.LastModifiedBy = this.LastModifiedBy; _profileData = profile; _isDirty = true; _log.Debug(logMethodName + "End Method"); return(true); }
/// <summary> /// Creates and instance of the member profile using the passed memberID and accepting the boolean to set anonymous on this instance. /// /// NOTE: All data is lazy loaded on first property access. /// </summary> /// <param name="memberId">Unique member ID to load</param> /// <param name="isAnonymous">true=anonymous; false=not anonymous</param> internal MemberProfile(Object memberId, Boolean isAnonymous) { String logMethodName = ".ctor(Object memberId, Boolean isAnonymous) - "; _log.Debug(logMethodName + "Begin Method"); _isAnonymous = isAnonymous; _memberId = memberId; _provider = IntegrationLoader.CurrentContextDataProvider; _profileData = new MemberProfileData(); _profileData.MemberId = memberId; _orignalProfileData = _profileData; _newProfile = true; if (_isAnonymous) { _profileDataLoaded = true; } _log.Debug(logMethodName + "End Method"); }
/// <summary> /// Accept a MemberProfileData object and use it to update the internal data. /// /// This convieance method preserves ID's so tracking by the developers is not neccassary. /// </summary> /// <typeparam name="TModel">ASA.Web.WTF.MemberProfileData</typeparam> /// <param name="data">ASA.Web.WTF.MemberProfileData</param> /// <returns>true=success; false=failure or type mismatch</returns> Boolean IUpdateable.SetValues <TModel>(TModel data) { String logMethodName = ".SetValues<TModel>(TModel data) - "; _log.Debug(logMethodName + "Begin Method"); Boolean result = false; if (data is MemberProfileData) { MemberProfileData profileData = data as MemberProfileData; if (profileData != null) { result = SetValues <MemberProfileData>(profileData); } else { result = false; } } else { _log.Warn(logMethodName + "Only MemberProfileData objects are supported currently"); throw new WtfException("Only MemberProfileData objects are supported currently"); } _log.Debug(logMethodName + "End Method"); return(result); }
/// <summary> /// Save any changes to the profile. /// /// Profile default validation requires the user to own the record being created/updated and requires them to be logged in. /// </summary> /// <returns>true=success; false=failure</returns> public bool Save() { String logMethodName = ".Save() - "; _log.Debug(logMethodName + "Begin Method"); if (_isAnonymous) { _log.Warn(logMethodName + "Cannot save the information of an anonymous user"); throw new WtfException("Cannot save the information of an anonymous user"); } // Stage 1: Hard coded validators <-- You are here // Stage 2: Load Validators from Config <-- FUTURE // Stage 3: Internal Validator Configuration Support <-- FUTURE Boolean validated = false; _log.Debug(logMethodName + "Loading save data validators"); try { //First load validators List <IContextActionValidationRequest <IContextActionValidator> > validationRequests = new List <IContextActionValidationRequest <IContextActionValidator> >(); // Two rulesets right now for saving: // 1. new user accounts with no profiles get one created (this is mainly for testing and will be disabled or not // exposed in prod will be supported in prod at some point post decemeber launch as needed) // // 2. User can save only own records. Internalizes a common type of fine grained security check validationRequests.Add((IContextActionValidationRequest <IContextActionValidator>) new ContextActionValidationRequest <MustbeLoggedInValidator>()); if (!_newProfile) { validationRequests.Add((IContextActionValidationRequest <IContextActionValidator>) new ContextActionValidationRequest <ManageOwnRecordsValidator>(_orignalProfileData, _profileData)); } //NOTE For now ALL validators must return true for a successful save _log.Debug(logMethodName + "Validating save data request"); foreach (IContextActionValidationRequest <IContextActionValidator> request in validationRequests) { if (!request.Process()) { validated = false; break; } validated = true; } } catch (Exception ex) { throw new WtfException("Profile save request validation failure. Data save aborted.", ex); } if (validated) { _log.Debug(logMethodName + "Save request validated successfully, saving changes"); _profileData.LastModified = DateTime.Now; _profileData.LastModifiedBy = _memberId; #region Save Data Logic //update already exsiting member profile try { _log.Debug(logMethodName + "Calling IContextDataProvider.UpdateMemberProfile(_profileData, _profileData.ProviderKeys) - Attempting to save the member profile data"); _profileData = new MemberProfileData(_provider.UpdateMemberProfile(_profileData, _profileData.ProviderKeys)); } catch (Exception ex) { _log.Error(logMethodName + "Error occured while attempting to save the profile.", ex); throw new WtfException("Error occured while attempting to save the profile.", ex); } #endregion //After a successful save or update take the current profile data and copy it to the back-up //data variable. _orignalProfileData = _profileData; _isDirty = false; _log.Debug(logMethodName + "Save request was successful!"); _log.Debug(logMethodName + "End Method"); return(true); } else { _log.Debug(logMethodName + "Save request did not validate successfully, skipping save"); } _log.Debug(logMethodName + "End Method"); return(false); }
/// <summary> /// Handles lazy loading of profile data. Note that current implmentation loads ALL data for the profile /// when this method is called. /// </summary> private void LoadProfileData() { String logMethodName = ".LoadProfileData() - "; _log.Debug(logMethodName + "Begin Method"); if (!_profileDataLoaded) { _log.Debug(logMethodName + "Loading Member Profile Data"); IMemberProfileData profileData = null; try { _log.Debug(logMethodName + "Calling IContextDataProvider.GetMemberProfile(Object membershipId, Dictionary<String, Object> providerKeys)"); _log.Debug(string.Format("_memberId = {0}", _memberId != null ? _memberId : "NULL")); //COV-10330 check for NULL if (_memberId != null) { profileData = _provider.GetMemberProfile(_memberId); } } catch (Exception ex) { String message = logMethodName + "Error getting profile data"; _log.Error(message, ex); throw new WtfException(message, ex); } //If the profile is null it means one does not exsist for this user yet. if (profileData != null) { _profileData = new MemberProfileData(profileData); _newProfile = false; _log.Debug(logMethodName + "Profile Data found and loaded successfully"); } else { //Internally mark that we have a new profile here. Thie allows save to //work properly. _profileData = new MemberProfileData(); _newProfile = true; _log.Debug(logMethodName + "No profile data found for user, creating empty profile record"); } //_profileData.MemberId = _memberId; //_profileData.MemberId is the memberId in the SALTDb lets leave it alone _profileData.Id = _memberId; _orignalProfileData = _profileData; //We still set the profile loaded to true because it is in fact loaded. //Also this keeps us from hitting the provider over and over as the properties //are accessed. _profileDataLoaded = true; } else { _log.Debug(logMethodName + "Member profile data has already been loaded, skipping"); } _log.Debug(string.Format("About to set WTFSession.ProfileId = {0}", _profileData.Id != null?_profileData.Id:"NULL")); WTFSession.ProfileId = _profileData.Id; _log.Debug(logMethodName + "End Method"); }
public SiteMember CreateMember(MemberAuthInfo authInfo, MemberProfileData profile, out MemberCreationStatus status, IList <IContextActionValidationRequest <IContextActionValidator> > validationRequests = null) { const string logMethodName = ".CreateMember(MemberAuthInfo, MemberProfileData, out MemberCreationStatus, IList<IContextActionValidationRequest<IContextActionValidator>>)"; const string logEndMessage = logMethodName + " - End Method"; _log.Info(logMethodName + " - Creating new SiteMember"); _log.Debug(logMethodName + " - Begin Method"); SiteMember newMember = null; status = MemberCreationStatus.Error; IMemberAccountData accountData = null; int timesToTry = 2; //SWD-7461 - adding retry logic. for (int i = 0; i < timesToTry; i++) { try { _log.Debug(logMethodName + " - Calling ISecurityAdapter.CreateMember(MemberAuthInfo authInfo, MemberProfileData data, out MemberCreationStatus status)"); status = MemberCreationStatus.Error; accountData = _adapter.CreateMember(authInfo, profile, out status); break; } catch (Exception ex) { _log.Error(logMethodName + " - Error Creating new member account using the ISecurityAdapter.CreateMember will retry again", ex); System.Threading.Thread.Sleep(1000); accountData = null; } } if (status == MemberCreationStatus.Success) { _log.Info(logMethodName + " - MemberAccount created successfully by ISecurityAdapter.CreateMember - Creating MemberProfile"); var memberProfile = new MemberProfileData(profile) { MemberId = accountData.MemberId, LastModified = DateTime.Now, LastModifiedBy = accountData.MemberId }; if (memberProfile.ProviderKeys == null) { memberProfile.ProviderKeys = new Dictionary <string, object>(); } memberProfile.ProviderKeys.Add("ActiveDirectoryKey", accountData.MemberId); // We prob dont need this, code using the ADKey lower in the framework will be ignored try { IMemberProfileData data; _log.Debug(logMethodName + " - Calling IContextDataProvider.CreateMemberProfile(MemberProfileData data, ProviderKeys keys)"); //TODO verify and remove provider key integration at this layer. - May need pin based lookup for pre-registered accounts to call update. data = _provider.CreateMemberProfile(memberProfile, memberProfile.ProviderKeys); memberProfile = new MemberProfileData(data); } catch (Exception ex) { _log.Error(logMethodName + " - Error Creating new member profile using the IContextDataProvider - Rolling back new account", ex); _log.Info(logMethodName + " - Rolling back - STEP 1. DELETE MEMBER ACCOUNT"); _log.Debug(logMethodName + " - Calling ISecurityAdapter.DeleteMember(Object memberId)"); _adapter.DeleteMember(accountData.Username); status = MemberCreationStatus.AdapterError; _log.Debug(logEndMessage); accountData = null; } try { newMember = new SiteMember(accountData, memberProfile); } catch (Exception ex) { _log.Error(logMethodName + " - Error Creating new sitemember instance", ex); _log.Debug(logEndMessage); newMember = null; } } else { // SWD-5616 _log.Warn(logMethodName + " - Member Creation Unsuccessful. Status: " + status); } _log.Debug(logEndMessage); return(newMember); }
public SiteMember CreateMember(MemberAuthInfo authInfo, MemberProfileData profile, out MemberCreationStatus status, System.Collections.Generic.IList <IContextActionValidationRequest <IContextActionValidator> > validationRequests = null) { status = MemberCreationStatusResponse; return(CreateMemberResponse); }