an updated and hopefully faster version of the ST Toolbox
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

210 lines
7.0 KiB

package api
import (
"encoding/json"
"fmt"
"io"
"log"
"net/http"
)
// GetJobPaperwork retrieves a list of paperwork for a specific job
// This is a specialized endpoint to directly access paperwork
func (s *Session) GetJobPaperwork(jobID string) ([]map[string]interface{}, error) {
log.Printf("GetJobPaperwork: Fetching paperwork for job %s", jobID)
url := fmt.Sprintf("%s/job/%s/paperwork", BaseURL, jobID)
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, fmt.Errorf("error creating request: %v", err)
}
// Add authorization header
req.Header.Set("Cookie", s.Cookie)
// Set headers for better compatibility
req.Header.Set("Accept", "application/json")
req.Header.Set("Content-Type", "application/json")
// Send the request
log.Printf("GetJobPaperwork: Sending request to %s", url)
resp, err := s.Client.Do(req)
if err != nil {
return nil, fmt.Errorf("error sending request: %v", err)
}
defer resp.Body.Close()
// Read the full response body
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("error reading response body: %v", err)
}
// Check for errors
if resp.StatusCode != http.StatusOK {
// Log detailed error information
log.Printf("GetJobPaperwork: API returned error %d for job %s", resp.StatusCode, jobID)
log.Printf("GetJobPaperwork: Error response: %s", string(body))
return nil, fmt.Errorf("API returned error: %s - %s", resp.Status, string(body))
}
// Log response preview
responsePreview := string(body)
if len(responsePreview) > 200 {
responsePreview = responsePreview[:200] + "... [truncated]"
}
log.Printf("GetJobPaperwork: Response preview for job %s: %s", jobID, responsePreview)
// Parse the response into a generic map
var result map[string]interface{}
if err := json.Unmarshal(body, &result); err != nil {
return nil, fmt.Errorf("error parsing response: %v", err)
}
// Debug the response structure
keys := make([]string, 0)
for k := range result {
keys = append(keys, k)
}
log.Printf("GetJobPaperwork: Response root keys for job %s: %v", jobID, keys)
// Check for data.attachments format (which is what the logs show)
paperworkItems := make([]map[string]interface{}, 0)
// Check if data key exists
if data, ok := result["data"].(map[string]interface{}); ok {
dataKeys := make([]string, 0)
for k := range data {
dataKeys = append(dataKeys, k)
}
log.Printf("GetJobPaperwork: Data keys for job %s: %v", jobID, dataKeys)
// Look for the attachments array in data
if attachments, ok := data["attachments"].([]interface{}); ok && len(attachments) > 0 {
log.Printf("GetJobPaperwork: Found %d attachments in data.attachments for job %s",
len(attachments), jobID)
// Convert each attachment to a map and add to our collection
for _, attachment := range attachments {
if attachmentMap, ok := attachment.(map[string]interface{}); ok {
// Log the structure of the first attachment to better understand format
if len(paperworkItems) == 0 {
log.Printf("GetJobPaperwork: First attachment structure: %+v", attachmentMap)
}
paperworkItems = append(paperworkItems, attachmentMap)
}
}
return paperworkItems, nil
}
// Check for objects in data
if objects, ok := data["objects"].([]interface{}); ok && len(objects) > 0 {
log.Printf("GetJobPaperwork: Found %d items in data.objects for job %s", len(objects), jobID)
for _, obj := range objects {
if objMap, ok := obj.(map[string]interface{}); ok {
paperworkItems = append(paperworkItems, objMap)
}
}
}
// Check for paperwork array in data
if paperwork, ok := data["paperwork"].([]interface{}); ok && len(paperwork) > 0 {
log.Printf("GetJobPaperwork: Found %d items in data.paperwork for job %s", len(paperwork), jobID)
for _, doc := range paperwork {
if docMap, ok := doc.(map[string]interface{}); ok {
paperworkItems = append(paperworkItems, docMap)
}
}
}
}
// Also try the old formats
// Check for objects at root level
if objects, ok := result["objects"].([]interface{}); ok && len(objects) > 0 {
log.Printf("GetJobPaperwork: Found %d items at root.objects for job %s", len(objects), jobID)
for _, obj := range objects {
if objMap, ok := obj.(map[string]interface{}); ok {
paperworkItems = append(paperworkItems, objMap)
}
}
}
if len(paperworkItems) > 0 {
log.Printf("GetJobPaperwork: Extracted %d total paperwork items from response for job %s",
len(paperworkItems), jobID)
return paperworkItems, nil
}
log.Printf("GetJobPaperwork: No paperwork items found in any format for job %s", jobID)
return nil, nil
}
// CheckJobPermissions verifies if the current user has permissions to access the specified job
func (s *Session) CheckJobPermissions(jobID string) (bool, string, error) {
log.Printf("CheckJobPermissions: Checking permissions for job %s", jobID)
// First try to get the job details - if this succeeds, the user has basic read access
url := fmt.Sprintf("%s/job/%s", BaseURL, jobID)
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return false, "Error creating request", err
}
req.Header.Set("Cookie", s.Cookie)
resp, err := s.Client.Do(req)
if err != nil {
return false, "Error sending request", err
}
defer resp.Body.Close()
// Read response for detailed error information
body, _ := io.ReadAll(resp.Body)
// If we can't get the job, check the specific error
if resp.StatusCode != http.StatusOK {
errorMessage := string(body)
// Check for permission-related errors
if resp.StatusCode == http.StatusForbidden || resp.StatusCode == http.StatusUnauthorized {
log.Printf("CheckJobPermissions: Permission denied for job %s: %s", jobID, errorMessage)
return false, fmt.Sprintf("Permission denied: %s", resp.Status), nil
}
// Check for job not found
if resp.StatusCode == http.StatusNotFound {
log.Printf("CheckJobPermissions: Job %s not found: %s", jobID, errorMessage)
return false, "Job not found", nil
}
// Other errors
log.Printf("CheckJobPermissions: Error accessing job %s: %s - %s", jobID, resp.Status, errorMessage)
return false, fmt.Sprintf("Error: %s", resp.Status), nil
}
// If we get here, the user can at least view the job
// Now try to check if they can access paperwork
paperworkURL := fmt.Sprintf("%s/job/%s/paperwork", BaseURL, jobID)
paperworkReq, err := http.NewRequest("GET", paperworkURL, nil)
if err != nil {
return true, "Can access job, but error checking paperwork permissions", err
}
paperworkReq.Header.Set("Cookie", s.Cookie)
paperworkResp, err := s.Client.Do(paperworkReq)
if err != nil {
return true, "Can access job, but error checking paperwork API", err
}
defer paperworkResp.Body.Close()
if paperworkResp.StatusCode != http.StatusOK {
log.Printf("CheckJobPermissions: User can access job %s but paperwork API returned %d",
jobID, paperworkResp.StatusCode)
return true, "Can access job, but paperwork access denied", nil
}
log.Printf("CheckJobPermissions: User has full access to job %s and its paperwork", jobID)
return true, "Full access", nil
}