token-validator: handle remote-validator authentication + new student features
This commit is contained in:
parent
0fbe142626
commit
fa45457bb7
@ -1,11 +1,16 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha512"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/julienschmidt/httprouter"
|
||||
)
|
||||
@ -18,6 +23,21 @@ func Router() *httprouter.Router {
|
||||
|
||||
type DispatchFunction func(httprouter.Params, []byte) (interface{}, error)
|
||||
|
||||
func remoteValidatorHandler(f func(http.ResponseWriter, *http.Request, httprouter.Params)) func(http.ResponseWriter, *http.Request, httprouter.Params) {
|
||||
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
expectedMAC := hmac.New(sha512.New, []byte(sharedSecret)).Sum([]byte(fmt.Sprintf("%d", time.Now().Unix()/10)))
|
||||
previousMAC := hmac.New(sha512.New, []byte(sharedSecret)).Sum([]byte(fmt.Sprintf("%d", time.Now().Unix()/10-1)))
|
||||
|
||||
if aauth, err := base64.StdEncoding.DecodeString(r.Header.Get("X-ADLIN-Authentication")); err != nil {
|
||||
http.Error(w, fmt.Sprintf("{\"errmsg\":%q}", err), http.StatusUnauthorized)
|
||||
} else if !hmac.Equal(expectedMAC, aauth) && !hmac.Equal(previousMAC, aauth) {
|
||||
http.Error(w, fmt.Sprintf("{\"errmsg\":%q}", "Bad authentication header"), http.StatusUnauthorized)
|
||||
} else {
|
||||
f(w, r, ps)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func apiHandler(f DispatchFunction) func(http.ResponseWriter, *http.Request, httprouter.Params) {
|
||||
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||
if addr := r.Header.Get("X-Forwarded-For"); addr != "" {
|
||||
@ -78,3 +98,19 @@ func apiHandler(f DispatchFunction) func(http.ResponseWriter, *http.Request, htt
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func studentHandler(f func(Student, []byte) (interface{}, error)) func(httprouter.Params, []byte) (interface{}, error) {
|
||||
return func(ps httprouter.Params, body []byte) (interface{}, error) {
|
||||
if sid, err := strconv.Atoi(string(ps.ByName("sid"))); err != nil {
|
||||
if student, err := getStudentByLogin(ps.ByName("sid")); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return f(student, body)
|
||||
}
|
||||
} else if student, err := getStudent(sid); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
return f(student, body)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,14 @@ func init() {
|
||||
router.GET("/api/students/", apiHandler(
|
||||
func(httprouter.Params,[]byte) (interface{}, error) {
|
||||
return getStudents() }))
|
||||
router.POST("/api/students/", apiHandler(createStudent))
|
||||
router.POST("/api/students/", remoteValidatorHandler(apiHandler(createStudent)))
|
||||
router.GET("/api/students/:sid/", apiHandler(studentHandler(
|
||||
func(std Student, _ []byte) (interface{}, error) {
|
||||
return std, nil })))
|
||||
router.PUT("/api/students/:sid/", remoteValidatorHandler(apiHandler(studentHandler(updateStudent))))
|
||||
router.DELETE("/api/students/:sid/", remoteValidatorHandler(apiHandler(studentHandler(
|
||||
func(std Student, _ []byte) (interface{}, error) {
|
||||
return std.Delete() }))))
|
||||
}
|
||||
|
||||
|
||||
@ -43,11 +50,16 @@ func getStudents() (students []Student, err error) {
|
||||
}
|
||||
}
|
||||
|
||||
func getStudent(id int64) (s Student, err error) {
|
||||
func getStudent(id int) (s Student, err error) {
|
||||
err = DBQueryRow("SELECT id_student, login, time FROM students WHERE id_student=?", id).Scan(&s.Id, &s.Login, &s.Time)
|
||||
return
|
||||
}
|
||||
|
||||
func getStudentByLogin(login string) (s Student, err error) {
|
||||
err = DBQueryRow("SELECT id_student, login, time FROM students WHERE login=?", login).Scan(&s.Id, &s.Login, &s.Time)
|
||||
return
|
||||
}
|
||||
|
||||
func NewStudent(login string) (Student, error) {
|
||||
if res, err := DBExec("INSERT INTO students (login, time) VALUES (?, ?)", login, time.Now()); err != nil {
|
||||
return Student{}, err
|
||||
@ -97,3 +109,14 @@ func createStudent(_ httprouter.Params, body []byte) (interface{}, error) {
|
||||
|
||||
return NewStudent(strings.TrimSpace(std.Login))
|
||||
}
|
||||
|
||||
func updateStudent(current Student, body []byte) (interface{}, error) {
|
||||
var new Student
|
||||
if err := json.Unmarshal(body, &new); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
current.Login = new.Login
|
||||
current.Time = new.Time
|
||||
return current.Update()
|
||||
}
|
||||
|
Reference in New Issue
Block a user