private async Task StartWorkflowAsync(SigningRequest req, string[] signerEmails)
        {
            var model = new WorkflowStartModel
            {
                RequestId    = req.Id,
                DocumentName = req.DocumentName,
                Message      = req.Message,
                SignerEmails = signerEmails,
                Subject      = req.Subject
            };
            string json         = JsonSerializer.Serialize(model);
            var    startRequest = new HttpRequestMessage(HttpMethod.Post, _workflowStartUrl)
            {
                Content = new StringContent(json, Encoding.UTF8, "application/json")
            };
            HttpResponseMessage startResponse = await _httpClient.SendAsync(startRequest);

            if (startResponse.StatusCode != System.Net.HttpStatusCode.Accepted)
            {
                throw new Exception("Unexpected start response: " + startResponse.StatusCode);
            }

            // Update info about the started workflow in DB
            // Allows us to query status, terminate it etc.
            DurableFunctionsCheckStatusResponse checkStatusResponse = JsonSerializer.Deserialize <DurableFunctionsCheckStatusResponse>(await startResponse.Content.ReadAsStringAsync());

            req.Workflow.Id              = checkStatusResponse.Id;
            req.Workflow.StatusQueryUrl  = checkStatusResponse.StatusQueryGetUri;
            req.Workflow.SendEventUrl    = checkStatusResponse.SendEventPostUri;
            req.Workflow.TerminateUrl    = checkStatusResponse.TerminatePostUri;
            req.Workflow.PurgeHistoryUrl = checkStatusResponse.PurgeHistoryDeleteUri;
            await _db.SaveChangesAsync();
        }
        private async Task <IActionResult> HandlePostAsync(bool isApprove)
        {
            SigningRequest request = await _db.Requests.SingleAsync(r => r.Id == RequestId);

            Signer signer = await _db.Signers.SingleAsync(s => s.RequestId == RequestId && s.Email == SignerEmail);

            var model = new AddSignEventModel
            {
                InstanceId = signer.WaitForSignatureInstanceId,
                EventData  = new SigningEvent
                {
                    DecidedAt = DateTimeOffset.UtcNow,
                    Email     = SignerEmail,
                    Signed    = isApprove
                }
            };
            string json         = JsonSerializer.Serialize(model);
            var    startRequest = new HttpRequestMessage(HttpMethod.Post, _addSignEventUrl)
            {
                Content = new StringContent(json, Encoding.UTF8, "application/json")
            };
            HttpResponseMessage startResponse = await _httpClient.SendAsync(startRequest);

            if (startResponse.StatusCode != System.Net.HttpStatusCode.NoContent)
            {
                throw new Exception("Unexpected start response: " + startResponse.StatusCode);
            }

            return(RedirectToPage("Status", new { id = RequestId.ToString() }));
        }
示例#3
0
        public static SigningRequest BuildRequest(string id, string signText, string targetUrl)
        {
            var request = new SigningRequest()
            {
                SignText = Convert.ToBase64String(Encoding.UTF8.GetBytes(signText)),
                //EntitId = SigningConfiguration.Instance.EntityId,
                RequestId       = id,
                TargetUrl       = targetUrl,
                DigestAlgorithm = "SHA256",
                SignTextFormat  = "HTML",
                //SigneringEndPoint = SigningConfiguration.Instance.SigningServiceUrl
            };

            // Note that this implementation relies on a signing certificate being configured to Nemlog-in SSO
            //var certificate = GetCertificateFromCertStore(SigningConfiguration.Instance.SigningCertificateThumbprint);

            //// Generate digest and sign
            //var digest = string.Concat(request.SignText, request.EntitId, request.TargetUrl);
            //var digestBytes = Encoding.UTF8.GetBytes(digest);
            //var key = (RSACryptoServiceProvider)certificate.PrivateKey;
            //var hashAlgo = CryptoConfig.CreateFromName(request.DigestAlgorithm);
            //var signedFingerprint = key.SignData(digestBytes, hashAlgo);
            //request.SignedFingerprint = Convert.ToBase64String(signedFingerprint);

            return(request);
        }
示例#4
0
        public async Task MarkWorkflowCompleted(
            [ActivityTrigger] Guid requestId)
        {
            SigningRequest request = await _db.Requests.SingleAsync(r => r.Id == requestId);

            request.WorkflowCompletedAt = DateTimeOffset.UtcNow;
            await _db.SaveChangesAsync();
        }
        public async Task <IActionResult> DownloadUnsignedAsync(Guid requestId)
        {
            SigningRequest request = await _db.Requests.SingleAsync(r => r.Id == requestId);

            Stream stream = await _blobStorageService.DownloadAsync(requestId, DocumentType.Unsigned);

            return(File(stream, "application/pdf", request.DocumentName));
        }
示例#6
0
        public void GetStatusTest()
        {
            var s = new SigningRequest();

            s.Status = null;
            Assert.AreEqual(SigningRequestStatus.New, s.GetStatus());

            s.Status = (int?)SigningRequestStatus.Signed;
            Assert.AreEqual(SigningRequestStatus.Signed, s.GetStatus());
        }
示例#7
0
        private async Task <string> GetWorkflowStatusAsync(SigningRequest request)
        {
            if (string.IsNullOrEmpty(request.Workflow?.StatusQueryUrl))
            {
                return("");
            }

            HttpResponseMessage res = await _httpClient.GetAsync(request.Workflow.StatusQueryUrl);

            if (res.StatusCode != HttpStatusCode.OK && res.StatusCode != HttpStatusCode.Accepted)
            {
                return($"Failed to get status, got status code: {(int)res.StatusCode}");
            }

            string json = await res.Content.ReadAsStringAsync();

            // Deserialize and serialize in indented form
            return(JsonConvert.SerializeObject(JsonConvert.DeserializeObject(json), Formatting.Indented));
        }
        public async Task <IActionResult> OnPostAsync()
        {
            if (!ModelState.IsValid)
            {
                return(Page());
            }

            if (!Model.Document.FileName.EndsWith(".pdf", StringComparison.OrdinalIgnoreCase))
            {
                ModelState.AddModelError("Document", "Must send PDF file");
                return(Page());
            }

            var id = Guid.NewGuid();

            string[] signerEmails = Model.SignerEmails
                                    .Split(',', StringSplitOptions.RemoveEmptyEntries)
                                    .ToArray();
            var req = new SigningRequest
            {
                Id           = id,
                Subject      = Model.Subject,
                Message      = Model.Message,
                DocumentName = $"{Guid.NewGuid()}.pdf",
                Signers      = signerEmails
                               .Select(email => new Signer
                {
                    Email = email.Trim()
                })
                               .ToList()
            };

            _db.Requests.Add(req);

            await UploadAttachmentAsync(req.Id);

            await _db.SaveChangesAsync();

            await StartWorkflowAsync(req, signerEmails);

            return(RedirectToPage("Status", new { id = id.ToString() }));
        }
        public async Task <IActionResult> OnGetAsync(Guid id, [FromQuery] string email)
        {
            SigningRequest request = await _db.Requests.SingleAsync(r => r.Id == id);

            Signer signer = await _db.Signers.SingleAsync(s => s.RequestId == id && s.Email == email);

            if (signer.DecidedAt != null)
            {
                // Signer has already given their decision
                return(RedirectToPage("Status", new { id = id.ToString() }));
            }

            RequestId             = request.Id;
            SignerEmail           = email;
            RequestSubject        = request.Subject;
            RequestMessage        = request.Message;
            DocumentName          = request.DocumentName;
            WorkflowReadyForEvent = signer.WaitForSignatureInstanceId != null;
            return(Page());
        }
示例#10
0
        public async Task OnGetAsync(Guid id)
        {
            SigningRequest request = await _db.Requests
                                     .Include(r => r.Signers)
                                     .SingleAsync(r => r.Id == id);

            RequestId           = request.Id;
            RequestSubject      = request.Subject;
            RequestMessage      = request.Message;
            DocumentName        = request.DocumentName;
            WorkflowStartedAt   = request.WorkflowStartedAt;
            WorkflowCompletedAt = request.WorkflowCompletedAt;
            Signers             = request.Signers.Select(s => new SignerModel
            {
                Email     = s.Email,
                DecidedAt = s.DecidedAt,
                Signed    = s.Signed
            }).ToArray();

            if (request.WorkflowStartedAt == null)
            {
                Status = RequestStatus.Creating;
            }
            else if (request.WorkflowCompletedAt == null)
            {
                Status = RequestStatus.WaitingForSignatures;
            }
            else if (request.Signers.All(s => s.Signed))
            {
                Status = RequestStatus.Completed;
            }
            else
            {
                Status = RequestStatus.Failed;
            }

            WorkflowStatusResponse = await GetWorkflowStatusAsync(request);
        }
示例#11
0
        /// <summary>
        /// Create a signed certificate Create and return a signed certificate based on a registered root CA.
        /// </summary>
        /// <exception cref="DevOpsVault.SDK.Core.Client.ApiException">Thrown when fails to make API call</exception>
        /// <param name="body"> (optional)</param>
        /// <returns>Task of ApiResponse (ResponseCertificate)</returns>
        public async System.Threading.Tasks.Task <DevOpsVault.SDK.Core.Client.ApiResponse <ResponseCertificate> > SignCertificateAsyncWithHttpInfo(SigningRequest body = default(SigningRequest))
        {
            DevOpsVault.SDK.Core.Client.RequestOptions localVarRequestOptions = new DevOpsVault.SDK.Core.Client.RequestOptions();

            String[] _contentTypes = new String[] {
                "application/json"
            };

            // to determine the Accept header
            String[] _accepts = new String[] {
                "application/json"
            };

            foreach (var _contentType in _contentTypes)
            {
                localVarRequestOptions.HeaderParameters.Add("Content-Type", _contentType);
            }

            foreach (var _accept in _accepts)
            {
                localVarRequestOptions.HeaderParameters.Add("Accept", _accept);
            }

            localVarRequestOptions.Data = body;

            // authentication (Bearer) required
            if (!String.IsNullOrEmpty(this.Configuration.GetApiKeyWithPrefix("Authorization")))
            {
                localVarRequestOptions.HeaderParameters.Add("Authorization", this.Configuration.GetApiKeyWithPrefix("Authorization"));
            }

            // make the HTTP request

            var localVarResponse = await this.AsynchronousClient.PostAsync <ResponseCertificate>("/pki/sign", localVarRequestOptions, this.Configuration);

            if (this.ExceptionFactory != null)
            {
                Exception _exception = this.ExceptionFactory("SignCertificate", localVarResponse);
                if (_exception != null)
                {
                    throw _exception;
                }
            }

            return(localVarResponse);
        }
示例#12
0
        /// <summary>
        /// Create a signed certificate Create and return a signed certificate based on a registered root CA.
        /// </summary>
        /// <exception cref="DevOpsVault.SDK.Core.Client.ApiException">Thrown when fails to make API call</exception>
        /// <param name="body"> (optional)</param>
        /// <returns>Task of ResponseCertificate</returns>
        public async System.Threading.Tasks.Task <ResponseCertificate> SignCertificateAsync(SigningRequest body = default(SigningRequest))
        {
            DevOpsVault.SDK.Core.Client.ApiResponse <ResponseCertificate> localVarResponse = await SignCertificateAsyncWithHttpInfo(body);

            return(localVarResponse.Data);
        }
示例#13
0
        /// <summary>
        /// Create a signed certificate Create and return a signed certificate based on a registered root CA.
        /// </summary>
        /// <exception cref="DevOpsVault.SDK.Core.Client.ApiException">Thrown when fails to make API call</exception>
        /// <param name="body"> (optional)</param>
        /// <returns>ApiResponse of ResponseCertificate</returns>
        public DevOpsVault.SDK.Core.Client.ApiResponse <ResponseCertificate> SignCertificateWithHttpInfo(SigningRequest body = default(SigningRequest))
        {
            DevOpsVault.SDK.Core.Client.RequestOptions localVarRequestOptions = new DevOpsVault.SDK.Core.Client.RequestOptions();

            String[] _contentTypes = new String[] {
                "application/json"
            };

            // to determine the Accept header
            String[] _accepts = new String[] {
                "application/json"
            };

            var localVarContentType = DevOpsVault.SDK.Core.Client.ClientUtils.SelectHeaderContentType(_contentTypes);

            if (localVarContentType != null)
            {
                localVarRequestOptions.HeaderParameters.Add("Content-Type", localVarContentType);
            }

            var localVarAccept = DevOpsVault.SDK.Core.Client.ClientUtils.SelectHeaderAccept(_accepts);

            if (localVarAccept != null)
            {
                localVarRequestOptions.HeaderParameters.Add("Accept", localVarAccept);
            }

            localVarRequestOptions.Data = body;

            // authentication (Bearer) required
            if (!String.IsNullOrEmpty(this.Configuration.GetApiKeyWithPrefix("Authorization")))
            {
                localVarRequestOptions.HeaderParameters.Add("Authorization", this.Configuration.GetApiKeyWithPrefix("Authorization"));
            }

            // make the HTTP request
            var localVarResponse = this.Client.Post <ResponseCertificate>("/pki/sign", localVarRequestOptions, this.Configuration);

            if (this.ExceptionFactory != null)
            {
                Exception _exception = this.ExceptionFactory("SignCertificate", localVarResponse);
                if (_exception != null)
                {
                    throw _exception;
                }
            }

            return(localVarResponse);
        }
示例#14
0
 /// <summary>
 /// Create a signed certificate Create and return a signed certificate based on a registered root CA.
 /// </summary>
 /// <exception cref="DevOpsVault.SDK.Core.Client.ApiException">Thrown when fails to make API call</exception>
 /// <param name="body"> (optional)</param>
 /// <returns>ResponseCertificate</returns>
 public ResponseCertificate SignCertificate(SigningRequest body = default(SigningRequest))
 {
     DevOpsVault.SDK.Core.Client.ApiResponse <ResponseCertificate> localVarResponse = SignCertificateWithHttpInfo(body);
     return(localVarResponse.Data);
 }
        public IActionResult SignData([FromBody] SigningRequest request)
        {
            _logger.LogDebug($"Calling POST /generateDigest endpoint ");
            if (request == null)
            {
                return(BadRequest());
            }

            _logger.LogDebug($"Calling POST /generateDigest endpoint ");
            try
            {
                request.DataToSign = DecodeBase64(request.DataToSign);
            }
            catch (Exception ex)
            {
                _logger.LogError($"Error decoding data to sign", ex);
                return(BadRequest("Error decoding data to sign, check base64 encoding"));
            }
            if (request.Algorithm == SigningAlgoritm.SHA256WITHRSA)
            {
                var bytes     = Encoding.UTF8.GetBytes(request.DataToSign ?? request.Digest.Replace("SHA-256=", ""));
                var signBytes = Sha256Helper.SignData(request.PrivateKey, bytes);
                var signature = Convert.ToBase64String(signBytes);
                var testValid = Sha256Helper.VerifyData(request.Certificate, bytes, signBytes);

                var response = new SigningResponse()
                {
                    Algorithm = Enum.GetName(typeof(SigningAlgoritm),
                                             request.Algorithm),
                    Headers              = "digest tpp-transaction - id tpp - request - id timestamp psu-id",
                    KeyId                = request.KeyID,
                    Signature            = signature,
                    CertificateAuthority = "CA",
                    IsValid              = testValid
                };


                return(Ok(response));
            }
            else if (request.Algorithm == SigningAlgoritm.SHA512WITHRSA)
            {
                var bytes     = Encoding.UTF8.GetBytes(request.DataToSign ?? request.Digest.Replace("SHA-512=", ""));
                var signBytes = Sha512Helper.SignData(request.PrivateKey, bytes);
                var signature = Convert.ToBase64String(signBytes);
                var testValid = Sha512Helper.VerifyData(request.Certificate, bytes, signBytes);
                var response  = new SigningResponse()
                {
                    Algorithm            = GetEnumDescription(request.Algorithm),
                    Headers              = "digest tpp-transaction - id tpp - request - id timestamp psu-id",
                    KeyId                = request.KeyID,
                    Signature            = signature,
                    CertificateAuthority = "CA",
                    IsValid              = testValid
                };
                return(Ok(response));
            }
            else
            {
                return(BadRequest($"Unsupported signing algoritm {request.Algorithm}"));
            }
        }