Skip to content

Commit 7dc1b21

Browse files
committed
Assignment validation endpoint
1 parent 3a6fb9f commit 7dc1b21

File tree

4 files changed

+110
-0
lines changed

4 files changed

+110
-0
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package assignmentvalidator
2+
3+
import (
4+
"context"
5+
6+
"github.com/gemsorg/assignment/pkg/apierror"
7+
"github.com/gemsorg/assignment/pkg/assignment"
8+
"github.com/gemsorg/assignment/pkg/authentication"
9+
ds "github.com/gemsorg/assignment/pkg/datastore"
10+
"github.com/gemsorg/assignment/pkg/service"
11+
"github.com/go-kit/kit/endpoint"
12+
)
13+
14+
type AssignmentValidatorResponse struct {
15+
Valid bool `json:"valid"`
16+
Reason string `json:"reason"`
17+
}
18+
19+
func makeAssignmentValidatorEndpoint(svc service.AssignmentService) endpoint.Endpoint {
20+
return func(ctx context.Context, request interface{}) (interface{}, error) {
21+
res := AssignmentValidatorResponse{}
22+
data, _ := authentication.ParseAuthData(ctx)
23+
svc.SetAuthData(data)
24+
25+
req := request.(assignment.NewAssignment)
26+
settings, err := svc.GetSettings(req.JobID)
27+
if err != nil {
28+
if _, ok := err.(ds.NoRowErr); !ok {
29+
return nil, errorResponse(err)
30+
}
31+
}
32+
33+
valid, err := svc.ValidateAssignment(req, settings)
34+
if err != nil {
35+
res.Reason = err.Error()
36+
}
37+
res.Valid = valid
38+
39+
return res, nil
40+
}
41+
}
42+
43+
func errorResponse(err error) *apierror.APIError {
44+
return apierror.New(500, err.Error(), err)
45+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package assignmentvalidator
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"net/http"
7+
8+
"github.com/gemsorg/assignment/pkg/apierror"
9+
"github.com/gemsorg/assignment/pkg/assignment"
10+
"github.com/gemsorg/assignment/pkg/service"
11+
kithttp "github.com/go-kit/kit/transport/http"
12+
)
13+
14+
func MakeHandler(s service.AssignmentService) http.Handler {
15+
return kithttp.NewServer(
16+
makeAssignmentValidatorEndpoint(s),
17+
decodeNewAssignmentValidatorRequest,
18+
encodeResponse,
19+
)
20+
}
21+
22+
func encodeResponse(ctx context.Context, w http.ResponseWriter, response interface{}) error {
23+
w.Header().Set("Content-Type", "application/json; charset=utf-8")
24+
return json.NewEncoder(w).Encode(response)
25+
}
26+
27+
func decodeNewAssignmentValidatorRequest(_ context.Context, r *http.Request) (interface{}, error) {
28+
var a assignment.NewAssignment
29+
decoder := json.NewDecoder(r.Body)
30+
err := decoder.Decode(&a)
31+
if err != nil {
32+
return nil, apierror.New(500, err.Error(), err)
33+
}
34+
return a, nil
35+
}

pkg/server/server.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"github.com/gemsorg/assignment/pkg/api/assignmentdestroyer"
88
"github.com/gemsorg/assignment/pkg/api/assignmentfetcher"
99
"github.com/gemsorg/assignment/pkg/api/assignmentupdater"
10+
"github.com/gemsorg/assignment/pkg/api/assignmentvalidator"
1011
"github.com/gemsorg/assignment/pkg/api/settingcreator"
1112
"github.com/gemsorg/assignment/pkg/api/settingfetcher"
1213

@@ -33,6 +34,7 @@ func New(
3334
r.Handle("/assignments", assignmentupdater.MakeHandler(s)).Methods("PATCH")
3435
r.Handle("/settings/{job_id}", settingfetcher.MakeHandler(s)).Methods("GET")
3536
r.Handle("/settings", settingcreator.MakeHandler(s)).Methods("PUT")
37+
r.Handle("/validate", assignmentvalidator.MakeHandler(s)).Methods("GET")
3638
r.Use(authentication.AuthMiddleware)
3739
return withHandlers(r)
3840
}

pkg/service/service.go

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ type AssignmentService interface {
2020
UpdateAssignment(workerID, jobID, responseID uint64, status string) (bool, error)
2121
CreateSettings(assignment.Settings) (*assignment.Settings, error)
2222
GetStore() datastore.Storage
23+
ValidateAssignment(a assignment.NewAssignment, set *assignment.Settings) (bool, error)
2324
}
2425

2526
type service struct {
@@ -108,3 +109,30 @@ func (s *service) UpdateAssignment(workerID, jobID, responseID uint64, status st
108109
func (s *service) CreateSettings(set assignment.Settings) (*assignment.Settings, error) {
109110
return s.store.CreateSettings(set)
110111
}
112+
113+
func (s *service) ValidateAssignment(a assignment.NewAssignment, set *assignment.Settings) (bool, error) {
114+
allowed := true
115+
if set == nil {
116+
return allowed, nil
117+
}
118+
119+
// if job has a whitelist, check if worker is part of it
120+
if set.Whitelist {
121+
wl, err := s.store.GetWhitelist(a.JobID, a.WorkerID)
122+
if wl == nil || err != nil {
123+
return false, assignment.WorkerNotWhitelisted{}
124+
}
125+
}
126+
127+
// Get worker's assignment for this job
128+
assigned, err := s.store.WorkerAlreadyAssigned(a.JobID, a.WorkerID)
129+
a.WorkerAlreadyAssigned = assigned
130+
131+
// Check if the assignment is allowed
132+
allowed, err = a.IsAllowed(set)
133+
if !allowed {
134+
return false, err
135+
}
136+
137+
return allowed, nil
138+
}

0 commit comments

Comments
 (0)