Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 89 additions & 11 deletions proto/wsscan/abstractserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ func (srv *AbstractServer) ServeHTTP(w http.ResponseWriter, rq *http.Request) {
case *GetActiveJobsRequest:
rsp, err = srv.handleGetActiveJobsRequest(query, body)

case *GetJobElementsRequest:
rsp, err = srv.handleGetJobElementsRequest(query, body)

case *GetJobHistoryRequest:
rsp, err = srv.handleGetJobHistoryRequest(query, body)

Expand All @@ -133,9 +136,9 @@ func (srv *AbstractServer) handleGetScannerElementsRequest(
req *GetScannerElementsRequest,
) (Body, error) {

// Build ElementData for each requested element, skipping duplicates.
var elements []ElementData
seen := generic.NewSet[ScannerRequestedElement]()
// Build ScannerElemData for each requested element, skipping duplicates.
var elements []ScannerElemData
seen := generic.NewSet[ScannerElemName]()

for _, re := range req.RequestedElements {
if !seen.TestAndAdd(re) {
Expand All @@ -146,25 +149,25 @@ func (srv *AbstractServer) handleGetScannerElementsRequest(
req := srv.caps.DefaultRequest()
if req != nil {
ticket := fromAbstractScannerRequest(req)
elements = append(elements, ElementData{
Name: ElementDataDefaultScanTicket,
elements = append(elements, ScannerElemData{
Name: ScannerElemDefaultScanTicket,
Valid: BooleanElement("true"),
DefaultScanTicket: optional.New(ticket),
})
}

case ScannerElemDescription:
desc := fromAbstractScannerDescription(srv.caps)
elements = append(elements, ElementData{
Name: ElementDataScannerDescription,
elements = append(elements, ScannerElemData{
Name: ScannerElemDescription,
Valid: BooleanElement("true"),
ScannerDescription: optional.New(desc),
})

case ScannerElemConfiguration:
conf := fromAbstractScannerConfiguration(srv.caps)
elements = append(elements, ElementData{
Name: ElementDataScannerConfiguration,
elements = append(elements, ScannerElemData{
Name: ScannerElemConfiguration,
Valid: BooleanElement("true"),
ScannerConfiguration: optional.New(conf),
})
Expand All @@ -174,8 +177,8 @@ func (srv *AbstractServer) handleGetScannerElementsRequest(
status := srv.status
srv.lock.Unlock()
status.ScannerCurrentTime = time.Now()
elements = append(elements, ElementData{
Name: ElementDataScannerStatus,
elements = append(elements, ScannerElemData{
Name: ScannerElemStatus,
Valid: BooleanElement("true"),
ScannerStatus: optional.New(status),
})
Expand All @@ -187,6 +190,81 @@ func (srv *AbstractServer) handleGetScannerElementsRequest(
}, nil
}

// handleGetJobElementsRequest handles GetJobElements requests.
// It returns the requested job schema elements for the job identified
// by JobID.
func (srv *AbstractServer) handleGetJobElementsRequest(
query *transport.ServerQuery,
req *GetJobElementsRequest,
) (Body, error) {

srv.lock.Lock()
job := srv.jobs.get(req.JobID)
if job == nil {
srv.lock.Unlock()
query.Reject(http.StatusNotFound, nil)
return nil, errInvalidJob
}
j := *job
srv.lock.Unlock()

var elements []JobElemData
seen := generic.NewSet[JobElemName]()

for _, re := range req.RequestedElements {
if !seen.TestAndAdd(re) {
continue
}
switch re {
case JobElemStatus:
elements = append(elements, JobElemData{
Name: JobElemStatus,
Valid: BooleanElement("true"),
JobStatus: optional.New(jobStatusFrom(j)),
})

case JobElemScanTicket:
elements = append(elements, JobElemData{
Name: JobElemScanTicket,
Valid: BooleanElement("true"),
ScanTicket: optional.New(j.scanTicket),
})

case JobElemDocuments:
docs := Documents{}
if j.scanTicket.DocumentParameters != nil {
docs.DocumentFinalParameters =
optional.Get(j.scanTicket.DocumentParameters)
}
elements = append(elements, JobElemData{
Name: JobElemDocuments,
Valid: BooleanElement("true"),
Documents: optional.New(docs),
})
}
}

return &GetJobElementsResponse{
JobElements: elements,
}, nil
}

// jobStatusFrom builds a [JobStatus] from a [jobInfo].
func jobStatusFrom(j jobInfo) JobStatus {
js := JobStatus{
JobID: j.jobID,
JobState: j.state,
ScansCompleted: j.scansCompleted,
}
if !j.createdTime.IsZero() {
js.JobCreatedTime = optional.New(j.createdTime)
}
if !j.completedTime.IsZero() {
js.JobCompletedTime = optional.New(j.completedTime)
}
return js
}

// handleCreateScanJobRequest handles CreateScanJob requests.
func (srv *AbstractServer) handleCreateScanJobRequest(
query *transport.ServerQuery,
Expand Down
28 changes: 27 additions & 1 deletion proto/wsscan/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func NewClient(u *url.URL, tr *transport.Transport) *Client {
// from the WS-Scan server.
func (c *Client) GetScannerElements(
ctx context.Context,
elements ...ScannerRequestedElement,
elements ...ScannerElemName,
) (*GetScannerElementsResponse, error) {

req := GetScannerElementsRequest{RequestedElements: elements}
Expand All @@ -61,6 +61,32 @@ func (c *Client) GetScannerElements(
return rsp, nil
}

// GetJobElements requests the specified job schema elements for the
// job identified by jobID from the WS-Scan server.
func (c *Client) GetJobElements(
ctx context.Context,
jobID int,
elements ...JobElemName,
) (*GetJobElementsResponse, error) {

req := GetJobElementsRequest{
JobID: jobID,
RequestedElements: elements,
}
msg, err := c.sendSOAP(ctx, &req)
if err != nil {
return nil, err
}

rsp, ok := msg.Body.(*GetJobElementsResponse)
if !ok {
return nil,
fmt.Errorf("wsscan: unexpected response type %T", msg.Body)
}

return rsp, nil
}

// sendSOAP wraps body in a SOAP envelope, POSTs it to the server,
// and returns the decoded response [Message].
func (c *Client) sendSOAP(ctx context.Context, body Body) (Message, error) {
Expand Down
187 changes: 0 additions & 187 deletions proto/wsscan/elementdata.go

This file was deleted.

Loading