public Task BindModelAsync(ModelBindingContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var fieldName  = context.ModelName;
            var fieldValue = context.ValueProvider.GetValue(fieldName);

            if (fieldValue == ValueProviderResult.None || string.IsNullOrWhiteSpace(fieldValue.FirstValue))
            {
                return(Task.CompletedTask);
            }

            if (!Helpers.TryFromBase64String(fieldValue.FirstValue, out var buffer))
            {
                context.ModelState.TryAddModelError(fieldName, $"Is not a valid base64 string.");
                return(Task.CompletedTask);
            }

            var model = C25519Point.From(buffer);

            if (!model.IsValid)
            {
                context.ModelState.TryAddModelError(fieldName, $"Is not a valid point.");
                return(Task.CompletedTask);
            }

            context.Result = ModelBindingResult.Success(model);
            return(Task.CompletedTask);
        }
        public ActionResult GetSecret([FromRoute] string user, [FromRoute] string pass)
        {
            var g = C25519Point.From(Convert.FromBase64String(pass.DecodeBase64Url()));

            if (!g.IsValid)
            {
                return(BadRequest());
            }

            var s  = new BigInteger(Convert.FromBase64String(_manager.GetSecret(user)), true, true);
            var gs = g * s;

            return(Ok(Convert.ToBase64String(gs.ToByteArray())));
        }
        public async Task <ActionResult <ApplyResponse> > Apply([FromRoute] Guid uid, [FromRoute] string pass)
        {
            if (!pass.FromBase64UrlString(out byte[] bytesPass))
            {
                _logger.LogInformation($"Apply: Invalid pass for {uid}");
                return(BadRequest("Invalid parameters"));
            }

            C25519Point g;

            try
            {
                g = C25519Point.From(bytesPass);
                if (!g.IsValid)
                {
                    _logger.LogInformation($"Apply: Invalid point for {uid}");
                    return(BadRequest("Invalid parameters"));
                }
            }
            catch (ArgumentException)
            {
                _logger.LogInformation($"Apply: Invalid point for {uid} with error");
                return(BadRequest("Invalid parameters"));
            }

            var s = await _manager.GetPrism(uid);

            if (s == BigInteger.Zero)
            {
                _logger.LogInformation($"Apply: Account {uid} does not exist");
                return(BadRequest("Invalid parameters"));
            }

            var gs = g * s;

            _logger.LogInformation($"Login attempt for {uid}", uid, pass);
            return(new ApplyResponse
            {
                Prism = gs.ToByteArray(),
                Token = new TranToken().ToByteArray()
            });
        }
        public async Task <ActionResult> Authenticate([FromRoute] Guid uid, [FromRoute] C25519Point point, [FromRoute] string token, [FromHeader] Guid tranid)
        {
            if (!token.FromBase64UrlString(out byte[] bytesToken))
            {
                _logger.LoginUnsuccessful(ControllerContext.ActionDescriptor.ControllerName, tranid, uid, $"Authenticate: Invalid token format for {uid}");
                return(Unauthorized());
            }

            var tran    = TranToken.Parse(bytesToken);
            var account = await _manager.GetById(uid);

            if (account == null || tran == null || !tran.Check(account.PrismiAuth, uid.ToByteArray()))
            {
                if (account == null)
                {
                    _logger.LoginUnsuccessful(ControllerContext.ActionDescriptor.ControllerName, tranid, uid, $"Authenticate: Account {uid} does not exist");
                }
                else
                {
                    _logger.LoginUnsuccessful(ControllerContext.ActionDescriptor.ControllerName, tranid, uid, $"Authenticate: Invalid token for {uid}");
                }

                return(Unauthorized("Invalid account or signature"));
            }

            if (!tran.OnTime)
            {
                _logger.LoginUnsuccessful(ControllerContext.ActionDescriptor.ControllerName, tranid, uid, $"Authenticate: Expired token for {uid}");
                return(StatusCode(418, new TranToken().ToString()));
            }

            _logger.LoginSuccessful(ControllerContext.ActionDescriptor.ControllerName, tranid, uid, $"Authenticate: Successful login for {uid}");
            var cvkAuthi = (point * account.Cmki).ToByteArray();

            return(Ok(account.PrismiAuth.EncryptStr(cvkAuthi)));
        }