segregated api machinery
This commit is contained in:
parent
5571401103
commit
86f304e1b8
@ -1,4 +1,4 @@
|
|||||||
package server
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/hmac"
|
"crypto/hmac"
|
||||||
@ -8,63 +8,63 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type APICommand struct {
|
type Command struct {
|
||||||
Expires time.Time `json:"exp"`
|
Expires time.Time `json:"exp"`
|
||||||
Command string `json:"cmd"`
|
Command string `json:"cmd"`
|
||||||
Scheme string `json:"sch"`
|
Scheme string `json:"sch"`
|
||||||
Signature []byte `json:"sig,omitempty"`
|
Signature []byte `json:"sig,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseAPICommand(jsn []byte) (*APICommand, error) {
|
func ParseCommand(jsn []byte) (*Command, error) {
|
||||||
api := &APICommand{}
|
cmd := &Command{}
|
||||||
err := json.Unmarshal(jsn, api)
|
err := json.Unmarshal(jsn, cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return api, nil
|
return cmd, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ac *APICommand) JSON() ([]byte, error) {
|
func (c *Command) JSON() ([]byte, error) {
|
||||||
return json.Marshal(ac)
|
return json.Marshal(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ac *APICommand) Sign(key []byte) error {
|
func (c *Command) Sign(key []byte) error {
|
||||||
switch ac.Scheme {
|
switch c.Scheme {
|
||||||
case "hmac-sha256":
|
case "hmac-sha256":
|
||||||
j, err := ac.JSON()
|
j, err := c.JSON()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("json encoding error")
|
return fmt.Errorf("json encoding error")
|
||||||
}
|
}
|
||||||
|
|
||||||
mac := hmac.New(sha256.New, key)
|
mac := hmac.New(sha256.New, key)
|
||||||
mac.Write(j)
|
mac.Write(j)
|
||||||
ac.Signature = mac.Sum(nil)
|
c.Signature = mac.Sum(nil)
|
||||||
|
|
||||||
case "":
|
case "":
|
||||||
return fmt.Errorf("scheme may not be empty")
|
return fmt.Errorf("scheme may not be empty")
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("unsupported scheme: %s", ac.Scheme)
|
return fmt.Errorf("unsupported scheme: %s", c.Scheme)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ac *APICommand) Validate(key []byte) error {
|
func (c *Command) Validate(key []byte) error {
|
||||||
cpy := &APICommand{
|
cpy := &Command{
|
||||||
Expires: ac.Expires,
|
Expires: c.Expires,
|
||||||
Command: ac.Command,
|
Command: c.Command,
|
||||||
Scheme: ac.Scheme,
|
Scheme: c.Scheme,
|
||||||
}
|
}
|
||||||
err := cpy.Sign(key)
|
err := cpy.Sign(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !hmac.Equal(cpy.Signature, ac.Signature) {
|
if !hmac.Equal(cpy.Signature, c.Signature) {
|
||||||
return fmt.Errorf("invalid signature")
|
return fmt.Errorf("invalid signature")
|
||||||
}
|
}
|
||||||
|
|
||||||
if time.Now().After(ac.Expires) {
|
if time.Now().After(c.Expires) {
|
||||||
return fmt.Errorf("command expired")
|
return fmt.Errorf("command expired")
|
||||||
}
|
}
|
||||||
|
|
@ -3,6 +3,7 @@ package server
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"git.binarythought.com/cdramey/alrm/api"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
@ -14,7 +15,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
http.Error(w, "no command given", http.StatusBadRequest)
|
http.Error(w, "no command given", http.StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cmd, err := ParseAPICommand([]byte(c))
|
cmd, err := api.ParseCommand([]byte(c))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, fmt.Sprintf("error parsing command: %s", err.Error()),
|
http.Error(w, fmt.Sprintf("error parsing command: %s", err.Error()),
|
||||||
http.StatusBadRequest)
|
http.StatusBadRequest)
|
||||||
|
Loading…
Reference in New Issue
Block a user