Knocks/BackEnd/Knoks.Api/Controllers/GeneralController.cs

390 lines
15 KiB
C#

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<GeneralController> _logger;
private readonly IGeneralManager _generalManager;
private readonly IUserManager _userManager;
private readonly IExchangeManager _exchangeManager;
private readonly IOperatorManager _operatorManager;
#endregion
/// <summary>
/// ctor
/// </summary>
/// <param name="logger"></param>
/// <param name="generalManager"></param>
/// <param name="userManager"></param>
/// <param name="operatorManager"></param>
/// <param name="exchangeManager"></param>
/// <param name="systemConfigurationManager"></param>
public GeneralController(
ILogger<GeneralController> 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<User> 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<User> 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<SiteMeta> 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<ApiArray<Country>> GetCountries()
{
return GetCountries(null);
}
[HttpGet("UserRankCount")]
public async Task<ApiArray<RankCount>> GetUserRanksCount()
{
return ApiArray(await _generalManager.GetUserRankCount(this.ContextUserId));
}
[HttpGet("KnoksLossCount")]
public async Task<ApiArray<KnokLossCount>> KnoksLossCount()
{
return ApiArray(await _generalManager.GetKnoksLossCount(this.ContextUserId));
}
[HttpGet("Countries/{CountryCode2}")]
public async Task<ApiArray<Country>> GetCountries([FromRoute]string countryCode2)
{
return ApiArray(await _generalManager.GetCountries(countryCode2));
}
[HttpGet("Languages")]
public async Task<ApiArray<Language>> GetLanguages()
{
return ApiArray(await _generalManager.GetLanguages());
}
[HttpGet("KnokStatuses")]
public async Task<ApiArray<KnokStatus>> GetKnokStatuses()
{
return ApiArray(await _generalManager.GetKnokStatuses());
}
[HttpGet("KnokStartvalues")]
public async Task<ApiObject<ExchangeStart>> GetKnokStartValues([FromQuery]int exchangeId, [FromQuery]string currency1, [FromQuery]string currency2)
{
return ApiObject(await _exchangeManager.GetTradingPairRate(exchangeId, currency1, currency2));
}
[HttpPost("AddOngoingKnokFeedback")]
public async Task<ApiObject<bool>> 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<bool>(true));
}
[HttpPost("AddEndedKnokFeedback")]
public async Task<ApiObject<bool>> 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<bool>(true));
}
[UserForbid, OperatorForbid]
[HttpPost("Operator")]
public async Task<Operator> 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<ApiObject<bool>> Update([FromServices] IExchangeManager exchangeManager)
{
await exchangeManager.UpdateExchanges();
return new ApiObject<bool>(true);
}
[HttpGet("FilterCurrencies")]
public async Task<ApiArray<Currency>> GetFilterCurrencies([FromQuery] long? userId, [FromQuery] bool? availableKnoks, [FromQuery] bool? activeKnoks, [FromQuery] bool? endedKnoks)
{
return new ApiArray<Currency>(await _generalManager.GetFilterCurrencies(userId, availableKnoks, activeKnoks, endedKnoks));
}
[HttpGet("Currencies/{currency?}")]
public async Task<ApiArray<Currency>> GetCurrencies([FromRoute] string currency)
{
return new ApiArray<Currency>(await _generalManager.GetCurrencies(currency));
}
[HttpGet("Exchanges")]
public async Task<ApiArray<Exchange>> GetExchanges([FromServices] IExchangeManager exchangeManager, [FromQuery] long? userId, [FromQuery] bool? availableKnoks, [FromQuery] bool? activeKnoks, [FromQuery] bool? endedKnoks)
{
return new ApiArray<Exchange>(await _generalManager.GetExchanges(userId, availableKnoks, activeKnoks, endedKnoks));
}
[HttpGet("Configs")]
public Task<ApiDictionary<string>> GetConfigs([FromQuery]IList<string> 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<string>(
settings
//new Dictionary<string, string>() { { "KnokSettings.MaximumDuration", knokManager.MaximumDuration.ToString() }//days }
));
}
[HttpGet("Tags/{isTechnical:int}")]
public async Task<ApiArray<AnalysisTag>> GetTags([FromRoute] int isTechnical, [FromServices]Core.Data.Interfaces.ITagDao tagDao)
{
return new ApiArray<AnalysisTag>((await tagDao.GetTags(isTechnical == 1 ? isTechnical : 2)));
}
[HttpPost("SendPasswordReset")]
[AllowAnonymous]
public async Task<ApiObject<bool>> SendPasswordReset([FromBody] RetrievePasswordArgs args)
{
if (await _userManager.UserEmailExists(args.Email))
{
await _userManager.SendPasswordResetLink(args.Email, args.Url);
return new ApiObject<bool>(true);
}
throw new ApiResponseException(ApiErrorType.UserEmailDoesNotExist, $"User with \"{args.Email}\" email does not exist.");
}
[HttpPost("CheckPasswordResetToken")]
[AllowAnonymous]
public async Task<ApiObject<bool>> 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<bool>(true);
}
[HttpPost("PasswordReset")]
[AllowAnonymous]
public async Task<ApiObject<bool>> 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<bool>(await _userManager.PasswordReset(args.Token, args.NewPassword));
}
}
}