From 6d8f38d74958d03ae0941eb40360706450b401f5 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Sun, 7 Mar 2021 12:39:38 +0100 Subject: [PATCH] Use pointer instead of struct --- checker/checker.go | 2 +- libadlin/domain.go | 8 ++-- libadlin/ping.go | 4 +- libadlin/session.go | 25 +++++------ libadlin/ssh.go | 25 +++++------ libadlin/students.go | 80 ++++++++++++++++++++++++------------ libadlin/tunnel.go | 39 ++++++++++-------- token-validator/auth.go | 8 ++-- token-validator/auth_oidc.go | 2 +- token-validator/challenge.go | 4 +- token-validator/check.go | 4 +- token-validator/domain.go | 56 ++++++++++++------------- token-validator/handler.go | 6 +-- token-validator/ip.go | 8 ++-- token-validator/ping.go | 6 +-- token-validator/ssh.go | 4 +- token-validator/students.go | 36 +++++++++++----- token-validator/wg.go | 12 +++--- 18 files changed, 187 insertions(+), 142 deletions(-) diff --git a/checker/checker.go b/checker/checker.go index c85ef00..3b98cae 100644 --- a/checker/checker.go +++ b/checker/checker.go @@ -167,7 +167,7 @@ func check_https(domain, ip string) (err error) { // Main -func minTunnelVersion(std adlin.Student, suffixip int) (int, error) { +func minTunnelVersion(std *adlin.Student, suffixip int) (int, error) { tunnels, err := std.GetTunnelTokens() if err != nil { return 0, err diff --git a/libadlin/domain.go b/libadlin/domain.go index f5d7f7d..4553012 100644 --- a/libadlin/domain.go +++ b/libadlin/domain.go @@ -10,7 +10,7 @@ const ( DelegatedDomainSuffix = "srs.p0m.fr." ) -func (student Student) MyDelegatedDomain() string { +func (student *Student) MyDelegatedDomain() string { if student.DelegatedDomain != nil { return *student.DelegatedDomain } else { @@ -18,11 +18,11 @@ func (student Student) MyDelegatedDomain() string { } } -func (student Student) DefaultAssociatedDomain() string { +func (student *Student) DefaultAssociatedDomain() string { return fmt.Sprintf("%s.%s", strings.Trim(strings.Replace(student.Login, "_", "-", -1), "-_"), AssociatedDomainSuffix) } -func (student Student) MyAssociatedDomain() string { +func (student *Student) MyAssociatedDomain() string { if student.AssociatedDomain != nil { return *student.AssociatedDomain } else { @@ -30,7 +30,7 @@ func (student Student) MyAssociatedDomain() string { } } -func (student Student) GetAssociatedDomains() (ds []string) { +func (student *Student) GetAssociatedDomains() (ds []string) { defdn := student.DefaultAssociatedDomain() ds = append(ds, defdn) diff --git a/libadlin/ping.go b/libadlin/ping.go index c8bef5a..a93fc9c 100644 --- a/libadlin/ping.go +++ b/libadlin/ping.go @@ -9,14 +9,14 @@ type Pong struct { State bool } -func (s Student) LastPongs() (pongs []Pong, err error) { +func (s *Student) LastPongs() (pongs []*Pong, err error) { if rows, errr := DBQuery("SELECT time, state FROM student_pong WHERE id_student = ? ORDER BY time DESC", s.Id); errr != nil { return nil, errr } else { defer rows.Close() for rows.Next() { - var p Pong + p := &Pong{} if err = rows.Scan(&p.Date, &p.State); err != nil { return } diff --git a/libadlin/session.go b/libadlin/session.go index 933f425..2665987 100644 --- a/libadlin/session.go +++ b/libadlin/session.go @@ -11,40 +11,41 @@ type Session struct { Time time.Time `json:"time"` } -func GetSession(id []byte) (s Session, err error) { +func GetSession(id []byte) (s *Session, err error) { + s = new(Session) err = DBQueryRow("SELECT id_session, id_student, time FROM student_sessions WHERE id_session=?", id).Scan(&s.Id, &s.IdStudent, &s.Time) return } -func NewSession() (Session, error) { +func NewSession() (*Session, error) { session_id := make([]byte, 255) if _, err := rand.Read(session_id); err != nil { - return Session{}, err + return nil, err } else if _, err := DBExec("INSERT INTO student_sessions (id_session, time) VALUES (?, ?)", session_id, time.Now()); err != nil { - return Session{}, err + return nil, err } else { - return Session{session_id, nil, time.Now()}, nil + return &Session{session_id, nil, time.Now()}, nil } } -func (student Student) NewSession() (Session, error) { +func (student *Student) NewSession() (*Session, error) { session_id := make([]byte, 255) if _, err := rand.Read(session_id); err != nil { - return Session{}, err + return nil, err } else if _, err := DBExec("INSERT INTO student_sessions (id_session, id_student, time) VALUES (?, ?, ?)", session_id, student.Id, time.Now()); err != nil { - return Session{}, err + return nil, err } else { - return Session{session_id, &student.Id, time.Now()}, nil + return &Session{session_id, &student.Id, time.Now()}, nil } } -func (s Session) SetStudent(student Student) (Session, error) { +func (s *Session) SetStudent(student *Student) (*Session, error) { s.IdStudent = &student.Id _, err := s.Update() return s, err } -func (s Session) Update() (int64, error) { +func (s *Session) Update() (int64, error) { if res, err := DBExec("UPDATE student_sessions SET id_student = ?, time = ? WHERE id_session = ?", s.IdStudent, s.Time, s.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { @@ -54,7 +55,7 @@ func (s Session) Update() (int64, error) { } } -func (s Session) Delete() (int64, error) { +func (s *Session) Delete() (int64, error) { if res, err := DBExec("DELETE FROM student_sessions WHERE id_session = ?", s.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { diff --git a/libadlin/ssh.go b/libadlin/ssh.go index 9e8f1be..f699860 100644 --- a/libadlin/ssh.go +++ b/libadlin/ssh.go @@ -16,14 +16,14 @@ type StudentKey struct { Time time.Time `json:"time"` } -func GetStudentKeys() (keys []StudentKey, err error) { +func GetStudentKeys() (keys []*StudentKey, err error) { if rows, errr := DBQuery("SELECT id_key, id_student, sshkey, time FROM student_keys"); errr != nil { return nil, errr } else { defer rows.Close() for rows.Next() { - var k StudentKey + k := &StudentKey{} if err = rows.Scan(&k.Id, &k.IdStudent, &k.Key, &k.Time); err != nil { return } @@ -37,14 +37,14 @@ func GetStudentKeys() (keys []StudentKey, err error) { } } -func (s Student) GetKeys() (keys []StudentKey, err error) { +func (s *Student) GetKeys() (keys []*StudentKey, err error) { if rows, errr := DBQuery("SELECT id_key, id_student, sshkey, time FROM student_keys WHERE id_student = ?", s.Id); errr != nil { return nil, errr } else { defer rows.Close() for rows.Next() { - var k StudentKey + k := &StudentKey{} if err = rows.Scan(&k.Id, &k.IdStudent, &k.Key, &k.Time); err != nil { return } @@ -58,12 +58,13 @@ func (s Student) GetKeys() (keys []StudentKey, err error) { } } -func getStudentKey(id int) (k StudentKey, err error) { +func getStudentKey(id int) (k *StudentKey, err error) { + k = new(StudentKey) err = DBQueryRow("SELECT id_key, id_student, sshkey, time FROM student_keys WHERE id_key=?", id).Scan(&k.Id, &k.IdStudent, &k.Key, &k.Time) return } -func (s Student) NewKey(key string) (k StudentKey, err error) { +func (s *Student) NewKey(key string) (k *StudentKey, err error) { // Check key before importing it cmd := exec.Command("ssh-keygen", "-l", "-f", "-") cmd.Stdin = strings.NewReader(key) @@ -101,20 +102,20 @@ func (s Student) NewKey(key string) (k StudentKey, err error) { key = keyf[0] + " " + keyf[1] if res, err := DBExec("INSERT INTO student_keys (id_student, sshkey, time) VALUES (?, ?, ?)", s.Id, key, time.Now()); err != nil { - return StudentKey{}, err + return nil, err } else if kid, err := res.LastInsertId(); err != nil { - return StudentKey{}, err + return nil, err } else { s.UnlockNewChallenge(11, "") - return StudentKey{kid, s.Id, key, time.Now()}, nil + return &StudentKey{kid, s.Id, key, time.Now()}, nil } } -func (k StudentKey) GetStudent() (Student, error) { +func (k *StudentKey) GetStudent() (*Student, error) { return GetStudent(int(k.IdStudent)) } -func (k StudentKey) Update() (int64, error) { +func (k *StudentKey) Update() (int64, error) { if res, err := DBExec("UPDATE student_keys SET id_student = ?, sshkey = ?, time = ? WHERE id_key = ?", k.IdStudent, k.Key, k.Time, k.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { @@ -124,7 +125,7 @@ func (k StudentKey) Update() (int64, error) { } } -func (k StudentKey) Delete() (int64, error) { +func (k *StudentKey) Delete() (int64, error) { if res, err := DBExec("DELETE FROM student_keys WHERE id_key = ?", k.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { diff --git a/libadlin/students.go b/libadlin/students.go index 6471335..9903cc0 100644 --- a/libadlin/students.go +++ b/libadlin/students.go @@ -17,14 +17,14 @@ type Student struct { DelegatedDomain *string `json:"delegated_domain,omitempty"` } -func GetStudents() (students []Student, err error) { +func GetStudents() (students []*Student, err error) { if rows, errr := DBQuery("SELECT S.id_student, S.login, MAX(L.time), L.ip, L.mac, S.associatedDomain, S.delegatedDomain FROM students S INNER JOIN (SELECT a.id_student, a.time, a.ip, a.mac FROM student_login a INNER JOIN (SELECT id_student, MAX(time) AS time FROM student_login GROUP BY id_student) b ON a.id_student = b.id_student AND a.time = b.time) L ON S.id_student = L.id_student GROUP BY id_student"); errr != nil { return nil, errr } else { defer rows.Close() for rows.Next() { - var s Student + s := &Student{} if err = rows.Scan(&s.Id, &s.Login, &s.Time, &s.IP, &s.MAC, &s.AssociatedDomain, &s.DelegatedDomain); err != nil { return } @@ -38,12 +38,14 @@ func GetStudents() (students []Student, err error) { } } -func GetStudent(id int) (s Student, err error) { +func GetStudent(id int) (s *Student, err error) { + s = new(Student) err = DBQueryRow("SELECT S.id_student, S.login, MAX(L.time), L.ip, L.mac, S.associatedDomain, S.delegatedDomain FROM students S INNER JOIN (SELECT a.id_student, a.time, a.ip, a.mac FROM student_login a INNER JOIN (SELECT id_student, MAX(time) AS time FROM student_login GROUP BY id_student) b ON a.id_student = b.id_student AND a.time = b.time) L ON S.id_student = L.id_student WHERE S.id_student=?", id).Scan(&s.Id, &s.Login, &s.Time, &s.IP, &s.MAC, &s.AssociatedDomain, &s.DelegatedDomain) return } -func GetStudentByLogin(login string) (s Student, err error) { +func GetStudentByLogin(login string) (s *Student, err error) { + s = new(Student) err = DBQueryRow("SELECT S.id_student, S.login, MAX(L.time), L.ip, L.mac, S.associatedDomain, S.delegatedDomain FROM students S INNER JOIN (SELECT a.id_student, a.time, a.ip, a.mac FROM student_login a INNER JOIN (SELECT id_student, MAX(time) AS time FROM student_login GROUP BY id_student) b ON a.id_student = b.id_student AND a.time = b.time) L ON S.id_student = L.id_student WHERE login=?", login).Scan(&s.Id, &s.Login, &s.Time, &s.IP, &s.MAC, &s.AssociatedDomain, &s.DelegatedDomain) return } @@ -54,22 +56,22 @@ func StudentExists(login string) bool { return err == nil && z == 1 } -func NewStudent(login string) (Student, error) { +func NewStudent(login string) (*Student, error) { t := time.Now() if res, err := DBExec("INSERT INTO students (login, time) VALUES (?, ?)", login, t); err != nil { - return Student{}, err + return nil, err } else if sid, err := res.LastInsertId(); err != nil { - return Student{}, err + return nil, err } else { - return Student{sid, login, &t, nil, nil, nil, nil}, nil + return &Student{sid, login, &t, nil, nil, nil, nil}, nil } } -func (s Student) GetPKey() []byte { +func (s *Student) GetPKey() []byte { return hmac.New(sha512.New512_224, []byte(SharedSecret)).Sum([]byte(s.Login)) } -func (s Student) Update() (int64, error) { +func (s *Student) Update() (int64, error) { if res, err := DBExec("UPDATE students SET login = ?, time = ?, associatedDomain = ?, delegatedDomain = ? WHERE id_student = ?", s.Login, s.Time, s.AssociatedDomain, s.DelegatedDomain, s.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { @@ -79,7 +81,7 @@ func (s Student) Update() (int64, error) { } } -func (s Student) Delete() (int64, error) { +func (s *Student) Delete() (int64, error) { if res, err := DBExec("DELETE FROM students WHERE id_student = ?", s.Id); err != nil { return 0, err } else if nb, err := res.RowsAffected(); err != nil { @@ -103,18 +105,20 @@ type UnlockedChallenge struct { Id int64 `json:"id,omitempty"` IdStudent int64 `json:"id_student"` Challenge int `json:"challenge,omitempty"` - Time time.Time `json:"time"` + Time *time.Time `json:"time,omitempty"` Value interface{} `json:"value,omitempty"` + LastCheck *time.Time `json:"last_check,omitempty"` + Error string `json:"error,omitempty"` } -func (s Student) GetStates() (ucs []UnlockedChallenge, err error) { +func (s *Student) GetStates() (ucs []*UnlockedChallenge, err error) { if rows, errr := DBQuery("SELECT id_st, challenge, time FROM student_challenges WHERE id_student = ?", s.Id); errr != nil { return nil, errr } else { defer rows.Close() for rows.Next() { - var u UnlockedChallenge + u := &UnlockedChallenge{} u.IdStudent = s.Id if err = rows.Scan(&u.Id, &u.Challenge, &u.Time); err != nil { return @@ -129,14 +133,36 @@ func (s Student) GetStates() (ucs []UnlockedChallenge, err error) { } } -func (s Student) GetStatesByChallenge() (ucs []UnlockedChallenge, err error) { +func (s *Student) GetChallengeErrors() (ucs []*ErroredChallenge, err error) { + if rows, errr := DBQuery("SELECT id_st, challenge, time, error FROM student_challenge_errors WHERE id_student = ?", s.Id); errr != nil { + return nil, errr + } else { + defer rows.Close() + + for rows.Next() { + u := &ErroredChallenge{} + u.IdStudent = s.Id + if err = rows.Scan(&u.Id, &u.Challenge, &u.Time, &u.Error); err != nil { + return + } + ucs = append(ucs, u) + } + if err = rows.Err(); err != nil { + return + } + + return + } +} + +func (s *Student) GetStatesByChallenge() (ucs []*UnlockedChallenge, err error) { if rows, errr := DBQuery("SELECT id_st, challenge, MIN(time), value FROM student_challenges WHERE id_student = ? GROUP BY challenge, id_student", s.Id); errr != nil { return nil, errr } else { defer rows.Close() for rows.Next() { - var u UnlockedChallenge + u := &UnlockedChallenge{} u.IdStudent = s.Id if err = rows.Scan(&u.Id, &u.Challenge, &u.Time, &u.Value); err != nil { return @@ -151,7 +177,7 @@ func (s Student) GetStatesByChallenge() (ucs []UnlockedChallenge, err error) { } } -func (s Student) UnlockChallenge(challenge int, value string) (uc UnlockedChallenge, err error) { +func (s *Student) UnlockChallenge(challenge int, value string) (uc *UnlockedChallenge, err error) { if uc, err = s.UnlockNewChallenge(challenge, value); err != nil { if uc, err = s.UpdateUnlockedChallenge(challenge, value); err != nil { return @@ -163,21 +189,23 @@ func (s Student) UnlockChallenge(challenge int, value string) (uc UnlockedChalle return } -func (s Student) UnlockNewChallenge(challenge int, value string) (UnlockedChallenge, error) { +func (s *Student) UnlockNewChallenge(challenge int, value string) (*UnlockedChallenge, error) { if res, err := DBExec("INSERT INTO student_challenges (id_student, challenge, time, value) VALUES (?, ?, ?, ?)", s.Id, challenge, time.Now(), value); err != nil { - return UnlockedChallenge{}, err + return nil, err } else if utid, err := res.LastInsertId(); err != nil { - return UnlockedChallenge{}, err + return nil, err } else { - return UnlockedChallenge{utid, s.Id, challenge, time.Now(), value}, err + now := time.Now() + return &UnlockedChallenge{utid, s.Id, challenge, &now, value, nil, ""}, err } } -func (s Student) UpdateUnlockedChallenge(challenge int, value string) (UnlockedChallenge, error) { +func (s *Student) UpdateUnlockedChallenge(challenge int, value string) (*UnlockedChallenge, error) { if _, err := DBExec("UPDATE student_challenges SET time = ?, value = ? WHERE id_student = ? AND challenge = ?", time.Now(), value, s.Id, challenge); err != nil { - return UnlockedChallenge{}, err + return nil, err } else { - return UnlockedChallenge{0, s.Id, challenge, time.Now(), value}, err + now := time.Now() + return &UnlockedChallenge{0, s.Id, challenge, &now, value, nil, ""}, err } } @@ -189,7 +217,7 @@ type ErroredChallenge struct { Error string `json:"error,omitempty"` } -func (s Student) RegisterChallengeError(challenge int, err error) error { +func (s *Student) RegisterChallengeError(challenge int, err error) error { if _, errr := DBExec("INSERT INTO student_challenge_errors (id_student, challenge, time, error) VALUES (?, ?, ?, ?)", s.Id, challenge, time.Now(), err.Error()); errr == nil { return nil } else if _, errr := DBExec("UPDATE student_challenge_errors SET time = ?, error = ? WHERE id_student = ? AND challenge = ?", time.Now(), err.Error(), s.Id, challenge); errr != nil { @@ -199,7 +227,7 @@ func (s Student) RegisterChallengeError(challenge int, err error) error { } } -func (s Student) RegisterAccess(ip, mac string) error { +func (s *Student) RegisterAccess(ip, mac string) error { if res, err := DBExec("INSERT INTO student_login (id_student, ip, mac, time) VALUES (?, ?, ?, ?)", s.Id, ip, mac, time.Now()); err != nil { return err } else if _, err := res.LastInsertId(); err != nil { diff --git a/libadlin/tunnel.go b/libadlin/tunnel.go index db96e47..c22a520 100644 --- a/libadlin/tunnel.go +++ b/libadlin/tunnel.go @@ -37,32 +37,32 @@ type WGDump struct { } var ( - wgDumpCache_data map[string]WGDump = nil + wgDumpCache_data map[string]*WGDump = nil wgDumpCache_time time.Time wgDumpCache_mutex sync.RWMutex ) -func _readWgDump() (wgd map[string]WGDump, err error) { +func _readWgDump() (wgd map[string]*WGDump, err error) { out, errr := exec.Command("wg", "show", "wg-adlin", "dump").Output() if errr != nil { return nil, errr } - wgd = map[string]WGDump{} + wgd = map[string]*WGDump{} for _, line := range strings.Split(string(out), "\n") { cols := strings.Fields(line) if len(cols) != 8 { continue } - wgd[cols[0]] = WGDump{cols[0], cols[1], cols[2], cols[3], cols[4], cols[5], cols[6], cols[7]} + wgd[cols[0]] = &WGDump{cols[0], cols[1], cols[2], cols[3], cols[4], cols[5], cols[6], cols[7]} } return } -func readWgDump() (wgd map[string]WGDump, err error) { +func readWgDump() (wgd map[string]*WGDump, err error) { wgDumpCache_mutex.RLock() defer wgDumpCache_mutex.RUnlock() @@ -116,24 +116,26 @@ func TokenFromText(token string) []byte { return sha[:] } -func GetTunnelToken(token []byte) (t TunnelToken, err error) { +func GetTunnelToken(token []byte) (t *TunnelToken, err error) { + t = new(TunnelToken) err = DBQueryRow("SELECT token, token_text, id_student, pubkey, time, suffixip, version FROM student_tunnel_tokens WHERE token=? ORDER BY time DESC", token).Scan(&t.token, &t.TokenText, &t.IdStudent, &t.PubKey, &t.Time, &t.SuffixIP, &t.Version) if err == nil && t.PubKey != nil { if wgd, errr := readWgDump(); errr == nil { if v, ok := wgd[base64.StdEncoding.EncodeToString(t.PubKey)]; ok { - t.Dump = &v + t.Dump = v } } } return } -func (student Student) NewTunnelToken(suffixip int) (t TunnelToken, err error) { +func (student *Student) NewTunnelToken(suffixip int) (t *TunnelToken, err error) { tok := make([]byte, 7) if _, err = rand.Read(tok); err != nil { return } + t = new(TunnelToken) t.TokenText = strings.Replace(strings.Replace(strings.Replace(strings.Replace(strings.Replace(base64.RawStdEncoding.EncodeToString(tok), "/", ".", -1), "+", "_", -1), "O", "<", -1), "l", "$", -1), "I", ">", -1) t.token = TokenFromText(t.TokenText) t.IdStudent = student.Id @@ -142,7 +144,7 @@ func (student Student) NewTunnelToken(suffixip int) (t TunnelToken, err error) { return } -func (student Student) GetTunnelTokens() (ts []TunnelToken, err error) { +func (student *Student) GetTunnelTokens() (ts []*TunnelToken, err error) { if rows, errr := DBQuery("SELECT token, token_text, id_student, pubkey, time, suffixip, version FROM student_tunnel_tokens WHERE id_student = ? ORDER BY time DESC", student.Id); errr != nil { return nil, errr } else if wgd, errr := readWgDump(); errr != nil { @@ -151,13 +153,13 @@ func (student Student) GetTunnelTokens() (ts []TunnelToken, err error) { defer rows.Close() for rows.Next() { - var t TunnelToken + t := &TunnelToken{} if err = rows.Scan(&t.token, &t.TokenText, &t.IdStudent, &t.PubKey, &t.Time, &t.SuffixIP, &t.Version); err != nil { return } if t.PubKey != nil { if v, ok := wgd[base64.StdEncoding.EncodeToString(t.PubKey)]; ok { - t.Dump = &v + t.Dump = v } } ts = append(ts, t) @@ -170,7 +172,7 @@ func (student Student) GetTunnelTokens() (ts []TunnelToken, err error) { } } -func (student Student) GetActivesTunnels() (ts []TunnelToken, err error) { +func (student *Student) GetActivesTunnels() (ts []*TunnelToken, err error) { if rows, errr := DBQuery("SELECT token, token_text, id_student, pubkey, time, suffixip, version FROM student_tunnel_tokens WHERE id_student = ? ORDER BY time DESC", student.Id); errr != nil { return nil, errr } else if wgd, errr := readWgDump(); errr != nil { @@ -179,13 +181,13 @@ func (student Student) GetActivesTunnels() (ts []TunnelToken, err error) { defer rows.Close() for rows.Next() { - var t TunnelToken + t := &TunnelToken{} if err = rows.Scan(&t.token, &t.TokenText, &t.IdStudent, &t.PubKey, &t.Time, &t.SuffixIP, &t.Version); err != nil { return } if t.PubKey != nil { if v, ok := wgd[base64.StdEncoding.EncodeToString(t.PubKey)]; ok { - t.Dump = &v + t.Dump = v ts = append(ts, t) } } @@ -198,12 +200,13 @@ func (student Student) GetActivesTunnels() (ts []TunnelToken, err error) { } } -func (student Student) GetTunnelToken(token []byte) (t TunnelToken, err error) { +func (student *Student) GetTunnelToken(token []byte) (t *TunnelToken, err error) { + t = new(TunnelToken) err = DBQueryRow("SELECT token, token_text, id_student, pubkey, time, suffixip, version FROM student_tunnel_tokens WHERE token = ? AND id_student = ? ORDER BY time DESC", token, student.Id).Scan(&t.token, &t.TokenText, &t.IdStudent, &t.PubKey, &t.Time, &t.SuffixIP, &t.Version) if err == nil && t.PubKey != nil { if wgd, errr := readWgDump(); errr == nil { if v, ok := wgd[base64.StdEncoding.EncodeToString(t.PubKey)]; ok { - t.Dump = &v + t.Dump = v } } } @@ -235,14 +238,14 @@ func (t *TunnelToken) Delete() (int64, error) { } } -func GetStudentsTunnels() (ts []TunnelToken, err error) { +func GetStudentsTunnels() (ts []*TunnelToken, err error) { if rows, errr := DBQuery("SELECT T.token, T.token_text, T.id_student, T.pubkey, T.time, T.suffixip, T.version FROM student_tunnel_tokens T INNER JOIN (SELECT B.id_student, MAX(B.time) AS time FROM student_tunnel_tokens B WHERE B.pubkey IS NOT NULL GROUP BY id_student) L ON T.id_student = L.id_student AND T.time = L.time"); errr != nil { return nil, errr } else { defer rows.Close() for rows.Next() { - var t TunnelToken + t := &TunnelToken{} if err = rows.Scan(&t.token, &t.TokenText, &t.IdStudent, &t.PubKey, &t.Time, &t.SuffixIP, &t.Version); err != nil { return } diff --git a/token-validator/auth.go b/token-validator/auth.go index f90fec9..97be90b 100644 --- a/token-validator/auth.go +++ b/token-validator/auth.go @@ -27,7 +27,7 @@ func init() { router.POST("/api/auth/logout", apiRawHandler(logout)) } -func validateAuthToken(s adlin.Student, _ httprouter.Params, _ []byte) (interface{}, error) { +func validateAuthToken(s *adlin.Student, _ httprouter.Params, _ []byte) (interface{}, error) { return s, nil } @@ -50,7 +50,7 @@ type loginForm struct { } func completeAuth(w http.ResponseWriter, username string, session *adlin.Session) (err error) { - var std adlin.Student + var std *adlin.Student if !adlin.StudentExists(username) { if std, err = adlin.NewStudent(username); err != nil { return err @@ -60,9 +60,7 @@ func completeAuth(w http.ResponseWriter, username string, session *adlin.Session } if session == nil { - var s adlin.Session - s, err = std.NewSession() - session = &s + session, err = std.NewSession() } else { _, err = session.SetStudent(std) } diff --git a/token-validator/auth_oidc.go b/token-validator/auth_oidc.go index 9118aea..590676a 100644 --- a/token-validator/auth_oidc.go +++ b/token-validator/auth_oidc.go @@ -111,7 +111,7 @@ func OIDC_CRI_complete(w http.ResponseWriter, r *http.Request, ps httprouter.Par return } - if err := completeAuth(w, claims.Username, &session); err != nil { + if err := completeAuth(w, claims.Username, session); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } diff --git a/token-validator/challenge.go b/token-validator/challenge.go index d21db5d..51144f1 100644 --- a/token-validator/challenge.go +++ b/token-validator/challenge.go @@ -338,7 +338,7 @@ func receiveChallenge(r *http.Request, ps httprouter.Params, body []byte) (inter return nil, errors.New("This is not the expected token.") } - var std adlin.Student + var std *adlin.Student if stdid, err := strconv.Atoi(gt.Login); err == nil { if std, err = adlin.GetStudent(stdid); err != nil { @@ -388,7 +388,7 @@ func receiveToken(r *http.Request, body []byte, chid int) (interface{}, error) { if std, err := adlin.GetStudentByLogin(gt.Login); err != nil { return nil, err } else { - if err := challenges[chid-1].Check(&std, >, chid); err != nil { + if err := challenges[chid-1].Check(std, >, chid); err != nil { log.Printf("%s just try ch#%d: %s\n", std.Login, chid, err) return nil, err } diff --git a/token-validator/check.go b/token-validator/check.go index 8e18faf..722e54f 100644 --- a/token-validator/check.go +++ b/token-validator/check.go @@ -19,7 +19,7 @@ type checkGLUE struct { } func init() { - router.POST("/api/check/GLUE", apiAuthHandler(func(student adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { + router.POST("/api/check/GLUE", apiAuthHandler(func(student *adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { var uc checkGLUE if err := json.Unmarshal(body, &uc); err != nil { return nil, err @@ -27,7 +27,7 @@ func init() { return true, check_GLUE_respond(student, uc.Domain, uc.IP) })) } -func check_GLUE_respond(student adlin.Student, domain string, ip string) (err error) { +func check_GLUE_respond(student *adlin.Student, domain string, ip string) (err error) { if !strings.HasPrefix(ip, adlin.StudentIP(student.Id).String()) { return fmt.Errorf("%q is not your IP range") } diff --git a/token-validator/domain.go b/token-validator/domain.go index 9f789d7..596f3bd 100644 --- a/token-validator/domain.go +++ b/token-validator/domain.go @@ -22,10 +22,10 @@ var ( ) func init() { - router.GET("/api/adomains/", apiAuthHandler(func(student adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { + router.GET("/api/adomains/", apiAuthHandler(func(student *adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { return student.GetAssociatedDomains(), nil })) - router.POST("/api/adomains/", apiAuthHandler(func(student adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { + router.POST("/api/adomains/", apiAuthHandler(func(student *adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { ue := &struct { Domain string `json:"domain"` A string `json:"a"` @@ -63,14 +63,14 @@ func init() { return true, AddAssociatedDomains(student, aaaa) } })) - router.GET("/api/adomains/:dn", apiAuthHandler(func(student adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { + router.GET("/api/adomains/:dn", apiAuthHandler(func(student *adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { return GetAssociatedDomain(student, ps.ByName("dn")) })) - router.GET("/api/ddomains/", apiAuthHandler(func(student adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { + router.GET("/api/ddomains/", apiAuthHandler(func(student *adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { return []string{student.MyDelegatedDomain()}, nil })) - router.POST("/api/ddomains/", apiAuthHandler(func(student adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { + router.POST("/api/ddomains/", apiAuthHandler(func(student *adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { ue := &struct { NS string `json:"ns"` }{} @@ -98,75 +98,75 @@ func init() { return true, nil } })) - router.GET("/api/ddomains/:dn/", apiAuthHandler(func(student adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { + router.GET("/api/ddomains/:dn/", apiAuthHandler(func(student *adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { return getRRDelegatedDomain(student, ps.ByName("dn"), "") })) - router.GET("/api/ddomains/:dn/NS", apiAuthHandler(func(student adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { + router.GET("/api/ddomains/:dn/NS", apiAuthHandler(func(student *adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { return getRRDelegatedDomain(student, ps.ByName("dn"), "NS") })) - router.POST("/api/ddomains/:dn/NS", apiAuthHandler(func(student adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { + router.POST("/api/ddomains/:dn/NS", apiAuthHandler(func(student *adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { var ue Entry if err := json.Unmarshal(body, &ue); err != nil { return nil, err } return true, AddNSDelegatedDomain(student, ps.ByName("dn"), ue.TTL, strings.Join(ue.Values, " ")) })) - router.PATCH("/api/ddomains/:dn/NS", apiAuthHandler(func(student adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { + router.PATCH("/api/ddomains/:dn/NS", apiAuthHandler(func(student *adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { var ue Entry if err := json.Unmarshal(body, &ue); err != nil { return nil, err } return true, UpdateNSDelegatedDomain(student, ps.ByName("dn"), ue.TTL, ue.ValuesFrom, strings.Join(ue.Values, "")) })) - router.DELETE("/api/ddomains/:dn/NS", apiAuthHandler(func(student adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { + router.DELETE("/api/ddomains/:dn/NS", apiAuthHandler(func(student *adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { var ue Entry if err := json.Unmarshal(body, &ue); err != nil { return nil, err } return true, DeleteRRDelegatedDomain(student, ps.ByName("dn"), "NS", strings.Join(ue.Values, " ")) })) - router.GET("/api/ddomains/:dn/GLUE", apiAuthHandler(func(student adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { + router.GET("/api/ddomains/:dn/GLUE", apiAuthHandler(func(student *adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { return getRRDelegatedDomain(student, ps.ByName("dn"), "AAAA") })) - router.POST("/api/ddomains/:dn/AAAA", apiAuthHandler(func(student adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { + router.POST("/api/ddomains/:dn/AAAA", apiAuthHandler(func(student *adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { var ue Entry if err := json.Unmarshal(body, &ue); err != nil { return nil, err } return true, AddGLUEDelegatedDomain(student, ps.ByName("dn"), ue.TTL, strings.Join(ue.Values, " ")) })) - router.PATCH("/api/ddomains/:dn/AAAA", apiAuthHandler(func(student adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { + router.PATCH("/api/ddomains/:dn/AAAA", apiAuthHandler(func(student *adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { var ue Entry if err := json.Unmarshal(body, &ue); err != nil { return nil, err } return true, UpdateGLUEDelegatedDomain(student, ps.ByName("dn"), ue.TTL, ue.ValuesFrom, strings.Join(ue.Values, " ")) })) - router.POST("/api/ddomains/:dn/GLUE", apiAuthHandler(func(student adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { + router.POST("/api/ddomains/:dn/GLUE", apiAuthHandler(func(student *adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { var ue Entry if err := json.Unmarshal(body, &ue); err != nil { return nil, err } return true, UpdateGLUEDelegatedDomain(student, ps.ByName("dn"), ue.TTL, ue.ValuesFrom, strings.Join(ue.Values, " ")) })) - router.DELETE("/api/ddomains/:dn/AAAA", apiAuthHandler(func(student adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { + router.DELETE("/api/ddomains/:dn/AAAA", apiAuthHandler(func(student *adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { var ue Entry if err := json.Unmarshal(body, &ue); err != nil { return nil, err } return true, DeleteRRDelegatedDomain(student, ps.ByName("dn"), "AAAA", strings.Join(ue.Values, " ")) })) - router.GET("/api/ddomains/:dn/DS", apiAuthHandler(func(student adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { + router.GET("/api/ddomains/:dn/DS", apiAuthHandler(func(student *adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { return getRRDelegatedDomain(student, ps.ByName("dn"), "DS") })) - router.POST("/api/ddomains/:dn/DS", apiAuthHandler(func(student adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { + router.POST("/api/ddomains/:dn/DS", apiAuthHandler(func(student *adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { var ue Entry if err := json.Unmarshal(body, &ue); err != nil { return nil, err } return true, AddDSDelegatedDomain(student, ps.ByName("dn"), ue.TTL, strings.Join(ue.Values, " ")) })) - router.DELETE("/api/ddomains/:dn/DS", apiAuthHandler(func(student adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { + router.DELETE("/api/ddomains/:dn/DS", apiAuthHandler(func(student *adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { var ue Entry if err := json.Unmarshal(body, &ue); err != nil { return nil, err @@ -223,7 +223,7 @@ func parseZoneRead(globalDomain string, domain string) (rr []Entry, err error) { return } -func GetAssociatedDomain(student adlin.Student, dn string) (rrs []Entry, err error) { +func GetAssociatedDomain(student *adlin.Student, dn string) (rrs []Entry, err error) { domains := student.GetAssociatedDomains() found := false for _, d := range domains { @@ -249,7 +249,7 @@ func GetAssociatedDomain(student adlin.Student, dn string) (rrs []Entry, err err return } -func delAssociatedDomains(student adlin.Student, dn string) (err error) { +func delAssociatedDomains(student *adlin.Student, dn string) (err error) { var adomains []Entry adomains, err = GetAssociatedDomain(student, dn) if err != nil { @@ -286,7 +286,7 @@ func delAssociatedDomains(student adlin.Student, dn string) (err error) { return } -func AddAssociatedDomains(student adlin.Student, aaaa net.IP) (err error) { +func AddAssociatedDomains(student *adlin.Student, aaaa net.IP) (err error) { err = delAssociatedDomains(student, student.DefaultAssociatedDomain()) if err != nil { return @@ -322,7 +322,7 @@ func AddAssociatedDomains(student adlin.Student, aaaa net.IP) (err error) { return } -func getRRDelegatedDomain(student adlin.Student, dn string, rr string) (rrs []Entry, err error) { +func getRRDelegatedDomain(student *adlin.Student, dn string, rr string) (rrs []Entry, err error) { domains := []string{student.MyDelegatedDomain()} found := false for _, d := range domains { @@ -348,7 +348,7 @@ func getRRDelegatedDomain(student adlin.Student, dn string, rr string) (rrs []En return } -func AddNSDelegatedDomain(student adlin.Student, dn string, ttl uint32, ns string) (err error) { +func AddNSDelegatedDomain(student *adlin.Student, dn string, ttl uint32, ns string) (err error) { for _, d := range []string{student.MyDelegatedDomain()} { m1 := new(dns.Msg) m1.Id = dns.Id() @@ -371,7 +371,7 @@ func AddNSDelegatedDomain(student adlin.Student, dn string, ttl uint32, ns strin return } -func UpdateNSDelegatedDomain(student adlin.Student, dn string, ttl uint32, oldns string, ns string) (err error) { +func UpdateNSDelegatedDomain(student *adlin.Student, dn string, ttl uint32, oldns string, ns string) (err error) { for _, d := range []string{student.MyDelegatedDomain()} { m1 := new(dns.Msg) m1.Id = dns.Id() @@ -399,7 +399,7 @@ func UpdateNSDelegatedDomain(student adlin.Student, dn string, ttl uint32, oldns return } -func AddGLUEDelegatedDomain(student adlin.Student, dn string, ttl uint32, aaaa string) (err error) { +func AddGLUEDelegatedDomain(student *adlin.Student, dn string, ttl uint32, aaaa string) (err error) { domains := []string{student.MyDelegatedDomain()} found := false for _, d := range domains { @@ -435,7 +435,7 @@ func AddGLUEDelegatedDomain(student adlin.Student, dn string, ttl uint32, aaaa s return } -func UpdateGLUEDelegatedDomain(student adlin.Student, dn string, ttl uint32, oldaaaa string, aaaa string) (err error) { +func UpdateGLUEDelegatedDomain(student *adlin.Student, dn string, ttl uint32, oldaaaa string, aaaa string) (err error) { domains := []string{student.MyDelegatedDomain()} found := false for _, d := range domains { @@ -477,7 +477,7 @@ func UpdateGLUEDelegatedDomain(student adlin.Student, dn string, ttl uint32, old return } -func AddDSDelegatedDomain(student adlin.Student, dn string, ttl uint32, rdata string) (err error) { +func AddDSDelegatedDomain(student *adlin.Student, dn string, ttl uint32, rdata string) (err error) { domains := []string{student.MyDelegatedDomain()} found := false for _, d := range domains { @@ -527,7 +527,7 @@ func AddDSDelegatedDomain(student adlin.Student, dn string, ttl uint32, rdata st return } -func DeleteRRDelegatedDomain(student adlin.Student, dn string, rr string, values ...string) (err error) { +func DeleteRRDelegatedDomain(student *adlin.Student, dn string, rr string, values ...string) (err error) { domains := []string{student.MyDelegatedDomain()} found := false for _, d := range domains { diff --git a/token-validator/handler.go b/token-validator/handler.go index c93c842..d40be85 100644 --- a/token-validator/handler.go +++ b/token-validator/handler.go @@ -65,7 +65,7 @@ func rawHandler(f func(http.ResponseWriter, *http.Request, httprouter.Params, [] http.Error(w, fmt.Sprintf(`{"errmsg": %q}`, err), http.StatusUnauthorized) return } else { - student = &std + student = std } } @@ -158,7 +158,7 @@ func apiHandler(f DispatchFunction, access ...func(*adlin.Student, *http.Request return rawHandler(responseHandler(func(_ *http.Request, ps httprouter.Params, b []byte) (interface{}, error) { return f(ps, b) }), access...) } -func apiAuthHandler(f func(adlin.Student, httprouter.Params, []byte) (interface{}, error), access ...func(*adlin.Student, *http.Request) error) func(http.ResponseWriter, *http.Request, httprouter.Params) { +func apiAuthHandler(f func(*adlin.Student, httprouter.Params, []byte) (interface{}, error), access ...func(*adlin.Student, *http.Request) error) func(http.ResponseWriter, *http.Request, httprouter.Params) { return rawHandler(responseHandler(func(r *http.Request, ps httprouter.Params, b []byte) (interface{}, error) { if cookie, err := r.Cookie("auth"); err != nil { return nil, errors.New("Authorization required") @@ -176,7 +176,7 @@ func apiAuthHandler(f func(adlin.Student, httprouter.Params, []byte) (interface{ }), access...) } -func studentHandler(f func(adlin.Student, []byte) (interface{}, error)) func(httprouter.Params, []byte) (interface{}, error) { +func studentHandler(f func(*adlin.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 := adlin.GetStudentByLogin(ps.ByName("sid")); err != nil { diff --git a/token-validator/ip.go b/token-validator/ip.go index 7036cc4..885cd0f 100644 --- a/token-validator/ip.go +++ b/token-validator/ip.go @@ -12,12 +12,12 @@ import ( func init() { router.GET("/api/ips", apiHandler(showIPs)) - router.GET("/api/students/:sid/ips", apiHandler(studentHandler(func(student adlin.Student, body []byte) (interface{}, error) { + router.GET("/api/students/:sid/ips", apiHandler(studentHandler(func(student *adlin.Student, body []byte) (interface{}, error) { return getStudentIPs(student), nil }))) } -func IPSuffix(s adlin.Student, network net.IPNet) net.IP { +func IPSuffix(s *adlin.Student, network net.IPNet) net.IP { ipshift := s.Id*4 + 10 myIP := network.IP @@ -55,7 +55,7 @@ func showIPs(_ httprouter.Params, body []byte) (interface{}, error) { return r, nil } -func GetStudentTunnelIPs(student adlin.Student) (ips []string) { +func GetStudentTunnelIPs(student *adlin.Student) (ips []string) { if ts, err := student.GetActivesTunnels(); err != nil || len(ts) == 0 || ts[0].SuffixIP == 0 { ips = append(ips, adlin.StudentIP(student.Id).String()+"1") } else { @@ -66,7 +66,7 @@ func GetStudentTunnelIPs(student adlin.Student) (ips []string) { return } -func getStudentIPs(student adlin.Student) (r map[string]string) { +func getStudentIPs(student *adlin.Student) (r map[string]string) { r = make(map[string]string) r["vlan0"] = IPSuffix(student, net.IPNet{net.ParseIP("172.23.0.0"), net.CIDRMask(17, 32)}).String() diff --git a/token-validator/ping.go b/token-validator/ping.go index b6441c5..37a6290 100644 --- a/token-validator/ping.go +++ b/token-validator/ping.go @@ -11,13 +11,13 @@ var PongSecret = "felixfixit" func init() { router.GET("/api/students/:sid/ping", apiHandler(studentHandler(lastPing))) - router.GET("/api/students/:sid/pong", apiHandler(studentHandler(func(student adlin.Student, body []byte) (interface{}, error) { + router.GET("/api/students/:sid/pong", apiHandler(studentHandler(func(student *adlin.Student, body []byte) (interface{}, error) { return student.LastPongs() }))) router.POST("/api/students/:sid/pong", apiHandler(studentHandler(stdPong), sslOnly)) } -func lastPing(student adlin.Student, body []byte) (interface{}, error) { +func lastPing(student *adlin.Student, body []byte) (interface{}, error) { if pongs, err := student.LastPongs(); err != nil { return nil, err } else if len(pongs) <= 0 { @@ -27,7 +27,7 @@ func lastPing(student adlin.Student, body []byte) (interface{}, error) { } } -func stdPong(student adlin.Student, body []byte) (interface{}, error) { +func stdPong(student *adlin.Student, body []byte) (interface{}, error) { var gt givenToken if err := json.Unmarshal(body, >); err != nil { return nil, err diff --git a/token-validator/ssh.go b/token-validator/ssh.go index 666db4c..f810571 100644 --- a/token-validator/ssh.go +++ b/token-validator/ssh.go @@ -47,7 +47,7 @@ func init() { }) } -func hasSSHKeys(student adlin.Student, body []byte) (interface{}, error) { +func hasSSHKeys(student *adlin.Student, body []byte) (interface{}, error) { if keys, err := student.GetKeys(); err != nil { return nil, err } else { @@ -141,7 +141,7 @@ func dumpAuthorizedKeysFile(w io.Writer) { } } -func dumpStdAuthorizedKeysFile(s adlin.Student, w io.Writer) { +func dumpStdAuthorizedKeysFile(s *adlin.Student, w io.Writer) { seen := map[string]interface{}{} if keys, _ := s.GetKeys(); keys != nil { diff --git a/token-validator/students.go b/token-validator/students.go index ac101fa..cee1e47 100644 --- a/token-validator/students.go +++ b/token-validator/students.go @@ -18,19 +18,19 @@ func init() { if stds, err := adlin.GetStudents(); err != nil { return nil, err } else { - ret := map[string]map[string]adlin.UnlockedChallenge{} + ret := map[string]map[string]*adlin.UnlockedChallenge{} for _, std := range stds { if sts, err := std.GetStates(); err == nil { - ret[std.Login] = map[string]adlin.UnlockedChallenge{} + ret[std.Login] = map[string]*adlin.UnlockedChallenge{} for _, s := range sts { ret[std.Login][fmt.Sprintf("%d", s.Challenge)] = s } if pongs, err := std.LastPongs(); err == nil && len(pongs) > 0 { - ret[std.Login]["ping"] = adlin.UnlockedChallenge{ + ret[std.Login]["ping"] = &adlin.UnlockedChallenge{ IdStudent: std.Id, - Time: pongs[0].Date, + Time: &pongs[0].Date, Value: pongs[0].State, } } else if err != nil { @@ -47,17 +47,17 @@ func init() { })) router.POST("/api/students/", remoteValidatorHandler(apiHandler(createStudent))) router.GET("/api/students/:sid/", apiHandler(studentHandler( - func(std adlin.Student, _ []byte) (interface{}, error) { + func(std *adlin.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 adlin.Student, _ []byte) (interface{}, error) { + func(std *adlin.Student, _ []byte) (interface{}, error) { return std.Delete() })))) router.GET("/api/students/:sid/progress", apiHandler(studentHandler( - func(std adlin.Student, _ []byte) (interface{}, error) { - ret := map[string]adlin.UnlockedChallenge{} + func(std *adlin.Student, _ []byte) (interface{}, error) { + ret := map[string]*adlin.UnlockedChallenge{} if sts, err := std.GetStates(); err == nil { for _, s := range sts { @@ -65,6 +65,20 @@ func init() { } } + 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, + } + } + } + } + return ret, nil }))) } @@ -82,7 +96,7 @@ func createStudent(_ httprouter.Params, body []byte) (interface{}, error) { return nil, err } - var exist adlin.Student + var exist *adlin.Student if exist, err = adlin.GetStudentByLogin(strings.TrimSpace(std.Login)); err != nil { if exist, err = adlin.NewStudent(strings.TrimSpace(std.Login)); err != nil { return nil, err @@ -96,8 +110,8 @@ func createStudent(_ httprouter.Params, body []byte) (interface{}, error) { return exist, nil } -func updateStudent(current adlin.Student, body []byte) (interface{}, error) { - var new adlin.Student +func updateStudent(current *adlin.Student, body []byte) (interface{}, error) { + new := &adlin.Student{} if err := json.Unmarshal(body, &new); err != nil { return nil, err } diff --git a/token-validator/wg.go b/token-validator/wg.go index 437f870..195a3f7 100644 --- a/token-validator/wg.go +++ b/token-validator/wg.go @@ -27,7 +27,7 @@ func init() { } }) router.GET("/api/wg/", apiAuthHandler(showWgTunnel)) - router.GET("/api/wginfo", apiAuthHandler(func(student adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { + router.GET("/api/wginfo", apiAuthHandler(func(student *adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { return getTunnelInfo(student.Id), nil })) router.POST("/api/wg/", apiAuthHandler(genWgToken)) @@ -37,12 +37,12 @@ func init() { router.DELETE("/api/wg/:token", apiAuthHandler(deleteWgTunnel)) } -func showWgTunnel(student adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { +func showWgTunnel(student *adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { // Get tunnels assigned to the student return student.GetTunnelTokens() } -func genWgToken(student adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { +func genWgToken(student *adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { // Generate a token to access related wg info return student.NewTunnelToken(0) } @@ -132,7 +132,7 @@ func getWgTunnelInfo(w http.ResponseWriter, r *http.Request, ps httprouter.Param tinfo := getTunnelInfo(token.IdStudent) - var student adlin.Student + var student *adlin.Student student, err = adlin.GetStudent(int(token.IdStudent)) if err != nil { http.Error(w, fmt.Sprintf("{errmsg:%q}", err), http.StatusBadRequest) @@ -152,7 +152,7 @@ PersistentKeepalive = 5 `, base64.StdEncoding.EncodeToString(tinfo.SrvPubKey), "82.64.31.248", tinfo.SrvPort, tinfo.CltIPv6, token.SuffixIP, 64, tinfo.CltIPv6, tinfo.CltRange, tinfo.SrvGW6, student.Login))) } -func updateWgTunnel(student adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { +func updateWgTunnel(student *adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { token, err := adlin.GetTunnelToken(adlin.TokenFromText(ps.ByName("token"))) if err != nil { return nil, err @@ -180,7 +180,7 @@ func updateWgTunnel(student adlin.Student, ps httprouter.Params, body []byte) (i return true, err } -func deleteWgTunnel(student adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { +func deleteWgTunnel(student *adlin.Student, ps httprouter.Params, body []byte) (interface{}, error) { token, err := adlin.GetTunnelToken(adlin.TokenFromText(ps.ByName("token"))) if err != nil { return nil, err