/// <summary> /// Compares a recived open password with a stored to an user. /// </summary> /// <param name="recivedPassword"> /// A password received by a server in open format. /// Will hashed in compared with a stored one. /// </param> /// <returns>A result of comparison.</returns> public bool IsOpenPasswordCorrect(string recivedPassword) { // Gets a hashed password from recived one. byte[] recivedHashedPassword = SaltContainer.GetHashedPassword(recivedPassword, Config.Active.Salt); // Compares. return(IsHashedPasswordCorrect(recivedHashedPassword)); }
public void SetTokenRights() { if (!SetDefaults(out string error)) { Assert.Fail(error); return; } #region Users genration User moderatedUser = new User { id = 213455, login = "******", password = SaltContainer.GetHashedPassword("pass", Config.Active.Salt), firstName = "mu", rights = new string[] { "rank=2", "1", "2" } }; moderatedUser.tokens.Add(Tokens.UnusedToken); User adminUser = new User { id = 213456, login = "******", password = SaltContainer.GetHashedPassword("pass", Config.Active.Salt), firstName = "admFRT", rights = new string[] { "rank=8", "banhammer" } }; adminUser.tokens.Add(Tokens.UnusedToken); #endregion #region Sending the data to server. // Create a user for moderation. if (!UniformDataOperator.Sql.SqlOperatorHandler.Active.SetToTable(typeof(User), moderatedUser, out error)) { Assert.Fail(error); return; } // Create admin user. if (!UniformDataOperator.Sql.SqlOperatorHandler.Active.SetToTable(typeof(User), adminUser, out error)) { Assert.Fail(error); return; } #endregion #region Providing tokens AuthorityController.Session.Current.AssignTokenToUser (moderatedUser, moderatedUser.tokens[0]); AuthorityController.Session.Current.AssignTokenToUser (adminUser, adminUser.tokens[0]); #endregion #region SetToken rights AuthorityController.Session.Current.SetTokenRights (moderatedUser.tokens[0], moderatedUser.rights); AuthorityController.Session.Current.SetTokenRights (adminUser.tokens[0], adminUser.rights); #endregion // Building the query. var query = new Query( new QueryPart("set"), new QueryPart("targetToken", moderatedUser.tokens[0]), new QueryPart("rights", "rank=4+a+b+c"), new QueryPart("set"), new QueryPart("token", adminUser.tokens[0]), new QueryPart("guid", "tokenRightsUpdateTest")); // Marker that avoid finishing of the test until receiving result. bool operationCompete = false; bool operationResult = false; string internalError = null; // Start reciving clent line. UniformClient.BaseClient.EnqueueDuplexQueryViaPP( // Request connection to localhost server via main pipe. "localhost", Helpers.Networking.DefaultQueriesPipeName, query, // Handler that would recive ther ver answer. (PipesProvider.Client.TransmissionLine line, Query answer) => { if (answer.First.PropertyValueString.StartsWith("error", StringComparison.OrdinalIgnoreCase)) { internalError = query.First.PropertyValueString; operationResult = false; } else { operationResult = true; } operationCompete = true; }); // Wait until operation would complete. while (!operationCompete) { Thread.Sleep(5); } Assert.IsTrue(operationResult, internalError); }
/// <summary> /// Methods that process query. /// </summary> /// <param name="serverTL">Operator that call that operation</param> /// <param name="query">Recived query.</param> public virtual void Execute(object serverTL, Query query) { // Marker that would be mean that some of internal tasks was failed and operation require termination. bool failed = false; #region Get query params query.TryGetParamValue("login", out QueryPart login); query.TryGetParamValue("password", out QueryPart password); query.TryGetParamValue("fn", out QueryPart firstName); query.TryGetParamValue("ln", out QueryPart lastName); query.TryGetParamValue("token", out QueryPart token); query.TryGetParamValue("guid", out QueryPart guid); query.TryGetParamValue("os", out QueryPart os); query.TryGetParamValue("mac", out QueryPart mac); query.TryGetParamValue("stamp", out QueryPart timeStamp); System.Threading.Thread.Sleep(5); #endregion #region Validate login if (string.IsNullOrEmpty(login.PropertyValueString) || login.propertyValue.Length < Config.Active.LoginMinSize || login.propertyValue.Length > Config.Active.LoginMaxSize) { // Inform about incorrect login size. UniformServer.BaseServer.SendAnswerViaPP( "ERROR 401: Invalid login size. Require " + Config.Active.LoginMinSize + "-" + Config.Active.LoginMaxSize + " caracters.", query); return; } // Check login format. if (!Regex.IsMatch(login.PropertyValueString, @"^[a-zA-Z0-9@._]+$")) { // Inform about incorrect login size. UniformServer.BaseServer.SendAnswerViaPP( "ERROR 401: Invalid login format. Allowed symbols: [a-z][A-Z][0-9]@._", query); return; } // Can take enough long time so just let other query to process. System.Threading.Thread.Sleep(5); #endregion #region Validate password if (!API.Validation.PasswordFormat(password.PropertyValueString, out string errorMessage)) { // Inform about incorrect login size. UniformServer.BaseServer.SendAnswerViaPP( errorMessage, query); return; } // Can take enough long time so just let other query to process. Thread.Sleep(5); #endregion #region Validate names string firstNameString = firstName.PropertyValueString; string lastNameString = lastName.PropertyValueString; // Validate name. if (!API.Validation.NameFormat(ref firstNameString, out string error) || !API.Validation.NameFormat(ref lastNameString, out error)) { // Inform about incorrect login size. UniformServer.BaseServer.SendAnswerViaPP( error, query); return; } // Can take enough long time so just let other query to process. System.Threading.Thread.Sleep(5); #endregion // There you can apply some filter of rood words. //----------------------------------------------- #region Create user profile data. // Create base data. User userProfile = (User)Activator.CreateInstance(OperatingType); userProfile.login = login.PropertyValueString; userProfile.password = SaltContainer.GetHashedPassword(password.PropertyValueString, Config.Active.Salt); userProfile.firstName = firstName.PropertyValueString; userProfile.lastName = lastName.PropertyValueString; // Set rights default rights. userProfile.rights = Config.Active.UserDefaultRights; #endregion #region Data storing // Store in SQL data base if provided. if (UniformDataOperator.Sql.SqlOperatorHandler.Active != null) { #region SQL server // Start new task for providing possibility to terminate all operation by // session's cancelation token. // In other case after termination on any internal task other will started. Task.Run(delegate() { // Set ignorable value to activate autoincrement. userProfile.id = 0; #region Check existing // Virtual user profile that would be used to build the query for exist xhecking. User dbStoredProfile = (User)Activator.CreateInstance(OperatingType); // Set login to using in WHERE sql block. dbStoredProfile.login = login.PropertyValueString; // Mearker that would contains result of operation. bool userNotExist = false; // Task that would start async waiting for server's answer. Task existingCheckTask = new Task(async delegate() { // Callback that would be called if data not found. // If not called then data already exist and operation failed. void DataNotFound(object sender, string _) { // Drop if not target user. if (!dbStoredProfile.Equals(sender)) { return; } // Unsubscribe. UniformDataOperator.Sql.SqlOperatorHandler.SqlErrorOccured -= DataNotFound; // Enable marker. userNotExist = true; } // Subscribe on errors. UniformDataOperator.Sql.SqlOperatorHandler.SqlErrorOccured += DataNotFound; // Set data ro data base. await UniformDataOperator.Sql.SqlOperatorHandler.Active. SetToObjectAsync( OperatingType, Session.Current.TerminationTokenSource.Token, dbStoredProfile, new string[0], new string[] { "login" }); // Unsubscribe the errors listener. UniformDataOperator.Sql.SqlOperatorHandler.SqlErrorOccured -= DataNotFound; }, Session.Current.TerminationTokenSource.Token); existingCheckTask.Start(); // Start async task. // Whait untol result. while (!existingCheckTask.IsCanceled && !existingCheckTask.IsCompleted) { Thread.Sleep(5); } // Drop if user exist if (!userNotExist) { // Inform that user already exist. UniformServer.BaseServer.SendAnswerViaPP( "ERROR: User with login `" + userProfile.login + "` already exist.", query); return; } #endregion #region Create new user // Request creating of new user. Task registrationTask = new Task( async delegate() { // Subscribe on errors. UniformDataOperator.Sql.SqlOperatorHandler.SqlErrorOccured += SQLErrorListener; // Set data ro data base. await UniformDataOperator.Sql.SqlOperatorHandler.Active. SetToTableAsync(OperatingType, Session.Current.TerminationTokenSource.Token, userProfile); // If operation nit failed. if (!failed) { // Request logon. Logon(); // Unsubscribe from errors listening. UniformDataOperator.Sql.SqlOperatorHandler.SqlErrorOccured -= SQLErrorListener; } }, Session.Current.TerminationTokenSource.Token); registrationTask.Start(); }, Session.Current.TerminationTokenSource.Token); #endregion #endregion } // Store in local file system. else { #region Local storage // Check login exist. if (API.LocalUsers.TryToFindUser(login.PropertyValueString, out User _)) { // Inform that target user has the same or heigher rank then requester. UniformServer.BaseServer.SendAnswerViaPP("ERROR 401: Login occupied", query); return; } // Provide ID. userProfile.id = API.LocalUsers.GenerateID(userProfile); // Save profile in storage. API.LocalUsers.SetProfileAsync(userProfile, Config.Active.UsersStorageDirectory); API.LocalUsers.UserProfileStored += LocalDataStoredCallback; API.LocalUsers.UserProfileNotStored += LocalDataStroringFailed; #endregion } #endregion #region Local callbacks // Callback that would be processed in case of success of data storing. void LocalDataStoredCallback(User target) { // Check is that user is a target of this request. if (target.id == userProfile.id) { // Unsubscribe. API.LocalUsers.UserProfileStored -= LocalDataStoredCallback; API.LocalUsers.UserProfileNotStored -= LocalDataStroringFailed; Logon(); } } // Callback that would be processed in case of fail of data storing. void LocalDataStroringFailed(User target, string operationError) { if (target.id == userProfile.id) { // Unsubscribe. API.LocalUsers.UserProfileStored -= LocalDataStoredCallback; API.LocalUsers.UserProfileNotStored -= LocalDataStroringFailed; // Send answer with operation's error. UniformServer.BaseServer.SendAnswerViaPP( "failed:" + operationError, query); } } #endregion #region SQL server callbacks // Looking for user on SQL server if connected. void SQLErrorListener(object sender, string message) { // Drop if not target user. if (!userProfile.Equals(sender)) { return; } failed = true; // Unsubscribe. UniformDataOperator.Sql.SqlOperatorHandler.SqlErrorOccured -= SQLErrorListener; // Inform that user not found. UniformServer.BaseServer.SendAnswerViaPP("ERROR SQL SERVER: " + message, query); } #endregion #region Local methods // Request logon with current input data. void Logon() { // Build logon query. Query logonQuery = new Query( new QueryPart("USER"), new QueryPart("LOGON"), token, guid, login, password, os, mac, timeStamp ); // Create logon subquery. foreach (IQueryHandler processor in UniformQueries.API.QueryHandlers) { // Fini logon query processor. if (processor is USER_LOGON) { // Execute and send to client token valided to created user. processor.Execute(serverTL, logonQuery); return; } } } #endregion }
/// <summary> /// Methods that process query. /// </summary> /// <param name="serverTL">Operator that call that operation</param> /// <param name="query">Recived query.</param> public virtual void Execute(object serverTL, Query query) { // Init defaults. Task asyncDataOperator = null; bool dataOperationFailed = false; #region Get params. query.TryGetParamValue("password", out QueryPart password); query.TryGetParamValue("oldPassword", out QueryPart oldPassword); #endregion // Validate user rights to prevent not restricted acess passing. if (!Handler.ValidateUserRights( OperatingType, query, Config.Active.QUERY_UserNewPassword_RIGHTS, out string error, out User userProfile, out Data.Temporal.TokenInfo tokenInfo)) { // Drop if invalid. return; } #region Validate old password. if (tokenInfo.userId == 0 || tokenInfo.userId == userProfile.id) { try { // Comapre password with stored. if (!userProfile.IsOpenPasswordCorrect(oldPassword.PropertyValueString)) { // Inform that password is incorrect. UniformServer.BaseServer.SendAnswerViaPP("ERROR 412: Incorrect password", query); return; } } catch { // Inform that password is incorrect. UniformServer.BaseServer.SendAnswerViaPP("ERROR 412: Confirm old password", query); return; } } #endregion #region Validate new password if (!API.Validation.PasswordFormat(password.PropertyValueString, out string errorMessage)) { // Inform about incorrect login size. UniformServer.BaseServer.SendAnswerViaPP( errorMessage, query); return; } #endregion // Update password. userProfile.password = SaltContainer.GetHashedPassword(password.PropertyValueString, Config.Active.Salt); // Update stored profile. if (UniformDataOperator.Sql.SqlOperatorHandler.Active != null) { // Subscribe on errors. UniformDataOperator.Sql.SqlOperatorHandler.SqlErrorOccured += ErrorListener; // Update on SQL server. asyncDataOperator = UniformDataOperator.Sql.SqlOperatorHandler.Active.SetToTableAsync( OperatingType, Session.Current.TerminationTokenSource.Token, userProfile); } else { // Ipdate in local storage. API.LocalUsers.SetProfile(userProfile); } // If async operation started. if (asyncDataOperator != null) { // Wait until finishing. while (!asyncDataOperator.IsCompleted && !asyncDataOperator.IsCanceled) { Thread.Sleep(5); } // Unsubscribe from errors listening. UniformDataOperator.Sql.SqlOperatorHandler.SqlErrorOccured -= ErrorListener; asyncDataOperator = null; } // Log sucess if not failed. if (!dataOperationFailed) { // Inform about success UniformServer.BaseServer.SendAnswerViaPP( "success", query); } #region SQL server callbacks // Looking for user on SQL server if connected. void ErrorListener(object sender, string message) { // Drop if not target user. if (!userProfile.Equals(sender)) { return; } // Unsubscribe. UniformDataOperator.Sql.SqlOperatorHandler.SqlErrorOccured -= ErrorListener; // Inform that user not found. UniformServer.BaseServer.SendAnswerViaPP("ERROR SQL SERVER: " + message, query); dataOperationFailed = true; } #endregion }
/// <summary> /// Creating and apply base users pool: /// -Super admin /// -Admin /// -Moderator /// -Privileged user /// -User /// -Guest /// </summary> public static void SetBaseUsersPool() { lock (Locks.CONFIG_LOCK) { // Set new test directory to avoid conflicts with users profiles. Config.Active.UsersStorageDirectory = "Tests\\Queries\\Users\\" + Guid.NewGuid().ToString() + "\\"; // Clear current user pool. AC_API.LocalUsers.ClearUsersLoadedData(); #region Create superadmin user_SuperAdmin = new User() { id = 1, login = "******", password = SaltContainer.GetHashedPassword("password", Config.Active.Salt), tokens = new System.Collections.Generic.List <string> (new string[] { UniformQueries.Tokens.UnusedToken }), rights = new string[] { "rank=16", "banhammer", "passwordManaging" } }; // Generate ID. user_SuperAdmin.id = AC_API.LocalUsers.GenerateID(user_SuperAdmin); // Save profile. AC_API.LocalUsers.SetProfileAsync(user_SuperAdmin, Config.Active.UsersStorageDirectory); #endregion #region Create admin user_Admin = new User() { login = "******", password = SaltContainer.GetHashedPassword("password", Config.Active.Salt), tokens = new System.Collections.Generic.List <string> (new string[] { UniformQueries.Tokens.UnusedToken }), rights = new string[] { "rank=8", "banhammer", "passwordManaging" } }; // Generate ID. user_Admin.id = AC_API.LocalUsers.GenerateID(user_Admin); // Save profile. AC_API.LocalUsers.SetProfileAsync(user_Admin, Config.Active.UsersStorageDirectory); #endregion #region Create moderator user_Moderator = new User() { login = "******", password = SaltContainer.GetHashedPassword("password", Config.Active.Salt), tokens = new System.Collections.Generic.List <string> (new string[] { UniformQueries.Tokens.UnusedToken }), rights = new string[] { "rank=4", "banhammer", "passwordManaging" } }; // Generate ID. user_Moderator.id = AC_API.LocalUsers.GenerateID(user_Moderator); // Save profile. AC_API.LocalUsers.SetProfileAsync(user_Moderator, Config.Active.UsersStorageDirectory); #endregion #region Create privileged user user_PrivilegedUser = new User() { login = "******", password = SaltContainer.GetHashedPassword("password", Config.Active.Salt), tokens = new System.Collections.Generic.List <string> (new string[] { UniformQueries.Tokens.UnusedToken }), rights = new string[] { "rank=2", "passwordManaging" } }; // Generate ID. user_PrivilegedUser.id = AC_API.LocalUsers.GenerateID(user_PrivilegedUser); // Save profile. AC_API.LocalUsers.SetProfileAsync(user_PrivilegedUser, Config.Active.UsersStorageDirectory); #endregion #region Create user user_User = new User() { login = "******", password = SaltContainer.GetHashedPassword("password", Config.Active.Salt), tokens = new System.Collections.Generic.List <string> (new string[] { UniformQueries.Tokens.UnusedToken }), rights = new string[] { "rank=1", "passwordManaging" } }; // Generate ID. user_User.id = AC_API.LocalUsers.GenerateID(user_User); // Save profile. AC_API.LocalUsers.SetProfileAsync(user_User, Config.Active.UsersStorageDirectory); #endregion #region Create guest user_Guest = new User() { login = "******", password = SaltContainer.GetHashedPassword("password", Config.Active.Salt), tokens = new System.Collections.Generic.List <string> (new string[] { UniformQueries.Tokens.UnusedToken }), rights = new string[] { "rank=0" } }; // Generate ID. user_Guest.id = AC_API.LocalUsers.GenerateID(user_Guest); // Save profile. AC_API.LocalUsers.SetProfileAsync(user_Guest, Config.Active.UsersStorageDirectory); #endregion // Wait until loading. do { Thread.Sleep(5); }while (AC_API.LocalUsers.HasAsyncLoadings); #region Authorize tokens // Super admin AuthorityController.Session.Current.AssignTokenToUser(user_SuperAdmin, user_SuperAdmin.tokens[0]); AuthorityController.Session.Current.SetTokenRights(user_SuperAdmin.tokens[0], user_SuperAdmin.rights); // Admin AuthorityController.Session.Current.AssignTokenToUser(user_Admin, user_Admin.tokens[0]); AuthorityController.Session.Current.SetTokenRights(user_Admin.tokens[0], user_Admin.rights); // Moderator AuthorityController.Session.Current.AssignTokenToUser(user_Moderator, user_Moderator.tokens[0]); AuthorityController.Session.Current.SetTokenRights(user_Moderator.tokens[0], user_Moderator.rights); // Privileged user AuthorityController.Session.Current.AssignTokenToUser(user_PrivilegedUser, user_PrivilegedUser.tokens[0]); AuthorityController.Session.Current.SetTokenRights(user_PrivilegedUser.tokens[0], user_PrivilegedUser.rights); // User AuthorityController.Session.Current.AssignTokenToUser(user_User, user_User.tokens[0]); AuthorityController.Session.Current.SetTokenRights(user_User.tokens[0], user_User.rights); // Guest AuthorityController.Session.Current.AssignTokenToUser(user_Guest, user_Guest.tokens[0]); AuthorityController.Session.Current.SetTokenRights(user_Guest.tokens[0], user_Guest.rights); #endregion } }