-
Notifications
You must be signed in to change notification settings - Fork 15
/
api.go
113 lines (103 loc) · 4.62 KB
/
api.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package server
import (
"encoding/json"
"io"
"net/http"
"time"
"github.com/ashirt-ops/ashirt-server/backend"
"github.com/ashirt-ops/ashirt-server/backend/contentstore"
"github.com/ashirt-ops/ashirt-server/backend/database"
"github.com/ashirt-ops/ashirt-server/backend/dtos"
"github.com/ashirt-ops/ashirt-server/backend/logging"
"github.com/ashirt-ops/ashirt-server/backend/server/middleware"
"github.com/ashirt-ops/ashirt-server/backend/services"
"github.com/go-chi/chi/v5"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
func API(r chi.Router, db *database.Connection, contentStore contentstore.Store, logger logging.Logger) {
r.Handle("/metrics", promhttp.Handler())
r.Group(func(r chi.Router) {
r.Use(middleware.AuthenticateAppAndInjectCtx(db))
r.Use(middleware.LogRequests(logger))
bindSharedRoutes(r, db, contentStore)
bindAPIRoutes(r, db, contentStore)
})
}
func bindAPIRoutes(r chi.Router, db *database.Connection, contentStore contentstore.Store) {
route(r, "GET", "/checkconnection", jsonHandler(func(r *http.Request) (interface{}, error) {
return dtos.CheckConnection{Ok: true}, nil
}))
route(r, "GET", "/operations/{operation_slug}/evidence/{evidence_uuid}/{type:media|preview}", mediaHandler(func(r *http.Request) (io.Reader, error) {
dr := dissectNoBodyRequest(r)
i := services.ReadEvidenceInput{
EvidenceUUID: dr.FromURL("evidence_uuid").Required().AsString(),
OperationSlug: dr.FromURL("operation_slug").Required().AsString(),
LoadPreview: dr.FromURL("type").AsString() == "preview",
LoadMedia: dr.FromURL("type").AsString() == "media",
}
evidence, err := services.ReadEvidence(r.Context(), db, contentStore, i)
if err != nil {
return nil, backend.WrapError("Unable to read evidence", err)
}
if i.LoadPreview {
return evidence.Preview, nil
}
return evidence.Media, nil
}))
route(r, "POST", "/operations/{operation_slug}/evidence", jsonHandler(func(r *http.Request) (interface{}, error) {
dr := dissectFormRequest(r)
i := services.CreateEvidenceInput{
Description: dr.FromBody("notes").Required().AsString(),
Content: dr.FromFile("file"),
ContentType: dr.FromBody("contentType").OrDefault("image").AsString(),
OccurredAt: dr.FromBody("occurred_at").OrDefault(time.Now()).AsUnixTime(),
OperationSlug: dr.FromURL("operation_slug").Required().AsString(),
AdjustedAt: dr.FromBody("adjusted_at").OrDefault(nil).AsTimePtr(),
}
tagIDsJSON := dr.FromBody("tagIds").OrDefault("[]").AsString()
if dr.Error != nil {
return nil, dr.Error
}
if err := json.Unmarshal([]byte(tagIDsJSON), &i.TagIDs); err != nil {
return nil, backend.BadInputErr(err, "tagIds must be a json array of ints")
}
return services.CreateEvidence(r.Context(), db, contentStore, i)
}))
route(r, "PUT", "/operations/{operation_slug}/evidence/{evidence_uuid}", jsonHandler(func(r *http.Request) (interface{}, error) {
dr := dissectFormRequest(r)
i := services.UpdateEvidenceInput{
EvidenceUUID: dr.FromURL("evidence_uuid").Required().AsString(),
OperationSlug: dr.FromURL("operation_slug").Required().AsString(),
AdjustedAt: dr.FromBody("adjusted_at").OrDefault(nil).AsTimePtr(),
Description: dr.FromBody("notes").AsStringPtr(),
Content: dr.FromFile("file"),
}
tagsToAddJSON := dr.FromBody("tagsToAdd").OrDefault("[]").AsString()
tagsToRemoveJSON := dr.FromBody("tagsToRemove").OrDefault("[]").AsString()
if dr.Error != nil {
return nil, dr.Error
}
if err := json.Unmarshal([]byte(tagsToAddJSON), &i.TagsToAdd); err != nil {
return nil, backend.BadInputErr(err, "tagsToAdd must be a json array of ints")
}
if err := json.Unmarshal([]byte(tagsToRemoveJSON), &i.TagsToRemove); err != nil {
return nil, backend.BadInputErr(err, "tagsToRemove must be a json array of ints")
}
return nil, services.UpdateEvidence(r.Context(), db, contentStore, i)
}))
route(r, "PUT", "/operations/{operation_slug}/evidence/{evidence_uuid}/metadata", jsonHandler(func(r *http.Request) (interface{}, error) {
dr := dissectJSONRequest(r)
i := services.UpsertEvidenceMetadataInput{
EditEvidenceMetadataInput: services.EditEvidenceMetadataInput{
OperationSlug: dr.FromURL("operation_slug").Required().AsString(),
EvidenceUUID: dr.FromURL("evidence_uuid").Required().AsString(),
Source: dr.FromBody("source").Required().AsString(),
Body: dr.FromBody("body").Required().AsString(),
},
Status: dr.FromBody("status").Required().AsString(),
Message: dr.FromBody("message").AsStringPtr(),
CanProcess: dr.FromBody("canProcess").AsBoolPtr(),
}
return nil, services.UpsertEvidenceMetadata(r.Context(), db, i)
}))
}