public Task <ActionResult <List <ModuleContentView> > > SearchModules([FromQuery] string?name = null, [FromQuery] string?fields = "*") { return(MatchExceptions(async() => { var userId = GetUserIdStrict(); var values = new Dictionary <string, object> { { "type", InternalContentType.module }, }; var query = "contentType = @type and !notdeleted()"; if (name != null) { query += " and name like @name"; values.Add("name", name); } var modules = await CachedSearcher.SearchSingleType <ModuleContentView>(userId, new SearchRequest() { type = "content", fields = fields ?? "*", query = query }, values); foreach (var m in modules) { var loaded = modService.RefreshModule(m); m.subcommands = loaded.subcommands; } return modules; })); }
public Task <ActionResult <ContentView> > PostByNameAsync([FromBody] ContentView module) { return(MatchExceptions(async() => { RateLimit(RateWrite); //Go find by name first var userId = GetUserIdStrict(); var existing = await CachedSearcher.GetModuleForSystemByNameAsync(module.name, userId); if (existing != null) { module.id = existing.id; } else { module.id = 0; } //Need to add this just in case they don't, since this is a SPECIFIC module endpoint module.contentType = InternalContentType.module; var result = await CachedWriter.WriteAsync(module, userId); modService.RefreshModule(result); //Make it ready immediately, just in case. return result; })); }
public async Task <ActionResult <bool> > GetRawAsync([FromRoute] string hash) { try { var requester = GetUserId() ?? 0; var result = await CachedSearcher.SearchSingleType <ContentView>(requester, new SearchRequest() { type = nameof(RequestType.content), query = "hash = @hash", fields = "id, text, hash, literalType, lastRevisionId" }, new Dictionary <string, object> { { "hash", hash } }); if (result.Count == 0) { throw new NotFoundException($"No content found with hash {hash}"); } var content = result.First(); Response.Headers.Add("ETag", $"{hash}-{content.lastRevisionId}"); Response.Headers.Add("Content-Type", content.literalType); return(Content(content.text)); //File(result.Item1, result.Item2); } catch (Exception ex) { return(await MatchExceptions(() => { ExceptionDispatchInfo.Capture(ex).Throw(); return Task.FromResult(true); })); } }
public Task <ActionResult <bool> > SendPasswordRecovery([FromBody] string email) { return(MatchExceptions(async() => { if (config.ConfirmationType == InstantConfirmation) { throw new RequestException("User account creation is instant, meaning there is no email system in place and no way to recover passwords!"); } var userId = await userService.GetUserIdFromEmailAsync(email); var tempPassword = userService.GetTemporaryPassword(userId); var user = await CachedSearcher.GetById <UserView>(RequestType.user, userId); var utcExpire = tempPassword.ExpireDate.ToUniversalTime(); if (config.ConfirmationType.StartsWith(RestrictedConfirmation)) { var message = new EmailMessage(); message.Recipients = GetRestrictedEmails(); message.Title = $"User {user.username} is trying to recover their account"; message.Body = $"User {user.username} is trying to recover their account using email {email} on {Request.Host}\n\nIf this looks acceptable, please send them " + $"an email stating they have a ONE TIME USE temporary password that will last until {utcExpire} UTC ({StaticUtils.HumanTime(utcExpire - DateTime.UtcNow)}):\n\n{tempPassword.Key}"; //TODO: language? Configuration? I don't know await emailer.SendEmailAsync(message); } else { //TODO: language? Configuration? I don't know await emailer.SendEmailAsync(new EmailMessage(email, "Account Recovery", $"You can temporarily access your account on '{Request.Host}' for another {StaticUtils.HumanTime(utcExpire - DateTime.UtcNow)} using the ONE TIME USE temporary password:\n\n{tempPassword.Key}")); } return true; })); }
public Task <ActionResult <UserView> > GetMe() { return(MatchExceptions(() => { var uid = GetUserIdStrict(); return CachedSearcher.GetById <UserView>(RequestType.user, uid, true); })); }
public Task <ActionResult <RequestResponse> > RequestAsync([FromBody] SearchRequests search) { var sw = new Stopwatch(); sw.Start(); return(MatchExceptions(async() => { var data = await CachedSearcher.Search(search, GetUserId() ?? 0); var result = services.mapper.Map <RequestResponse>(data); result.requestUser = GetUserId(); sw.Stop(); result.totalTime = sw.Elapsed.TotalMilliseconds; result.nonDbTime = result.totalTime - result.databaseTimes.Sum(x => x.Value); return result; })); }
public Task <ActionResult <bool> > SendRegistrationCode([FromBody] string email) { return(MatchExceptions(async() => { if (config.ConfirmationType == InstantConfirmation) { throw new RequestException("User account creation is instant, there is no registration code"); } var userId = await userService.GetUserIdFromEmailAsync(email); var registrationCode = await userService.GetRegistrationKeyAsync(userId); var user = await CachedSearcher.GetById <UserView>(RequestType.user, userId); if (string.IsNullOrWhiteSpace(registrationCode)) { throw new RequestException("Couldn't find registration code for this email! Probably already registered!"); } if (config.ConfirmationType.StartsWith(RestrictedConfirmation)) { var message = new EmailMessage(); message.Recipients = GetRestrictedEmails(); message.Title = $"User {user.username} would like to create an account"; message.Body = $"User {user.username} is trying to create an account using email {email} on {Request.Host}\n\nIf this looks acceptable, please send them " + $"an email with instructions on how to create an account, using registration code:\n\n{registrationCode}"; //TODO: language? Configuration? I don't know await emailer.SendEmailAsync(message); } else { //TODO: language? Configuration? I don't know await emailer.SendEmailAsync(new EmailMessage(email, "Registration instructions", $"Your registration code for '{Request.Host}' is:\n\n{registrationCode}")); } return true; })); }
public Task <ActionResult <UserView> > Register([FromBody] UserCredentials credentials) { //Like all controllers, we want ALL of the work possible to be inside a service, not the controller. //A service which can be tested! return(MatchExceptions <UserView>(async() => { if (!config.AccountCreationEnabled) { throw new ForbiddenException("We're sorry, account creation is disabled at this time"); } var userId = await userService.CreateNewUser(credentials.username, credentials.password, credentials.email); var result = await CachedSearcher.GetById <UserView>(RequestType.user, userId); if (config.ConfirmationType == InstantConfirmation) { services.logger.LogDebug("Instant user account creation set, completing registration immediately"); var token = await userService.CompleteRegistration(userId, await userService.GetRegistrationKeyAsync(userId)); result.special = token; } return result; })); }
protected async Task <UserView> GetUserViewStrictAsync() { var userId = GetUserIdStrict(); return(await CachedSearcher.GetById <UserView>(RequestType.user, userId) ?? throw new RequestException($"Couldn't find user with id {userId}")); }