2018-02-20 12:49:03 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
2018-02-22 05:48:48 +00:00
|
|
|
"fmt"
|
2020-02-27 14:26:57 +00:00
|
|
|
"log"
|
2021-02-20 18:13:33 +00:00
|
|
|
"net"
|
2018-02-20 12:49:03 +00:00
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/julienschmidt/httprouter"
|
2020-03-27 13:57:14 +00:00
|
|
|
|
2021-10-31 15:43:43 +00:00
|
|
|
"git.nemunai.re/srs/adlin/libadlin"
|
2018-02-20 12:49:03 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func init() {
|
2020-02-27 14:26:57 +00:00
|
|
|
router.GET("/api/progress", apiHandler(
|
2018-02-22 03:47:57 +00:00
|
|
|
func(httprouter.Params, []byte) (interface{}, error) {
|
2020-03-27 13:57:14 +00:00
|
|
|
if stds, err := adlin.GetStudents(); err != nil {
|
2018-02-22 03:47:57 +00:00
|
|
|
return nil, err
|
|
|
|
} else {
|
2021-03-07 11:39:38 +00:00
|
|
|
ret := map[string]map[string]*adlin.UnlockedChallenge{}
|
2018-02-22 03:47:57 +00:00
|
|
|
for _, std := range stds {
|
2020-03-27 13:57:14 +00:00
|
|
|
if sts, err := std.GetStates(); err == nil {
|
2021-03-07 11:39:38 +00:00
|
|
|
ret[std.Login] = map[string]*adlin.UnlockedChallenge{}
|
2018-02-22 05:48:48 +00:00
|
|
|
|
|
|
|
for _, s := range sts {
|
|
|
|
ret[std.Login][fmt.Sprintf("%d", s.Challenge)] = s
|
|
|
|
}
|
2020-02-27 14:26:57 +00:00
|
|
|
|
2020-03-27 13:57:14 +00:00
|
|
|
if pongs, err := std.LastPongs(); err == nil && len(pongs) > 0 {
|
2021-03-07 11:39:38 +00:00
|
|
|
ret[std.Login]["ping"] = &adlin.UnlockedChallenge{
|
2020-02-27 14:26:57 +00:00
|
|
|
IdStudent: std.Id,
|
2021-03-07 11:39:38 +00:00
|
|
|
Time: &pongs[0].Date,
|
2020-03-27 13:57:14 +00:00
|
|
|
Value: pongs[0].State,
|
2020-02-27 14:26:57 +00:00
|
|
|
}
|
|
|
|
} else if err != nil {
|
|
|
|
log.Println(err)
|
|
|
|
}
|
2018-02-22 03:47:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return ret, nil
|
|
|
|
}
|
|
|
|
}))
|
2018-02-20 12:49:03 +00:00
|
|
|
router.GET("/api/students/", apiHandler(
|
2018-02-20 17:20:07 +00:00
|
|
|
func(httprouter.Params, []byte) (interface{}, error) {
|
2020-03-27 13:57:14 +00:00
|
|
|
return adlin.GetStudents()
|
2018-02-20 17:20:07 +00:00
|
|
|
}))
|
2018-02-20 13:55:32 +00:00
|
|
|
router.POST("/api/students/", remoteValidatorHandler(apiHandler(createStudent)))
|
|
|
|
router.GET("/api/students/:sid/", apiHandler(studentHandler(
|
2021-03-07 11:39:38 +00:00
|
|
|
func(std *adlin.Student, _ []byte) (interface{}, error) {
|
2018-02-20 17:20:07 +00:00
|
|
|
return std, nil
|
|
|
|
})))
|
2018-02-20 13:55:32 +00:00
|
|
|
router.PUT("/api/students/:sid/", remoteValidatorHandler(apiHandler(studentHandler(updateStudent))))
|
|
|
|
router.DELETE("/api/students/:sid/", remoteValidatorHandler(apiHandler(studentHandler(
|
2021-03-07 11:39:38 +00:00
|
|
|
func(std *adlin.Student, _ []byte) (interface{}, error) {
|
2018-02-20 17:20:07 +00:00
|
|
|
return std.Delete()
|
|
|
|
}))))
|
2019-03-04 08:00:22 +00:00
|
|
|
router.GET("/api/students/:sid/progress", apiHandler(studentHandler(
|
2021-03-07 11:39:38 +00:00
|
|
|
func(std *adlin.Student, _ []byte) (interface{}, error) {
|
|
|
|
ret := map[string]*adlin.UnlockedChallenge{}
|
2019-03-04 08:00:22 +00:00
|
|
|
|
2020-03-27 13:57:14 +00:00
|
|
|
if sts, err := std.GetStates(); err == nil {
|
2019-03-04 08:00:22 +00:00
|
|
|
for _, s := range sts {
|
|
|
|
ret[fmt.Sprintf("%d", s.Challenge)] = s
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-07 11:39:38 +00:00
|
|
|
if cerrors, err := std.GetChallengeErrors(); err == nil {
|
|
|
|
for _, cerr := range cerrors {
|
|
|
|
if _, ok := ret[fmt.Sprintf("%d", cerr.Challenge)]; ok {
|
|
|
|
ret[fmt.Sprintf("%d", cerr.Challenge)].Error = cerr.Error
|
|
|
|
ret[fmt.Sprintf("%d", cerr.Challenge)].LastCheck = &cerr.Time
|
|
|
|
} else {
|
|
|
|
ret[fmt.Sprintf("%d", cerr.Challenge)] = &adlin.UnlockedChallenge{
|
|
|
|
LastCheck: &cerr.Time,
|
|
|
|
Error: cerr.Error,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-04 08:00:22 +00:00
|
|
|
return ret, nil
|
|
|
|
})))
|
2018-02-20 12:49:03 +00:00
|
|
|
}
|
|
|
|
|
2018-02-22 04:36:46 +00:00
|
|
|
type uploadedStudent struct {
|
|
|
|
Login string `json:"login"`
|
|
|
|
IP string `json:"ip"`
|
|
|
|
MAC string `json:"mac"`
|
|
|
|
}
|
|
|
|
|
2018-02-20 12:49:03 +00:00
|
|
|
func createStudent(_ httprouter.Params, body []byte) (interface{}, error) {
|
2018-02-22 04:36:46 +00:00
|
|
|
var err error
|
|
|
|
var std uploadedStudent
|
|
|
|
if err = json.Unmarshal(body, &std); err != nil {
|
2018-02-20 12:49:03 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2021-03-07 11:39:38 +00:00
|
|
|
var exist *adlin.Student
|
2020-03-27 13:57:14 +00:00
|
|
|
if exist, err = adlin.GetStudentByLogin(strings.TrimSpace(std.Login)); err != nil {
|
|
|
|
if exist, err = adlin.NewStudent(strings.TrimSpace(std.Login)); err != nil {
|
2018-02-22 04:36:46 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
2018-02-21 23:45:51 +00:00
|
|
|
}
|
2020-03-27 13:57:14 +00:00
|
|
|
exist.RegisterAccess(std.IP, std.MAC)
|
2019-02-27 04:49:08 +00:00
|
|
|
|
2021-03-08 13:49:44 +00:00
|
|
|
ip := IPSuffix(exist, net.IPNet{IP: net.ParseIP("172.23.0.0"), Mask: net.CIDRMask(17, 32)}).String()
|
2019-03-13 10:19:51 +00:00
|
|
|
exist.IP = &ip
|
2019-02-27 04:49:08 +00:00
|
|
|
|
2018-02-22 04:36:46 +00:00
|
|
|
return exist, nil
|
2018-02-20 12:49:03 +00:00
|
|
|
}
|
2018-02-20 13:55:32 +00:00
|
|
|
|
2021-03-07 11:39:38 +00:00
|
|
|
func updateStudent(current *adlin.Student, body []byte) (interface{}, error) {
|
|
|
|
new := &adlin.Student{}
|
2018-02-20 13:55:32 +00:00
|
|
|
if err := json.Unmarshal(body, &new); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
current.Login = new.Login
|
|
|
|
current.Time = new.Time
|
|
|
|
return current.Update()
|
|
|
|
}
|