示例#1
0
        public async Task <IActionResult> SetPassword(Guid guid, [FromBody] SetPasswordPostModel pwModel)
        {
            var shortLink = Db.ShortLinks.Find(guid);

            if (shortLink == null)
            {
                return(NotFound(ErrorModel.NotFound()));
            }

            if (pwModel.Reset)
            {
                shortLink.PasswordHash        = default;
                shortLink.IsPasswordProtected = false;
                return(Ok());
            }

            if (pwModel.Password.IsEmpty())
            {
                return(BadRequest(ErrorModel.BadRequest("empty password")));
            }

            shortLink.PasswordHash        = Hashing.CreatePasswordHash(pwModel.Password);
            shortLink.IsPasswordProtected = true;

            Db.ShortLinks.Update(shortLink);
            await Db.SaveChangesAsync();

            return(Ok());
        }
示例#2
0
        public async Task <IActionResult> Initialize([FromBody] GeneralSettingsPostModel model)
        {
            var settings = Db.GeneralSettings.FirstOrDefault();

            if (settings != null && !settings.PasswordHash.IsEmpty())
            {
                return(new ForbidResult());
            }

            if (model.Password.IsEmpty())
            {
                return(BadRequest(ErrorModel.BadRequest("invalid new password")));
            }

            var hash = Hashing.CreatePasswordHash(model.Password);

            Db.GeneralSettings.Add(new GeneralSettingsModel()
            {
                PasswordHash = hash,
            });

            await Db.SaveChangesAsync();

            return(Ok());
        }
示例#3
0
        public async Task <IActionResult> Login([FromBody, Bind("ListIdentifier", "Keyword")] AuthorizationModel auth)
        {
            if (!auth.Validate())
            {
                return(BadRequest(ErrorModel.BadRequest()));
            }

            auth.LowerIdentifier();

            var list = db.Lists.FirstOrDefault(l => l.Identifier == auth.ListIdentifier);

            if (list == null)
            {
                return(Unauthorized());
            }

            if (!keywordAccess.ValidateLogin(list, auth.Keyword))
            {
                return(Unauthorized());
            }

            var claims = new List <Claim>
            {
                new Claim(ExtendedClaimTypes.ListIdentifier, list.Identifier),
                new Claim(ExtendedClaimTypes.ListGUID, list.GUID.ToString()),
            };

            var identity  = new ClaimsIdentity(claims, "login");
            var principal = new ClaimsPrincipal(identity);

            await HttpContext.SignInAsync(principal);

            return(Ok());
        }
示例#4
0
        public async Task <IActionResult> ForgotPassword([FromBody] ForgotPasswordViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ErrorModel.BadRequest(Request, ModelState)));
            }
            var user = await _userManager.FindByEmailAsync(model.Email);

            if (user == null)
            {
                return(NotFound(new ErrorModel
                {
                    StatusCode = System.Net.HttpStatusCode.NotFound,
                    Method = Request.Method,
                    URL = Request.Path,
                    Message = "User Not Found!"
                }));
            }

            //var code = await _userManager.GeneratePasswordResetTokenAsync(user);
            //
            //var callbackUrl = Url.ResetPasswordCallbackLink(user.Id, code, Request.Scheme);
            //
            //await _emailSender.SendEmailAsync(model.Email, "Reset Password",
            //     $"Please reset your password by clicking here: <a href='{callbackUrl}'>link</a>");
            ////return RedirectToAction(nameof(ForgotPasswordConfirmation));

            return(Ok("Password reset sent to your email."));
        }
示例#5
0
        public async Task <IActionResult> Edit(Guid guid, [FromBody] ShortLinkModel newShortLink)
        {
            var shortLink = Db.ShortLinks.Find(guid);

            if (shortLink == null)
            {
                return(NotFound(ErrorModel.NotFound()));
            }

            if (!shortLink.ValidateIdent())
            {
                return(BadRequest(ErrorModel.BadRequest("invalid short ident")));
            }

            if (!CheckShortIdent(newShortLink, shortLink.GUID))
            {
                return(BadRequest(ErrorModel.BadRequest("short ident already in use")));
            }

            if (!await newShortLink.ValidateURI())
            {
                return(BadRequest(ErrorModel.BadRequest("invalid root link")));
            }

            shortLink.Update(newShortLink);
            shortLink.Sanitize();

            Db.ShortLinks.Update(shortLink);
            await Db.SaveChangesAsync();

            return(Ok(shortLink));
        }
示例#6
0
        public async Task <IActionResult> ResetPassword([FromBody] ResetPasswordViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ErrorModel.BadRequest(Request, ModelState)));
            }

            var user = await _userManager.FindByEmailAsync(model.Email);

            if (user == null)
            {
                return(NotFound(new ErrorModel
                {
                    StatusCode = HttpStatusCode.NotFound,
                    Method = Request.Method,
                    URL = Request.Path,
                    Message = "User Not Found!",
                }));
            }
            var result = await _userManager.ResetPasswordAsync(user, model.Code, model.Password);

            if (result.Succeeded)
            {
                return(Ok("Password Reset Successfully"));
            }

            return(BadRequest(ErrorModel.BadRequest(Request)));
        }
示例#7
0
        public async Task <IActionResult> CreateList(
            [FromBody, Bind("Listidentifier", "Keyword")] AuthorizationModel listAuth)
        {
            if (!listAuth.Validate())
            {
                return(BadRequest(ErrorModel.BadRequest()));
            }

            listAuth.LowerIdentifier();

            if (db.Lists.FirstOrDefault(l => l.Identifier == listAuth.ListIdentifier) != null)
            {
                return(BadRequest(ErrorModel.AlreadyExists()));
            }

            var list = new List(listAuth.ListIdentifier, listAuth.Keyword);

            var masterKey = SecureRandom.GenerateMasterKey(32);

            list.MasterKeyHash = Hashing.CreatePasswordHash(masterKey);

            await db.Lists.AddAsync(list);

            await db.SaveChangesAsync();

            var outList = new ListCreated(list, masterKey);

            return(Created("list", outList));
        }
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            var listGUID = ((IListController)context.Controller).CurrentListGUID;
            var currList = db.Lists.Find(listGUID);

            if (currList == null)
            {
                context.Result = new NotFoundObjectResult(ErrorModel.NotFound());
                return;
            }


            if (!(context.ActionArguments.Values.FirstOrDefault(v => v is IMasterKey) is IMasterKey masterKeyModel))
            {
                context.Result = new BadRequestObjectResult(ErrorModel.BadRequest());
                return;
            }

            if (!Hashing.CompareStringToHash(masterKeyModel.MasterKey, currList.MasterKeyHash))
            {
                var res = new ObjectResult(ErrorModel.Unauthorized());
                res.StatusCode = 401;
                context.Result = res;
                return;
            }
        }
示例#9
0
        public IActionResult ChangePassword([FromBody] ChangePasswordViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ErrorModel.BadRequest(Request, ModelState)));
            }

            var user = ApplicationUser.Get(db, User);

            _userManager.ChangePasswordAsync(user, model.Password, model.NewPassword);

            return(Ok("Password Changed Successfully"));
        }
示例#10
0
        public async Task <IActionResult> Set([FromBody] GeneralSettingsPostModel model)
        {
            var isNew    = false;
            var settings = Db.GeneralSettings.FirstOrDefault();

            if (settings == null)
            {
                settings = new GeneralSettingsModel();
                isNew    = true;
            }

            if (!model.Password.IsEmpty())
            {
                if (model.CurrentPassword.IsEmpty() || !Hashing.CompareStringToHash(model.CurrentPassword, settings.PasswordHash))
                {
                    return(BadRequest(ErrorModel.BadRequest("invalid current password")));
                }

                settings.PasswordHash = Hashing.CreatePasswordHash(model.Password);
            }

            if (!model.DefaultRedirect.IsEmpty())
            {
                if (model.DefaultRedirect.Equals("__RESET__"))
                {
                    settings.DefaultRedirect = null;
                }
                else
                {
                    if (!await URIValidation.Validate(model.DefaultRedirect))
                    {
                        return(BadRequest(ErrorModel.BadRequest("invalid defautl redirect url")));
                    }
                    settings.DefaultRedirect = model.DefaultRedirect;
                }
            }

            if (isNew)
            {
                Db.GeneralSettings.Add(settings);
            }
            else
            {
                Db.GeneralSettings.Update(settings);
            }

            await Db.SaveChangesAsync();

            return(Ok(settings));
        }
示例#11
0
        public IActionResult Search([FromQuery] string query,
                                    [FromQuery] int page      = 0,
                                    [FromQuery] int size      = 100,
                                    [FromQuery] string sortBy = "CreationDate")
        {
            if (query.IsEmpty())
            {
                return(BadRequest(ErrorModel.BadRequest("invalid search query")));
            }

            query = query.ToLower();

            var shortLinkModel = typeof(ShortLinkModel);
            var property       = shortLinkModel.GetProperties()
                                 .FirstOrDefault(p => p.Name.ToLower() == sortBy.ToLower());

            if (property == null)
            {
                return(BadRequest(ErrorModel.BadRequest("invalid property for 'sortBy'")));
            }

            var outList = Db.ShortLinks
                          .Where((sl) => sl.ShortIdent.Contains(query) ||
                                 sl.RootURL.Contains(query) ||
                                 sl.GUID.ToString().Contains(query))
                          .OrderByDescending(sl => property.GetValue(sl))
                          .Skip(page * size)
                          .Take(size)
                          .ToList()
                          .Select(sl =>
            {
                var accesses = DbCache.GetAccesses(sl.GUID);

                sl.UniqueAccessCount = accesses
                                       .ToArray()
                                       .Count(a => a.IsUnique);

                sl.AccessCount = accesses.Length;

                sl.LastAccess = accesses
                                .OrderBy(a => a.Timestamp)
                                .LastOrDefault()?.Timestamp ?? DateTime.MinValue;

                return(sl);
            });

            return(Ok(outList));
        }
        public async Task <IActionResult> CreateEntry([Bind("Content"), FromBody] ListEntryPostModel entry)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ErrorModel.BadRequest()));
            }

            if (entry.Content == null || entry.Content == "")
            {
                return(BadRequest(ErrorModel.BadRequest()));
            }

            var listEntry = new ListEntry <string>(entry.Content, CurrentListGUID);

            db.Entries.Add(listEntry);
            await db.SaveChangesAsync();

            return(CreatedAtAction("entry created", listEntry));
        }
示例#13
0
        public async Task <IActionResult> LoginByPhone([FromBody] LoginByPhoneViewModel model)
        {
            if (ModelState.IsValid)
            {
                var user = db.Users.SingleOrDefault(u => u.PhoneNumber == model.PhoneNumber);

                if (user == null)
                {
                    return(NotFound(new ErrorModel
                    {
                        StatusCode = System.Net.HttpStatusCode.NotFound,
                        Method = Request.Method,
                        URL = Request.Path,
                        Message = "User Not Found",
                    }));
                }

                var result = await _userManager.ChangePhoneNumberAsync(user, model.PhoneNumber, model.VerificationCode);

                if (!result.Succeeded)
                {
                    AddErrors(result);

                    return(BadRequest(ErrorModel.BadRequest(Request, ModelState)));
                }

                var token = await GetToken(user);

                if (token != null)
                {
                    return(Ok(token));
                }
            }

            return(BadRequest(new ErrorModel
            {
                StatusCode = System.Net.HttpStatusCode.BadRequest,
                Method = Request.Method,
                URL = Request.Path,
                Message = "Login Failed"
            }));
        }
示例#14
0
        public async Task <IActionResult> RegisterByPhone([FromBody] RegisterByPhoneViewModel model)
        {
            ApplicationUser user;

            if (!db.Users.Any(u => u.PhoneNumber == model.PhoneNumber))
            {
                user = new ApplicationUser {
                    UserName = model.PhoneNumber, PhoneNumber = model.PhoneNumber, AddDateTime = DateTime.Now
                };

                var result = await _userManager.CreateAsync(user);

                if (result.Succeeded)
                {
                    _logger.LogInformation("User created a new account with phone number.");

                    await _signInManager.SignInAsync(user, isPersistent : false);

                    await _userManager.AddToRoleAsync(user, "User");
                }
                else
                {
                    AddErrors(result);

                    return(BadRequest(ErrorModel.BadRequest(Request, ModelState)));
                }
            }
            else
            {
                user = db.Users.SingleOrDefault(u => u.PhoneNumber == model.PhoneNumber);
            }

            //var code = await _userManager.GenerateChangePhoneNumberTokenAsync(user, user.PhoneNumber);
            //await _SMSSender.SendSMSAsync(user.PhoneNumber, $"{code} is your verification code in {_config["Title"]}", false);

            //if (_config["Development"] == "True")
            //{
            //    return Ok(new { Status = "Verification code sent!", Code = code });
            //}

            return(Ok(new { Status = "Verification code sent!" }));
        }
示例#15
0
        public async Task <IActionResult> Login([FromBody] LoginViewModel model)
        {
            if (!ModelState.IsValid)
            {
                return(BadRequest(ErrorModel.BadRequest(Request, ModelState)));
            }

            if (ModelState.IsValid)
            {
                return(await GetTokenAsync(model));
            }

            return(BadRequest(new ErrorModel
            {
                StatusCode = System.Net.HttpStatusCode.BadRequest,
                Message = "Login Failed",
                Method = Request.Method,
                URL = Request.Path
            }));
        }
        public async Task <IActionResult> DeleteEntry(Guid entryId)
        {
            if (entryId == null)
            {
                return(BadRequest(ErrorModel.BadRequest()));
            }

            var entry = db.Entries
                        .FirstOrDefault(e => e.ListGUID == CurrentListGUID && e.GUID == entryId);

            if (entry == null)
            {
                return(NotFound(ErrorModel.NotFound()));
            }

            db.Entries.Remove(entry);
            await db.SaveChangesAsync();

            return(Ok());
        }
示例#17
0
        public async Task <IActionResult> ChangePassword(
            [FromBody, Bind("MasterKey", "NewKeyword")] ListPasswordChangeModel model)
        {
            var list = db.Lists.Find(CurrentListGUID);

            if (list == null)
            {
                return(NotFound(ErrorModel.NotFound()));
            }

            if (model.NewKeyword == null || model.NewKeyword.Length < 1)
            {
                return(BadRequest(ErrorModel.BadRequest()));
            }

            list.KeywordHash = Hashing.CreatePasswordHash(model.NewKeyword);
            db.Lists.Update(list);
            await db.SaveChangesAsync();

            return(Ok());
        }
示例#18
0
        public async Task <IActionResult> ProtectedRedirect(Guid guid, [FromBody] ProtectedPostModel model)
        {
            if (model.Password.IsEmpty())
            {
                return(Unauthorized());
            }

            var shortLink = Db.ShortLinks.Find(guid);

            if (!IsValid(shortLink))
            {
                return(BadRequest(ErrorModel.BadRequest("invalid short link")));
            }

            if (!shortLink.IsPasswordProtected)
            {
                return(BadRequest(ErrorModel.BadRequest("short link not password protected")));
            }

            try
            {
                if (!Hashing.CompareStringToHash(model.Password, shortLink.PasswordHash))
                {
                    return(Unauthorized());
                }
            }
            catch (Exception)
            {
                return(Unauthorized());
            }

            await CountRedirect(shortLink, model.DisableTracking);

            var res = new ProtectedResponseModel()
            {
                RootURL = shortLink.RootURL,
            };

            return(Ok(res));
        }
示例#19
0
        public async Task <IActionResult> Create([FromBody] ShortLinkModel shortLink)
        {
            if (!shortLink.ValidateIdent())
            {
                return(BadRequest(ErrorModel.BadRequest("invalid short ident")));
            }

            if (!CheckShortIdent(shortLink))
            {
                return(BadRequest(ErrorModel.BadRequest("short ident already in use")));
            }

            if (!await shortLink.ValidateURI())
            {
                return(BadRequest(ErrorModel.BadRequest("invalid root link")));
            }

            shortLink.Sanitize(asNew: true);

            Db.ShortLinks.Add(shortLink);
            await Db.SaveChangesAsync();

            return(Created(shortLink.GUID.ToString(), shortLink));
        }