Example #1
0
        private async Task InitializeRootUser()
        {
            logger.LogInformation("Initializing root user...");

            var userName = config.GetValue <string>(Constants.ConfigKeyInitializationUserName);

            if (string.IsNullOrEmpty(userName))
            {
                throw new ArgumentException("root username not provided");
            }

            var password = config.GetValue <string>(Constants.ConfigKeyInitializationPassword);

            if (string.IsNullOrEmpty(password))
            {
                throw new ArgumentException("root user password not provided");
            }

            var user = new UserModel
            {
                UserName     = userName,
                PasswordHash = await pwHasher.GetEncodedHash(password),
                Permissions  = Permissions.ADMINISTRATOR,
            };

            database.Create(user);
            await database.Commit();

            logger.LogInformation($"Root user with name '{userName}' and the provided password was created.");
        }
Example #2
0
        public async Task <ActionResult <IEnumerable <UserViewModel> > > Create([FromBody] UserCreateModel user)
        {
            if (!await UsernameAlreadyExists(user.UserName))
            {
                return(BadRequest(new ResponseErrorModel("username already exists")));
            }

            var newUser = new UserModel
            {
                UserName     = user.UserName,
                PasswordHash = await hasher.GetEncodedHash(user.Password),
                Permissions  = user.Permissions,
            };

            database.Create(newUser);
            await database.Commit();

            return(Created(
                       $"/api/users/{newUser.Guid}",
                       new UserViewModel(newUser)));
        }
Example #3
0
        public async Task <ActionResult <LinkViewModel> > Create([FromBody] LinkCreateModel link)
        {
            if (string.IsNullOrEmpty(link.Ident))
            {
                do
                {
                    link.Ident = RandomUtil.GetString(Constants.RandomIdentLength, Constants.RandomIdentChars);
                }while (!await ValidateIdent(link.Ident));
            }
            else if (!await ValidateIdent(link.Ident))
            {
                return(BadRequest(new ResponseErrorModel("ident already exists")));
            }

            if (!await LinksUtil.ValidateDestination(link.Destination))
            {
                return(BadRequest(new ResponseErrorModel("invalid destination url")));
            }

            var newLink = new LinkModel
            {
                Creator      = AuthorizedUser,
                Destination  = link.Destination,
                Enabled      = link.Enabled,
                Expires      = link.Expires,
                Ident        = link.Ident,
                PasswordHash = string.IsNullOrEmpty(link.Password)
                    ? null
                    : await hasher.GetEncodedHash(link.Password),
                PermanentRedirect = link.PermanentRedirect,
                TotalAccessLimit  = link.TotalAccessLimit,
            };

            database.Create(newLink);
            await database.Commit();

            return(Created(
                       $"/api/links/{newLink.Guid}",
                       new LinkViewModel(newLink, AuthorizedUser)));
        }
Example #4
0
        public async Task <ActionResult <ApiKeyCreatedViewModel> > CreateApiKey()
        {
            var apiKey = await GetMyApiKey();

            if (apiKey != null)
            {
                database.Delete(apiKey);
            }

            var key = RandomUtil.GetString(Constants.RandomApiKeyLength, Constants.RandomApiKeyChars);

            var keyModel = new ApiKeyModel()
            {
                User    = AuthorizedUser,
                KeyHash = await hasher.GetEncodedHash(key),
            };

            database.Create(keyModel);
            await database.Commit();

            return(Created(
                       $"/api/apikey/{keyModel.Guid}",
                       new ApiKeyCreatedViewModel(keyModel, key)));
        }
Example #5
0
        public async Task <ActionResult <UserLoginViewModel> > Login(
            [FromBody] LoginModel login,
            [FromQuery] bool getSessionKey)
        {
            var user = await database
                       .GetWhere <UserModel>(u => u.UserName.Equals(login.Ident) || string.IsNullOrEmpty(u.MailAddress) && u.MailAddress.Equals(login.Ident))
                       .FirstOrDefaultAsync();

            if (user == null || !(await hasher.CompareEncodedHash(login.Password, user.PasswordHash)))
            {
                return(Unauthorized());
            }

            user.LastLogin = DateTime.Now;
            database.Update(user);

            var expire = login.Remember ? EXTENDED_SESSION_EXPIRATION : DEFAULT_SESSION_EXPIRATION;
            var claims = new AuthClaims
            {
                Guid = user.Guid,
            };

            var jwt = authorization.GetSessionKey(claims, expire);

            var cookieOptions = new CookieOptions
            {
                Expires  = DateTime.Now.Add(expire),
                HttpOnly = true,
                SameSite = SameSiteMode.Strict,
                Secure   = !bypassSecureCookies,
            };

            Response.Cookies.Append(Constants.SessionCookieName, jwt, cookieOptions);

            await database.Commit();

            var res = new UserLoginViewModel(user);

            if (getSessionKey)
            {
                res.SessionKey = jwt;
            }

            return(Ok(res));
        }
Example #6
0
        public async Task <ActionResult> GetIdent(
            [FromRoute] string ident,
            [FromQuery] string password)
        {
            var(ok, link) = await cache.Get <LinkModel>(ident);

            if (!ok)
            {
                link = await database.GetWhere <LinkModel>(l => l.Ident == ident).FirstOrDefaultAsync();

                if (link == null)
                {
                    return(Route(NotFound, routeNotFound));
                }
            }

            var now = DateTime.Now;

            if (!link.Enabled ||
                link.Expires != default && link.Expires <= now ||
                link.TotalAccessLimit > 0 && link.TotalAccessLimit <= link.UniqueAccessCount)
            {
                return(Route(NotFound, routeNotFound));
            }

            if (!string.IsNullOrEmpty(link.PasswordHash))
            {
                if (string.IsNullOrEmpty(password))
                {
                    return(Route(BadRequest, new ResponseErrorModel("password required"), $"{routePassword}?ident={link.Ident}"));
                }
                if (!await passwordHasher.CompareEncodedHash(password, link.PasswordHash))
                {
                    return(BadRequest(new ResponseErrorModel("password required")));
                }
            }

            link.LastAccess = now;
            link.AccessCount++;

            var hashedIPAddr = await fastHasher.GetEncodedHash(HttpContext.Connection.RemoteIpAddress.ToString());

            if (await database.GetWhere <AccessModel>(a => a.Link.Guid.Equals(link.Guid) && a.SourceIPHash.Equals(hashedIPAddr)).FirstOrDefaultAsync() == null)
            {
                link.UniqueAccessCount++;
            }

            database.Create(new AccessModel
            {
                Link         = link,
                SourceIPHash = hashedIPAddr,
            });
            database.Update(link);

            await database.Commit();

            await cache.Set(link, ident, cacheDuration);

            if (link.PermanentRedirect)
            {
                return(RedirectPermanent(link.Destination));
            }

            return(Redirect(link.Destination));
        }