Pracownia.Programowania/main.go

260 lines
6.4 KiB
Go

package main
import (
"fmt"
"html/template"
"net/http"
"git.wmi.amu.edu.pl/s439508/Pracownia.Programowania/common"
"git.wmi.amu.edu.pl/s439508/Pracownia.Programowania/helpers"
"git.wmi.amu.edu.pl/s439508/Pracownia.Programowania/models"
"github.com/go-martini/martini"
"github.com/martini-contrib/render"
"golang.org/x/crypto/bcrypt"
"github.com/satori/go.uuid"
)
type user struct {
UserName string
Password []byte
First string
Last string
}
var tpl *template.Template
var dbUsers = map[string]user{} // user ID, user
var dbSessions = map[string]string{} // session ID, user ID
func init() {
tpl = template.Must(template.ParseGlob("templates/*"))
bs, _ := bcrypt.GenerateFromPassword([]byte("password"), bcrypt.MinCost)
dbUsers["test@test.com"] = user{"test@test.com", bs, "James", "Bond"}
}
func index1(rend render.Render, w http.ResponseWriter, req *http.Request) {
if !alreadyLoggedIn(req) {
http.Redirect(w, req, "/", http.StatusSeeOther)
return
}
posts, err := models.Posts.FindAll()
if err != nil {
rend.Error(http.StatusBadRequest)
return
}
rend.HTML(http.StatusOK, "index1", posts)
}
func write(rend render.Render) {
rend.HTML(http.StatusOK, "write", &models.Post{})
}
func edit(rend render.Render, w http.ResponseWriter, r *http.Request, params martini.Params) {
post, err := models.Posts.FindOne(params["id"])
if err != nil {
rend.Error(http.StatusNotFound)
return
}
rend.HTML(http.StatusOK, "write", post)
}
func savePost(rend render.Render, w http.ResponseWriter, r *http.Request) {
id := r.FormValue("id")
title := r.FormValue("title")
if title == "" {
rend.Error(http.StatusNotFound)
return
} else {
contentMd := r.FormValue("content")
contentHtml := helpers.MarkdownToHtml(contentMd)
contentCom := r.FormValue("content1")
if id != "" {
if err := models.Posts.Update(id, title, contentHtml, contentMd, contentCom); err != nil {
rend.Error(http.StatusBadRequest)
return
}
} else {
if _, err := models.Posts.Create(helpers.GenerateId(), title, contentHtml, contentMd, contentCom); err != nil {
rend.Error(http.StatusBadRequest)
return
}
}
}
rend.Redirect("/index1")
}
func deletePost(rend render.Render, w http.ResponseWriter, r *http.Request, params martini.Params) {
if err := models.Posts.DeletebyId(params["id"]); err != nil {
rend.Error(http.StatusNotFound)
return
}
rend.Redirect("/index1")
}
func getHtmlPost(rend render.Render, w http.ResponseWriter, r *http.Request) {
md := r.FormValue("md")
rend.JSON(http.StatusOK, map[string]interface{}{
"html": helpers.MarkdownToHtml(md),
})
}
func index(w http.ResponseWriter, req *http.Request) {
u := getUser(w, req)
tpl.ExecuteTemplate(w, "index.html", u)
}
func login(w http.ResponseWriter, req *http.Request) {
if alreadyLoggedIn(req) {
http.Redirect(w, req, "/index1", http.StatusSeeOther)
return
}
var u user
// process form submission
if req.Method == http.MethodPost {
un := req.FormValue("username")
p := req.FormValue("password")
// is there a username?
u, ok := dbUsers[un]
if !ok {
http.Error(w, "NIEUDANA PRÓBA LOGOWANIA, SPRAWDŹ CZY HASŁO I LOGIN SĄ POPRAWNĘ, JEŚLI NIE MASZ JESZCZE KONTA ZAŁÓŻ JE", http.StatusForbidden)
return
}
// does the entered password match the stored password?
err := bcrypt.CompareHashAndPassword(u.Password, []byte(p))
if err != nil {
http.Error(w, "NIEUDANA PRÓBA LOGOWANIA, SPRAWDŹ CZY HASŁO I LOGIN SĄ POPRAWNĘ, JEŚLI NIE MASZ JESZCZE KONTA ZAŁÓŻ JE ", http.StatusForbidden)
return
}
// create session
sID, _ := uuid.NewV4()
c := &http.Cookie{
Name: "session",
Value: sID.String(),
}
http.SetCookie(w, c)
dbSessions[c.Value] = un
http.Redirect(w, req, "/index1", http.StatusSeeOther)
return
}
tpl.ExecuteTemplate(w, "login.html", u)
}
func signup(w http.ResponseWriter, req *http.Request) {
if alreadyLoggedIn(req) {
http.Redirect(w, req, "/login", http.StatusSeeOther)
return
}
var u user
// process form submission
if req.Method == http.MethodPost {
// get form values
un := req.FormValue("username")
p := req.FormValue("password")
f := req.FormValue("firstname")
l := req.FormValue("lastname")
// username taken?
if _, ok := dbUsers[un]; ok {
http.Error(w, "Username already taken", http.StatusForbidden)
return
}
// create session
sID, _ := uuid.NewV4()
c := &http.Cookie{
Name: "session",
Value: sID.String(),
}
http.SetCookie(w, c)
dbSessions[c.Value] = un
// store user in dbUsers
bs, err := bcrypt.GenerateFromPassword([]byte(p), bcrypt.MinCost)
if err != nil {
http.Error(w, "Internal server error", http.StatusInternalServerError)
return
}
u = user{un, bs, f, l}
dbUsers[un] = u
// redirect
http.Redirect(w, req, "/login", http.StatusSeeOther)
return
}
tpl.ExecuteTemplate(w, "signup.html", u)
}
func bar(w http.ResponseWriter, req *http.Request) {
u := getUser(w, req)
if !alreadyLoggedIn(req) {
http.Redirect(w, req, "/", http.StatusSeeOther)
return
}
tpl.ExecuteTemplate(w, "bar.html", u)
}
func logout(w http.ResponseWriter, req *http.Request) {
if !alreadyLoggedIn(req) {
http.Redirect(w, req, "/", http.StatusSeeOther)
return
}
c, _ := req.Cookie("session")
// delete the session
delete(dbSessions, c.Value)
// remove the cookie
c = &http.Cookie{
Name: "session",
Value: "",
MaxAge: -1,
}
http.SetCookie(w, c)
http.Redirect(w, req, "/login", http.StatusSeeOther)
}
func unescape(s string) interface{} {
return template.HTML(s)
}
func main() {
common.ConnectDB()
fmt.Println("Listening port 3000")
m := martini.Classic()
unescapeFuncMap := template.FuncMap{"unescape": unescape}
m.Use(render.Renderer(render.Options{
Directory: "views",
Layout: "layout",
Extensions: []string{".html"},
Funcs: []template.FuncMap{unescapeFuncMap},
Charset: "UTF-8",
IndentJSON: true,
}))
staticOptions := martini.StaticOptions{Prefix: "bower_components"}
m.Use(martini.Static("bower_components", staticOptions))
m.Get("/index1", index1)
m.Post("/index1", index1)
m.Get("/write", write)
m.Get("/", login)
m.Get("/login", login)
m.Post("/login", login)
m.Get("/signup", signup)
m.Post("/signup", signup)
m.Get("/bar", bar)
m.Get("/edit/:id", edit)
m.Post("/savePost", savePost)
m.Get("/deletePost/:id", deletePost)
m.Post("/getHtml", getHtmlPost)
m.Post("/logout", logout)
m.Get("/logout", logout)
http.Handle("/favicon.ico", http.NotFoundHandler())
m.Run()
}