func main() {
	store := sessions.NewCookieStore([]byte("secret123"))
	dbmap = initDb()

	m := martini.Classic()
	m.Use(render.Renderer())
	m.Use(sessions.Sessions("my_session", store))
	m.Use(sessionauth.SessionUser(GenerateAnonymousUser))
	sessionauth.RedirectUrl = "/new-login"
	sessionauth.RedirectParam = "new-next"

	m.Get("/", func(r render.Render) {
		r.HTML(200, "index", nil)
	})

	m.Get("/new-login", func(r render.Render) {
		r.HTML(200, "login", nil)
	})

	m.Post("/new-login", binding.Bind(MyUserModel{}), func(session sessions.Session, postedUser MyUserModel, r render.Render, req *http.Request) {
		// You should verify credentials against a database or some other mechanism at this point.
		// Then you can authenticate this session.
		user := MyUserModel{}
		err := dbmap.SelectOne(&user, "SELECT * FROM users WHERE username = $1 and password = $2", postedUser.Username, postedUser.Password)
		if err != nil {
			r.Redirect(sessionauth.RedirectUrl)
			return
		} else {
			err := sessionauth.AuthenticateSession(session, &user)
			if err != nil {
				r.JSON(500, err)
			}

			params := req.URL.Query()
			redirect := params.Get(sessionauth.RedirectParam)
			r.Redirect(redirect)
			return
		}
	})

	m.Get("/private", sessionauth.LoginRequired, func(r render.Render, user sessionauth.User) {
		r.HTML(200, "private", user.(*MyUserModel))
	})

	m.Get("/logout", sessionauth.LoginRequired, func(session sessions.Session, user sessionauth.User, r render.Render) {
		sessionauth.Logout(session, user)
		r.Redirect("/")
	})

	m.Run()
}
Beispiel #2
0
func main() {
	//Change secret123 to something more secure and store session in backend instead of cookie
	store := sessions.NewCookieStore([]byte("secret123"))

	dbmap = initDb()

	defer dbmap.Db.Close()

	err := dbmap.TruncateTables()
	checkErr(err, "TruncateTables failed")

	u1 := newUser("*****@*****.**", "pass", "Bob", false)

	//insert rows
	err = dbmap.Insert(&u1)
	checkErr(err, "Insert failed")

	//create two posts, assign to user 1 above
	p1 := newPost("Post 1", "Lorem ipsum lorem ipsum", 1)
	p2 := newPost("Post 2", "This is my second post", 1)

	// insert rows
	err = dbmap.Insert(&p1, &p2)
	checkErr(err, "Insert failed")

	m := martini.Classic()

	m.Use(render.Renderer(render.Options{
		Directory: "templates",
		Layout:    "layout",
		Funcs: []template.FuncMap{
			{
				"formatTime": func(args ...interface{}) string {
					t1 := time.Unix(args[0].(int64), 0)
					return t1.Format(time.Stamp)
				},
			},
		},
	}))

	m.Use(sessions.Sessions("my_session", store))
	m.Use(sessionauth.SessionUser(GenerateAnonymousUser))

	sessionauth.RedirectUrl = "/login"
	sessionauth.RedirectParam = "next"

	//ROUTES

	m.Get("/register", func(r render.Render, user sessionauth.User) {

		//redirect to homepage if already authenticated
		if user.IsAuthenticated() {
			r.Redirect("/")
		} else {
			r.HTML(200, "register", nil)
		}

	})

	m.Get("/login", func(r render.Render, user sessionauth.User) {

		//redirect to homepage if already authenticated
		if user.IsAuthenticated() {
			r.Redirect("/")
		} else {
			r.HTML(200, "login", nil)
		}
	})

	m.Post("/login", binding.Form(User{}), func(session sessions.Session, postedUser User, r render.Render, ferr binding.Errors, req *http.Request) {

		log.Println(ferr)

		//Example of server side error validation for the client side form
		if ferr.Count() > 0 {
			newmap := map[string]interface{}{"metatitle": "Registration", "errormessage": "Error with Form Submission"}
			r.HTML(200, "login", newmap)
		} else {

			user := User{}

			//check login credentails with DataBase
			err := dbmap.SelectOne(&user, "SELECT * FROM users WHERE email = ? and password = ?", postedUser.Email, postedUser.Password)
			if err != nil {
				r.Redirect(sessionauth.RedirectUrl)
				return
			} else {
				err := sessionauth.AuthenticateSession(session, &user)
				if err != nil {
					r.JSON(500, err)
				}

				params := req.URL.Query()
				redirect := params.Get(sessionauth.RedirectParam)
				r.Redirect(redirect)
				return
			}

		}

	})

	m.Get("/logout", sessionauth.LoginRequired, func(session sessions.Session, user sessionauth.User, r render.Render) {
		sessionauth.Logout(session, user)
		r.Redirect("/")
	})

	m.Get("/", func(r render.Render, authuser sessionauth.User) {

		var posts []Post
		_, err = dbmap.Select(&posts, "select * from posts order by post_id")
		checkErr(err, "Select failed")

		newmap := map[string]interface{}{"metatitle": "HomePage", "authuser": authuser, "posts": posts}
		r.HTML(200, "posts", newmap)
	})

	m.Get("/users", func(r render.Render, authuser sessionauth.User) {

		var users []User

		_, err = dbmap.Select(&users, "select * from users order by id")
		checkErr(err, "Select failed")

		newmap := map[string]interface{}{"metatitle": "Users listing", "authuser": authuser, "users": users}
		r.HTML(200, "users", newmap)

	})

	m.Get("/users/:id", sessionauth.LoginRequired, func(args martini.Params, r render.Render, authuser sessionauth.User) {

		var user User

		err = dbmap.SelectOne(&user, "select * from users where id=?", args["id"])

		//simple error check
		if err != nil {
			newmap := map[string]interface{}{"metatitle": "404 Error", "message": "User not found"}
			r.HTML(404, "error", newmap)
		} else {

			var posts []Post
			_, err = dbmap.Select(&posts, "select * from posts where UserId=?", args["id"])
			checkErr(err, "Select failed")

			newmap := map[string]interface{}{"metatitle": user.Name + " profile page", "authuser": authuser, "user": user, "posts": posts}
			r.HTML(200, "user", newmap)
		}

	})

	m.Post("/users", binding.Form(User{}), func(session sessions.Session, user User, ferr binding.Errors, r render.Render) {

		//Example of server side error validation for the client side form
		if ferr.Count() > 0 {
			fmt.Println(ferr)
			newmap := map[string]interface{}{"metatitle": "Registration", "errormessage": "Error with Form Submission"}
			r.HTML(200, "register", newmap)
		} else {

			u := newUser(user.Email, user.Password, user.Name, user.authenticated)

			err = dbmap.Insert(&u)
			checkErr(err, "Insert failed")

			//create the session and redirect always to homepage
			err := sessionauth.AuthenticateSession(session, &u)
			if err != nil {
				r.JSON(500, err)
			}

			r.Redirect("/")
		}

	})

	m.Put("/users/:id", binding.Bind(User{}), func(args martini.Params, user User, r render.Render, authuser sessionauth.User) {

		//convert string to int64 so you can match the struct (passing userid via ajax does not work as it comes in as a string)
		f, _ := strconv.ParseInt(args["id"], 0, 64)

		//only allow the authenticated user to update his user attributes
		if authuser.UniqueId() == f {

			//specify the user id
			user.Id = f

			count, err := dbmap.Update(&user)
			checkErr(err, "Update failed")
			log.Println("Rows updated:", count)

			if count == 1 {
				newmap := map[string]interface{}{"responseText": "success"}
				r.JSON(200, newmap)
			} else {
				newmap := map[string]interface{}{"responseText": "error"}
				r.JSON(400, newmap)
			}

		} else {
			newmap := map[string]interface{}{"responseText": "You are not allowed to update this resource."}
			r.JSON(403, newmap)
		}

	})

	m.Delete("/users/:id", func(args martini.Params, r render.Render, authuser sessionauth.User) {

		//convert id from string to int64
		f, _ := strconv.ParseInt(args["id"], 0, 64)

		//only allow the authenticated user to delete him or her
		if authuser.UniqueId() == f {

			_, err = dbmap.Exec("delete from users where id=?", args["id"])
			checkErr(err, "Delete failed")

			if err == nil {
				newmap := map[string]interface{}{"responseText": "success"}
				r.JSON(200, newmap)
				//if you delete yourself, Ajax should redirec you
			} else {
				newmap := map[string]interface{}{"responseText": "error"}
				r.JSON(400, newmap)
			}

		} else {
			newmap := map[string]interface{}{"responseText": "You are not allowed to delete this resource."}
			r.JSON(403, newmap)
		}

	})

	m.Post("/posts", sessionauth.LoginRequired, binding.Bind(Post{}), func(post Post, r render.Render, authuser sessionauth.User) {

		//convert to int64
		f := authuser.UniqueId().(int64)
		p1 := newPost(post.Title, post.Body, f)

		err = dbmap.Insert(&p1)
		checkErr(err, "Insert failed")

		r.Redirect("/")
	})

	m.Get("/posts/:id", func(args martini.Params, r render.Render, authuser sessionauth.User) {

		var post Post

		err = dbmap.SelectOne(&post, "select * from posts where post_id=?", args["id"])

		//simple error check
		if err != nil {
			newmap := map[string]interface{}{"metatitle": "404 Error", "message": "This is not found"}
			r.HTML(404, "error", newmap)
		} else {
			newmap := map[string]interface{}{"metatitle": post.Title + " more custom", "authuser": authuser, "post": post}
			r.HTML(200, "post", newmap)
		}
	})

	m.Get("/p/:str", func(args martini.Params, r render.Render, authuser sessionauth.User) {

		var post Post

		err = dbmap.SelectOne(&post, "select * from posts where url=?", args["str"])

		//simple error check
		if err != nil {
			newmap := map[string]interface{}{"metatitle": "404 Error", "message": "This is not found"}
			r.HTML(404, "error", newmap)
		} else {
			newmap := map[string]interface{}{"metatitle": post.Title + " more custom", "authuser": authuser, "post": post}
			r.HTML(200, "post", newmap)
		}
	})

	m.Put("/posts/:id", binding.Bind(Post{}), func(args martini.Params, post Post, r render.Render, authuser sessionauth.User) {

		var newTitle = post.Title
		var newBody = post.Body

		err = dbmap.SelectOne(&post, "select * from posts where post_id=?", args["id"])

		//simple database error check
		if err != nil {
			newmap := map[string]interface{}{"message": "Something went wrong."}
			r.JSON(400, newmap)
		} else {

			//owner check
			if authuser.UniqueId() == post.UserId {

				post.Title = newTitle
				post.Body = newBody

				count, err := dbmap.Update(&post)
				checkErr(err, "Update failed")

				if count == 1 {
					newmap := map[string]interface{}{"responseText": "success"}
					r.JSON(200, newmap)
				} else {
					newmap := map[string]interface{}{"responseText": "error"}
					r.JSON(400, newmap)
				}

			} else {
				newmap := map[string]interface{}{"responseText": "You are not allowed to modify this resource."}
				r.JSON(403, newmap)
			}

		}

	})

	m.Delete("/posts/:id", func(args martini.Params, r render.Render, authuser sessionauth.User) {

		//retrieve the post to check the real owner
		var post Post
		err = dbmap.SelectOne(&post, "select * from posts where post_id=?", args["id"])

		//simple DB error check
		if err != nil {
			newmap := map[string]interface{}{"message": "Something went wrong."}
			r.JSON(400, newmap)
		} else {

			//owner check
			if authuser.UniqueId() == post.UserId {

				//delete it
				_, err := dbmap.Delete(&post)
				checkErr(err, "Delete failed")

				newmap := map[string]interface{}{"responseText": "success"}
				r.JSON(200, newmap)

			} else {
				newmap := map[string]interface{}{"responseText": "You are not allowed to delete this resource."}
				r.JSON(403, newmap)
			}

		}

	})

	m.Run()
}