using Knoks.Api.Controllers.Base; using Knoks.Api.Entities; using Knoks.Api.Filters; using Knoks.Core.Entities; using Knoks.Core.Entities.Args; using Knoks.Core.Logic.Interfaces; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Net; using HtmlAgilityPack; using Newtonsoft.Json.Linq; using Newtonsoft.Json; using System.Text.RegularExpressions; using Knoks.Framework.Cryptography; using Knoks.Framework.Security; namespace Knoks.Api.Controllers { [Route("v1/[controller]")] public class GeneralController : ApiConsumerController { #region Fields private readonly ILogger _logger; private readonly IGeneralManager _generalManager; private readonly IUserManager _userManager; private readonly IExchangeManager _exchangeManager; private readonly IOperatorManager _operatorManager; #endregion /// /// ctor /// /// /// /// /// /// /// public GeneralController( ILogger logger, IGeneralManager generalManager, IUserManager userManager, IOperatorManager operatorManager, IExchangeManager exchangeManager, ISystemConfigurationManager systemConfigurationManager) { _logger = logger; _generalManager = generalManager; _userManager = userManager; _exchangeManager = exchangeManager; _operatorManager = operatorManager; } [HttpPut("User")] public async Task UpdateUser([FromBody]UpdateUserArgs args) { if (!await _userManager.UserNameExists(args.UserName, this.ContextUserId)) { if (!string.IsNullOrEmpty(args.UserName)) { var name = args.UserName.Split(' '); if (name.Count() > 1) { args.FirstName = name[0].TrimStart().TrimEnd(); args.LastName = args.UserName.Substring(name[0].Length).TrimStart().TrimEnd(); } else { args.FirstName = args.UserName; args.LastName = string.Empty; } } return await _userManager.UpdateUser(args); } throw new ApiResponseException(ApiErrorType.UserNameAlreadyExists, $"User with \"{args.UserName}\" username already exists."); } [HttpPost("NewUser")] [UserForbid] public async Task RegisterUser([FromBody]CreateUserArgs args, [FromServices] IPasswordStrength _passwordStrength) { //args.Source = "web"; //args.CreateOrigin = "0"; args.UserTypeId = 1; // Demo if (await _passwordStrength.CheckStrength(args.Password) < PasswordScore.Medium) { throw new ApiResponseException(ApiErrorType.PasswordIsNotStrong, "Password is not enough strong."); } if (await _userManager.UserExists(args.UserName)) { throw new ApiResponseException(ApiErrorType.UserNameAlreadyExists, $"User with \"{args.UserName}\" username already exists."); } if (await _userManager.UserEmailExists(args.Email)) { throw new ApiResponseException(ApiErrorType.UserEmailAlreadyExists, $"User with \"{args.Email}\" email already exists."); } return await _userManager.CreateUser(args); } [HttpPost("ParseUrl")] public async Task ParseUrl([FromBody]ReferenceUrlArgs args) { return await Task.Run(() => { var meta = new SiteMeta(); string xmlStr; using (var wc = new WebClient()) { Regex RgxUrl = new Regex("(([a-zA-Z][0-9a-zA-Z+\\-\\.]*:)?/{0,2}[0-9a-zA-Z;/?:@&=+$\\.\\-_!~*'()%]+)?(#[0-9a-zA-Z;/?:@&=+$\\.\\-_!~*'()%]+)?"); if (args.Url != null && RgxUrl.IsMatch(args.Url)) { try { wc.Headers.Add("User-Agent: Other"); xmlStr = wc.DownloadString(args.Url); } catch(Exception ex) { _logger.LogError(ex, ex.Message); return null; } } else return null; } var doc = new HtmlDocument(); try { doc.LoadHtml(xmlStr); } catch (Exception) { return null; } if (doc != null) { var titleelement = doc.DocumentNode.SelectNodes("//meta[@property='og:title']"); if (titleelement != null) { if (titleelement.Count > 0) { var title = titleelement.First().Attributes["content"].Value; meta.Header = title; } } var descelement = doc.DocumentNode.SelectNodes("//meta[@property='og:description']"); if (descelement != null) { if (titleelement.Count > 0) { var desc = descelement.First().Attributes["content"].Value; meta.Description = desc; } } var urllelement = doc.DocumentNode.SelectNodes("//meta[@property='og:url']"); if (urllelement != null) { if (urllelement.Count > 0) { var urll = urllelement.First().Attributes["content"].Value; meta.Url = urll; } } var imageelement = doc.DocumentNode.SelectNodes("//meta[@property='og:image']"); if (imageelement != null) { if (imageelement.Count > 0) { var image = imageelement.First().Attributes["content"].Value; meta.Image = image; } } } try { var jsonString = doc.DocumentNode.SelectNodes("//script[@type='application/ld+json']").First().InnerHtml; JObject json = JObject.Parse(jsonString); var t = json.SelectToken("datePublished").ToString(); meta.Published = Convert.ToDateTime(t); var name = json.SelectToken("publisher").SelectToken("name").ToString(); meta.PublishedBy = name; } catch { return meta; } return meta; }); } [HttpGet("Countries")] public Task> GetCountries() { return GetCountries(null); } [HttpGet("UserRankCount")] public async Task> GetUserRanksCount() { return ApiArray(await _generalManager.GetUserRankCount(this.ContextUserId)); } [HttpGet("KnoksLossCount")] public async Task> KnoksLossCount() { return ApiArray(await _generalManager.GetKnoksLossCount(this.ContextUserId)); } [HttpGet("Countries/{CountryCode2}")] public async Task> GetCountries([FromRoute]string countryCode2) { return ApiArray(await _generalManager.GetCountries(countryCode2)); } [HttpGet("Languages")] public async Task> GetLanguages() { return ApiArray(await _generalManager.GetLanguages()); } [HttpGet("KnokStatuses")] public async Task> GetKnokStatuses() { return ApiArray(await _generalManager.GetKnokStatuses()); } [HttpGet("KnokStartvalues")] public async Task> GetKnokStartValues([FromQuery]int exchangeId, [FromQuery]string currency1, [FromQuery]string currency2) { return ApiObject(await _exchangeManager.GetTradingPairRate(exchangeId, currency1, currency2)); } [HttpPost("AddOngoingKnokFeedback")] public async Task> AddOngoingKnokFeedback([FromBody]OngoingKnokFeedbackArgs feedback) { await _generalManager.AddKnokFeedBack(new Feedback() { KnokId = feedback.KnokId, UserId = feedback.UserId, FeedbackType = FeedbackType.Ongoing, Comment = feedback.Comment, Clear = feedback.Clear, Educational = feedback.Educational, Comprehensive = feedback.Comprehensive }); return await Task.FromResult(ApiObject(true)); } [HttpPost("AddEndedKnokFeedback")] public async Task> AddEndedKnokFeedback([FromBody]EndedKnokFeedbackArgs feedback) { await _generalManager.AddKnokFeedBack(new Feedback() { KnokId = feedback.KnokId, UserId = feedback.UserId, FeedbackType = FeedbackType.RecentlyEnded, Comment = feedback.Comment, KnokBenefit = feedback.KnokBenefit }); return await Task.FromResult(ApiObject(true)); } [UserForbid, OperatorForbid] [HttpPost("Operator")] public async Task CreateOperator([FromBody]CreateOperatorArgs args) { return await _operatorManager.CreateOperator(args); } [HttpGet("{user}/avatar")] [AllowAnonymous] public FileStreamResult GetAvatar([FromRoute]string user, [FromServices] IUidManager uidManager) { int? userId = uidManager.ToIntValue(user, typeof(User), Constants.avatarCause); if (userId == null) { throw new ArgumentNullException("User was no provided"); } var result = _userManager.GetAvatarFile(userId.Value); if (result.File != null) { result.ContentType = "image/png"; return File(result.File, result.ContentType, result.LastModified, null);// "image/png"); } else { return null; } } [HttpGet("Update")] public async Task> Update([FromServices] IExchangeManager exchangeManager) { await exchangeManager.UpdateExchanges(); return new ApiObject(true); } [HttpGet("FilterCurrencies")] public async Task> GetFilterCurrencies([FromQuery] long? userId, [FromQuery] bool? availableKnoks, [FromQuery] bool? activeKnoks, [FromQuery] bool? endedKnoks) { return new ApiArray(await _generalManager.GetFilterCurrencies(userId, availableKnoks, activeKnoks, endedKnoks)); } [HttpGet("Currencies/{currency?}")] public async Task> GetCurrencies([FromRoute] string currency) { return new ApiArray(await _generalManager.GetCurrencies(currency)); } [HttpGet("Exchanges")] public async Task> GetExchanges([FromServices] IExchangeManager exchangeManager, [FromQuery] long? userId, [FromQuery] bool? availableKnoks, [FromQuery] bool? activeKnoks, [FromQuery] bool? endedKnoks) { return new ApiArray(await _generalManager.GetExchanges(userId, availableKnoks, activeKnoks, endedKnoks)); } [HttpGet("Configs")] public Task> GetConfigs([FromQuery]IList keys, [FromServices]IKnokManager knokManager) { var settings = knokManager.Settings.ToDictionary(it => /*"KnokSettings." +*/ it.Key, it => it.Value); settings.Add("tagOtherMagicValue", "-1"); return Task.FromResult( new ApiDictionary( settings //new Dictionary() { { "KnokSettings.MaximumDuration", knokManager.MaximumDuration.ToString() }//days } )); } [HttpGet("Tags/{isTechnical:int}")] public async Task> GetTags([FromRoute] int isTechnical, [FromServices]Core.Data.Interfaces.ITagDao tagDao) { return new ApiArray((await tagDao.GetTags(isTechnical == 1 ? isTechnical : 2))); } [HttpPost("SendPasswordReset")] [AllowAnonymous] public async Task> SendPasswordReset([FromBody] RetrievePasswordArgs args) { if (await _userManager.UserEmailExists(args.Email)) { await _userManager.SendPasswordResetLink(args.Email, args.Url); return new ApiObject(true); } throw new ApiResponseException(ApiErrorType.UserEmailDoesNotExist, $"User with \"{args.Email}\" email does not exist."); } [HttpPost("CheckPasswordResetToken")] [AllowAnonymous] public async Task> CheckPasswordResetToken([FromBody] CheckTokenArgs args) { if (args == null || string.IsNullOrEmpty(args.Token)) { throw new ApiResponseException(ApiErrorType.UserEmailDoesNotExist, $"Token is incorrect."); } var result = await _userManager.CheckPasswordResetToken(args.Token); if (!result) { throw new ApiResponseException(ApiErrorType.UserEmailDoesNotExist, $"Token is incorrect."); } return new ApiObject(true); } [HttpPost("PasswordReset")] [AllowAnonymous] public async Task> PasswordReset([FromBody] ResetPasswordArgs args, [FromServices] IPasswordStrength _passwordStrength) { if (await _passwordStrength.CheckStrength(args.NewPassword) < PasswordScore.Medium) { throw new ApiResponseException(ApiErrorType.PasswordIsNotStrong, "Password is not enough strong."); } return new ApiObject(await _userManager.PasswordReset(args.Token, args.NewPassword)); } } }