Last active
November 5, 2017 14:57
-
-
Save BadLamb/32c23ff4274cf1286ee3de7df079751c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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