예제 #1
0
 public void SaveAuthorization(DbAuthorization authz)
 {
     using (var db = new LiteDatabase(DbName))
     {
         db.GetCollection <DbAuthorization>().Upsert(authz);
     }
 }
예제 #2
0
        public ActionResult <Order> NewOrder([FromBody] JwsSignedPayload signedPayload)
        {
            var ph = ExtractProtectedHeader(signedPayload);

            ValidateNonce(ph);

            var requ = ExtractPayload <CreateOrderRequest>(signedPayload);

            var acct = _repo.GetAccountByKid(ph.Kid);

            if (acct == null)
            {
                throw new Exception("could not resolve account");
            }
            var acctId = acct.Id.ToString();

            ValidateAccount(acct, signedPayload);

            if (requ.Identifiers.Length == 0)
            {
                throw new Exception("at least one identifier is required");
            }

            if (requ.Identifiers.Length > 100)
            {
                throw new Exception("too many identifiers");
            }

            if (requ.Identifiers.Count(x => x.Type != "dns") > 0)
            {
                throw new Exception("unsupported identifier type");
            }

            // We start by saving an empty order so we can compute the next ID
            var dbOrder = new DbOrder();

            _repo.SaveOrder(dbOrder);

            var orderId  = dbOrder.Id.ToString();
            var orderIds = new { acctId, orderId };
            var orderUrl = Url.Action(nameof(GetOrder), controller: null,
                                      values: orderIds, protocol: Request.Scheme);
            var finalizeUrl = Url.Action(nameof(FinalizeOrder), controller: null,
                                         values: orderIds, protocol: Request.Scheme);

            var authzs = new List <DbAuthorization>();

            foreach (var dnsId in requ.Identifiers)
            {
                var authzKey = Guid.NewGuid().ToString();
                var chlngs   = new List <DbChallenge>();

                var chlngTypes = ChallengeTypes;
                var isWildcard = dnsId.Value.StartsWith("*.");

                if (isWildcard)
                {
                    chlngTypes = ChallengeTypesForWildcard;
                }

                foreach (var chlngType in chlngTypes)
                {
                    var chlngToken = Guid.NewGuid().ToString();

                    // We start by saving an empty challenge so we can compute the next ID
                    var chlng = new DbChallenge
                    {
                        Payload = new Challenge
                        {
                            Token = chlngToken,
                            // We temporarily assign the token to the URL in order
                            // to satisfy the unique constraint on the URL index
                            Url = chlngToken,
                        }
                    };
                    _repo.SaveChallenge(chlng);

                    chlng.Payload = new Challenge
                    {
                        Type   = chlngType,
                        Token  = chlngToken,
                        Status = "pending",
                        Url    = Url.Action(nameof(GetChallenge), controller: null,
                                            values: new { authzKey, challengeId = chlng.Id.ToString() },
                                            protocol: Request.Scheme),
                    };
                    _repo.SaveChallenge(chlng);
                    chlngs.Add(chlng);
                }

                var dbAuthz = new DbAuthorization
                {
                    OrderId = dbOrder.Id,
                    Url     = Url.Action(nameof(GetAuthorization), controller: null,
                                         values: new { authzKey }, protocol: Request.Scheme),
                    Payload = new Authorization
                    {
                        Identifier = dnsId,
                        Status     = "pending",
                        Expires    = DateTime.Now.AddHours(24).ToUniversalTime().ToString(),
                        Challenges = chlngs.Select(x => x.Payload).ToArray(),
                        Wildcard   = isWildcard ? (bool?)true : null,
                    }
                };
                _repo.SaveAuthorization(dbAuthz);
                authzs.Add(dbAuthz);

                foreach (var chlng in chlngs)
                {
                    chlng.AuthorizationId = dbAuthz.Id;
                    _repo.SaveChallenge(chlng);
                }
            }

            dbOrder.Url       = orderUrl;
            dbOrder.AccountId = acct.Id;
            dbOrder.Details   = new OrderDetails
            {
                OrderUrl = orderUrl,
                Payload  = new Order
                {
                    Expires        = DateTime.Now.AddHours(24).ToUniversalTime().ToString(),
                    NotBefore      = null, // requ.NotBefore,
                    NotAfter       = null, //requ.NotAfter,
                    Identifiers    = requ.Identifiers,
                    Authorizations = authzs.Select(x => x.Url).ToArray(),
                    Finalize       = finalizeUrl,
                    Status         = "pending",
                    Error          = null,
                    Certificate    = null,
                }
            };
            _repo.SaveOrder(dbOrder);

            GenerateNonce();

            return(Created(orderUrl, dbOrder.Details.Payload));
        }