Skip to content

Instantly share code, notes, and snippets.

@BadLamb
Last active November 5, 2017 14:57
Show Gist options
  • Save BadLamb/32c23ff4274cf1286ee3de7df079751c to your computer and use it in GitHub Desktop.
Save BadLamb/32c23ff4274cf1286ee3de7df079751c to your computer and use it in GitHub Desktop.
/*
How to get this to work on your machine:
1) change the sqlx.Connect to connect with your server
2) run the following commands:
go get github.com/dgrijalva/jwt-go
go get github.com/jmoiron/sqlx
go get github.com/lib/pq
go get github.com/magical/argon2
go run main.go
The code will automagically setup the schema on your database.
Tested on go1.9 linux/amd64
*/
package main
import (
"encoding/json"
"hash/crc32"
"log"
"net/http"
"time"
"github.com/dgrijalva/jwt-go"
_ "github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
"github.com/magical/argon2"
)
var SECRET_KEY []byte
var db *sqlx.DB
type Student struct {
City string `db:"city"`
Classe int `db:"classe"`
Sezione string `db:"sezione"`
Sesso string `db:"sesso"`
Scuola string `db:"scuola"`
}
type Video struct {
Id int `db:"id"`
IdCorso int `db:"idCorso"`
Url string `db:"url"`
}
type Corso struct {
Id int `db:"id"`
Nome string `db:"nome"`
Categoria string `db:"categoria"`
Media float32 `db:"mediaVoto"`
}
type IscrizioneCorso struct {
Corso int `db:"idCorso"`
Studente string `db:"idStud"`
}
type Categoria struct {
Id int `db:"id"`
Nome string `db:"nome"`
}
func main() {
log.Println("Starting server..")
// openssl rand 64 | base64
SECRET_KEY = []byte("gRb+LFeT8fChcRWTybKfonhx92XxDdQ3QcrkA+q1Qarg4KU0mVbYXIrwgvE8oHHrr2HyKctaAAx+XDkctTg4qQ==")
// this Pings the database trying to connect, panics on error
db, _ = sqlx.Connect("mysql", "root:fSbFIawI+i9U4KbphDxYAH@/IntermenSchool")
db = db.Unsafe()
// Setup schema
//schema, err := ioutil.ReadFile("schema.sql")
//db.MustExec(string(schema))
http.HandleFunc("/login", loginHandler)
http.HandleFunc("/courses", courseHandler)
http.HandleFunc("/courses/uid", courseUidHandler)
http.HandleFunc("/courses/saveCourse", courseSaveHandler)
http.HandleFunc("/courses/complete", courseCompleteHandler)
http.HandleFunc("/videos", videosHandler)
http.HandleFunc("/videos/course/videolist", videoCourseListHandler)
http.HandleFunc("/videos/id/student", videoIdStudentHandler)
http.HandleFunc("/students/id", studentsIdHandler)
http.HandleFunc("/categories", categoriesHandler)
http.HandleFunc("/test", testHandler)
log.Fatal(http.ListenAndServe(":8080", nil))
}
// This function handles logins. It uses Argon2 hashing and
func loginHandler(w http.ResponseWriter, r *http.Request) {
username := r.FormValue("username")
password := r.FormValue("password")
salt := crc32.NewIEEE()
salt.Write([]byte(username))
// A lot of magic is going on here. The 27hCEQ6zwQs= is added because len(secret) must be at least 8.
// The other params are needed to set the difficulty and the memory usage of the hash
hash, err := argon2.Key([]byte(password), []byte(string(salt.Sum32())+"27hCEQ6zwQs="), 3, 1, 8, 32)
if err != nil {
w.WriteHeader(503)
}
// TODO Check for hash and username in database
if hash == nil {
return
}
// Generate a token that expires after 24h
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"username": username,
"expiartion": time.Now().Add(24 * time.Hour).Unix(),
"status": "user",
})
signed, err := token.SignedString(SECRET_KEY)
if err != nil {
w.WriteHeader(503)
}
http.SetCookie(w, &http.Cookie{
Name: "auth",
Value: signed,
})
w.Write([]byte("ok"))
}
// TODO Check if user is auth'd
func courseHandler(w http.ResponseWriter, r *http.Request) {
cc := []Corso{}
// Make query
err := db.Select(&cc, "SELECT * FROM Corsi")
if err != nil {
log.Println(err)
w.Write([]byte("Invalid request"))
return
}
// Marshal and return
res, err := json.Marshal(cc)
if err != nil {
log.Println(err)
w.Write([]byte("Invalid request"))
return
}
w.Write(res)
return
}
// TODO Check if user is auth'd
func courseUidHandler(w http.ResponseWriter, r *http.Request) {
cc := []Corso{}
userid := r.URL.Query().Get("uid")
if len(userid) == 0 {
w.Write([]byte("Invalid request"))
return
}
// Make query
err := db.Select(&cc, "SELECT Corsi.id,Corsi.nome,Corsi.categoria,Corsi.tag,IscrizioneCorso.completamento FROM IscrizioneCorso INNER JOIN Studenti ON Studenti.id = IscrizioneCorso.idStud INNER JOIN Corsi ON Corsi.id = IscrizioneCorso.idCorso WHERE Studenti.id = ?")
if err != nil {
log.Println(err)
w.Write([]byte("Invalid request"))
return
}
// Marshal and return
res, err := json.Marshal(cc)
if err != nil {
log.Println(err)
w.Write([]byte("Invalid request"))
return
}
w.Write(res)
return
}
// TODO Check if user is auth'd
func courseSaveHandler(w http.ResponseWriter, r *http.Request) {
id := r.FormValue("id")
userid := r.FormValue("uid")
if len(id) == 0 || len(userid) == 0 {
log.Println(id, userid)
w.Write([]byte("Invalid request"))
return
}
// Make query
err := db.MustExec("INSERT INTO IscrizioneCorso (idCorso,idStud,completamento) VALUES (?,?,'0.0') ", id, userid)
if err != nil {
log.Println(err)
w.Write([]byte("Invalid request"))
return
}
w.Write([]byte("ok"))
return
}
// TODO Check if user is auth'd THIS ISNT DONE YET
func courseCompleteHandler(w http.ResponseWriter, r *http.Request) {
id := r.URL.Query().Get("id")
if len(id) == 0 {
log.Println(id)
w.Write([]byte("Invalid request"))
return
}
cc := []IscrizioneCorso{}
// Make query
err := db.Select(&cc, "SELECT idCorso, idStud, completamento FROM IscrizioneCorso WHERE idCorso = ? AND idStud = &idStud", id)
if err != nil {
log.Println(err)
w.Write([]byte("Invalid request"))
return
}
// Marshal and return
res, err := json.Marshal(cc)
if err != nil {
log.Println(err)
w.Write([]byte("Invalid request"))
return
}
w.Write(res)
return
}
// TODO Check if user is auth'd
func videosHandler(w http.ResponseWriter, r *http.Request) {
id := r.URL.Query().Get("id")
if len(id) == 0 {
log.Println(id)
w.Write([]byte("Invalid request"))
return
}
cc := []Video{}
// Make query
err := db.Select(&cc, "SELECT id,nomeVideo,url FROM Video WHERE VIDEO.id=?", id)
if err != nil {
log.Println(err)
w.Write([]byte("Invalid request"))
return
}
// Marshal and return
res, err := json.Marshal(cc)
if err != nil {
log.Println(err)
w.Write([]byte("Invalid request"))
return
}
w.Write(res)
return
}
// TODO Check if user is auth'd
func videoCourseListHandler(w http.ResponseWriter, r *http.Request) {
id := r.URL.Query().Get("id")
if len(id) == 0 {
log.Println(id)
w.Write([]byte("Invalid request"))
return
}
cc := []Video{}
// Make query
err := db.Select(&cc, "SELECT * FROM Video WHERE idCorso = ?", id)
if err != nil {
log.Println(err)
w.Write([]byte("Invalid request"))
return
}
// Marshal and return
res, err := json.Marshal(cc)
if err != nil {
log.Println(err)
w.Write([]byte("Invalid request"))
return
}
w.Write(res)
return
}
// TODO Check if user is auth'd
func videoIdStudentHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Not implemented"))
return
if r.Method == "PUT" {
// What is time?
db.MustExec("UPDATE VideoStudente SET secondiVisti = ${time} WHERE (idStudente = '${userID}' AND idVideo = ${videoID});")
return
}
if r.Method == "PUT" {
//db.MustExec("INSERT INTO VideoStudente (idStudente,idVideo,secondiVisti) VALUES ("${userID}",${videoID},0);")
return
}
}
// TODO Check if user is auth'd
func studentsIdHandler(w http.ResponseWriter, r *http.Request) {
id := r.URL.Query().Get("id")
if len(id) == 0 {
log.Println(id)
w.Write([]byte("Invalid request"))
return
}
cc := []Video{}
// Make query
err := db.Select(&cc, "SELECT * FROM Video WHERE id = ?", id)
if err != nil {
log.Println(err)
w.Write([]byte("Invalid request"))
return
}
// Marshal and return
res, err := json.Marshal(cc)
if err != nil {
log.Println(err)
w.Write([]byte("Invalid request"))
return
}
w.Write(res)
return
}
// TODO Check if user is auth'd
func categoriesHandler(w http.ResponseWriter, r *http.Request) {
cc := []Video{}
// Make query
err := db.Select(&cc, "SELECT * FROM Categoria")
if err != nil {
log.Println(err)
w.Write([]byte("Invalid request"))
return
}
// Marshal and return
res, err := json.Marshal(cc)
if err != nil {
log.Println(err)
w.Write([]byte("Invalid request"))
return
}
w.Write(res)
return
}
// TODO Check if user is auth'd
func testHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Not implemented"))
return
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment