/// <summary> /// Registration over any channel defined in module. Credential concept is implicated too. /// </summary> /// <param name="obj">Request object</param> /// <returns>ID user if it's ok or null when it's error</returns> public ActionResponse RegisterAction(RegisterRequest obj) { ActionResponse output = new ActionResponse(); try { // OPERATOR registration bool asOperatorRegistration = false; if (obj.code != null) { asOperatorRegistration = true; } // Code doesn't exist, will enter by normal registration flow int idProduct = obj.idProduct.Value; int idChannel = obj.idChannel.Value; string passReq = null; if (!String.IsNullOrEmpty(obj.password)) { passReq = obj.password.Trim(); } // STEP 0: Need to verify if product and channel exist or not ProductData prodData = new ProductData(); Product oProduct = prodData.GetProductById(idProduct); if (oProduct == null) { return(functions.Response((int)CodeStatusEnum.NO_CONTENT, "El producto no existe en el sistema", null)); } ChannelData channelData = new ChannelData(); Channel oChannel = channelData.GetChannelById(idChannel); if (oChannel == null) { return(functions.Response((int)CodeStatusEnum.NO_CONTENT, "El canal no existe en el sistema", null)); } // We need to check if code is setted // If code exists, will check for this first (custody) CustodyController custodyController = new CustodyController(); Custody oCustody = new Custody(); if (asOperatorRegistration) { // Find Custody object linked to code received oCustody = custodyController.FindCustodyByCode(idProduct, obj.code, obj.codeType.ToLower()); if (oCustody == null) { return(functions.Response((int)CodeStatusEnum.NO_CONTENT, "No hay ninguna custodia vinculada al código proporcionado", null)); } } // Normal flow for registration. Distinct to get code or not, it will do same actions // Firstly, will check consistency value in function of channel switch (obj.idChannel.Value) { case (int)ChannelEnum.EMAIL: try { MailAddress m = new MailAddress(obj.value); break; } catch (FormatException) { return(functions.Response((int)CodeStatusEnum.BAD_REQUEST, "El formato del email es incorrecto", null)); } case (int)ChannelEnum.ANI: int l = 11; string prefix = "569"; bool error = true; string val = obj.value; // Check for prefix (569) considerating solution for Chile (need to be dynamic as soon as possible) if (val.Contains(prefix)) { // Check for length (11) adding prefix if (val.Length == l) { error = false; } } if (error) { return(functions.Response((int)CodeStatusEnum.BAD_REQUEST, "El formato del ani es incorrecto", null)); } break; case (int)ChannelEnum.FACEBOOK: // Will check if ID is a numeric number break; } // STEP 1: Check if user identify already exists // If UserIdentify doesn't exist, it won't check credential because of it doesn't exist too obviously // If UserIdentify exists, we need to check for credentials vinculated. UserIdentifyData uiData = new UserIdentifyData(); UserIdentify ui = uiData.FindByIdChannelAndValue(idChannel, obj.value); string passMD5 = null; if (ui.id_cliente != null) { // STEP 2: Check if credential already exists CredentialData cdData = new CredentialData(); List <Credential> lstCredential = cdData.FindByProductAndUserIdentify(idProduct, ui.idUserIdentify.Value); if (lstCredential.Count > 0) { return(functions.Response((int)CodeStatusEnum.CONFLICT, "La credencial del usuario ya existe en el sistema", null)); } } // If entire data is ok, try to create user // Will return ID user or null (transaction) ClienteData u = new ClienteData(); // string ani, string email, string usuario, decimal id_operador int?res = 0; // Create a random value for ani, it must to be fixed to correct logic with registration operator (custody) int max = Int32.Parse(functions.ConfigItem("MAX_RANDOM_ANI_USER")); string rndString = "user_" + functions.GetUniqueKey(max); // If password is setted, it becomes as MD5 if (!String.IsNullOrEmpty(passReq)) { // Will check password integrity int minLengthPass = Int32.Parse(functions.ConfigItem("MIN_PASS_LENGTH")); if (passReq.Length < minLengthPass) { return(functions.Response((int)CodeStatusEnum.BAD_REQUEST, "La contraseña debe tener un mínimo de " + minLengthPass + " caracteres", null)); } using (MD5 md5Hash = MD5.Create()) { passMD5 = functions.GetMd5Hash(md5Hash, passReq); } } else { // Without password passMD5 = passReq; } // Will create user, receiving UserIdentify or making it within other actions if (ui.idUserIdentify == null) { // Operator registration always won´t have UserIdentify associated (will be created later) // UserIdentify unknown res = u.CreateUser(idChannel, idProduct, obj.value, passMD5, 0, rndString, "", "", 0, false, 0, obj.idGuide.Value); } else { // UserIdentify already known res = u.CreateUser(idChannel, idProduct, obj.value, passMD5, 0, rndString, "", "", 0, true, ui.idUserIdentify.Value, obj.idGuide.Value); } // Sp's response if (res == null) { return(functions.Response((int)CodeStatusEnum.CONFLICT, "No se pudo registrar al usuario en la plataforma", res)); } // OK (will return ID cliente generated -last insert-) RegisterResponse response = new RegisterResponse(); response.idClient = (decimal)res; // Normal or custody registration if (asOperatorRegistration) { // Reserved value into response response.reservedValue = oCustody.value; // Try to close custody int idCustody = oCustody.idCustody.Value; int idClient = (int)oCustody.id_cliente.Value; // Need to close Custody, it will be the end of this process // Will check custody is valid or not ActionResponse resX = custodyController.CloseCustodyByIdAction(idCustody); if (resX.code != (int)CodeStatusEnum.OK) { logger.Error(resX.message); } } return(functions.Response((int)CodeStatusEnum.OK, "OK", response)); } catch (Exception e) { logger.Fatal(e.Message); return(functions.Response((int)CodeStatusEnum.INTERNAL_ERROR, e.Message, null)); } }