Пример #1
0
// Returns a generic OAuth 2.0 backend endpoint.
func NewOAuth2Provider(config *Config, authUrl, tokenUrl string) negroni.HandlerFunc {
	c := &oauth2.Config{
		ClientID:     config.ClientID,
		ClientSecret: config.ClientSecret,
		Scopes:       config.Scopes,
		RedirectURL:  config.RedirectURL,
		Endpoint: oauth2.Endpoint{
			AuthURL:  authUrl,
			TokenURL: tokenUrl,
		},
	}

	maskedValues = make(map[string][]byte)

	return func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {

		s := sessions.GetSession(r)

		if r.Method == "GET" {
			switch r.URL.Path {
			case PathLogin:
				login(c, s, w, r)
			case PathLogout:
				logout(s, w, r)
			case PathCallback:
				handleOAuth2Callback(c, s, w, r)
			default:
				next(w, r)
			}
		} else {
			next(w, r)
		}

	}
}
Пример #2
0
// Edit show the edition form for articles.
func Edit(w http.ResponseWriter, r *http.Request, p httprouter.Params) {

	// Ensure the user is logged
	if sessions.GetSession(r).Get("logged") != true {
		http.Error(w, "Unauthorized", http.StatusUnauthorized)
		return
	}

	var article Article

	// Get the article from the database.
	err := database.Get(&article, "SELECT * FROM articles WHERE slug = ?", p.ByName("slug"))
	if err != nil && err != sql.ErrNoRows {
		panic(err)
	}

	if err == sql.ErrNoRows {
		http.Error(w, "Page not found", http.StatusNotFound)
		return
	}

	render(w, r, "article_edit", map[string]interface{}{
		"Title":   "Edit " + article.Title,
		"Article": article,
	})
}
Пример #3
0
// Returns a generic OAuth 2.0 backend endpoint.
func NewOAuth2Provider(opts *Options, authUrl, tokenUrl string) negroni.HandlerFunc {
	config := &oauth2.Config{
		ClientID:     opts.ClientID,
		ClientSecret: opts.ClientSecret,
		Scopes:       opts.Scopes,
		RedirectURL:  opts.RedirectURL,
		Endpoint: oauth2.Endpoint{
			AuthURL:  authUrl,
			TokenURL: tokenUrl,
		},
	}

	return func(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
		s := sessions.GetSession(r)

		if r.Method == "GET" {
			switch r.URL.Path {
			case PathLogin:
				login(opts, config, s, rw, r)
			case PathLogout:
				logout(s, rw, r)
			case PathCallback:
				handleOAuth2Callback(opts, config, s, rw, r)
			default:
				next(rw, r)
			}
		} else {
			next(rw, r)
		}

	}
}
Пример #4
0
// View handle the displaying of articles.
func View(w http.ResponseWriter, r *http.Request, p httprouter.Params) {

	var article Article

	err := database.Get(&article, "SELECT * FROM articles WHERE slug = ?", p.ByName("slug"))
	if err != nil && err != sql.ErrNoRows {
		panic(err)
	}

	if err == sql.ErrNoRows {
		http.Error(w, "Page not found", http.StatusNotFound)
		return
	}

	// Reject the request if the user isn't logged and that the article isn't published.
	if sessions.GetSession(r).Get("logged") != true && !article.IsPublished {
		http.Error(w, "Unauthorized", http.StatusUnauthorized)
		return
	}

	render(w, r, "article", map[string]interface{}{
		"Title":   article.Title,
		"Article": article,
	})
}
Пример #5
0
// Update do the actual modification of the article in the database.
func Update(w http.ResponseWriter, r *http.Request, p httprouter.Params) {

	// Ensure the user is logged.
	if sessions.GetSession(r).Get("logged") != true {
		http.Error(w, "Unauthorized", http.StatusUnauthorized)
		return
	}

	var article Article

	err := database.Get(&article, "SELECT * FROM articles WHERE slug = ?", p.ByName("slug"))
	if err != nil && err != sql.ErrNoRows {
		panic(err)
	}

	if err == sql.ErrNoRows {
		http.Error(w, "Page not found", http.StatusNotFound)
		return
	}

	// Validate the request's form data for the article.
	var v = NewValidator(r)
	v.NotEmpty("title")
	v.MaxLen("title", 150)
	v.NotEmpty("slug")
	v.MaxLen("slug", 150)
	v.DoesntExists("slug", "articles", "slug", article.Slug)
	v.NotEmpty("tagline")
	v.MaxLen("tagline", 450)
	v.NotEmpty("text")

	// In case of error, forward them to the next request.
	if v.HasErrors() {
		sessions.GetSession(r).AddFlash(v.Errors(), "_errors")
		sessions.GetSession(r).AddFlash(r.Form, "_inputs")
		http.Redirect(w, r, "/article/"+article.Slug+"/edit", http.StatusFound)
		return
	}

	// If everything is fine, update the article in the database.
	_, err = database.Exec("UPDATE articles SET title = ?, slug = ?, tagline = ?, text = ?, tags = ?, updated_at = datetime('now') WHERE id = ?", r.FormValue("title"), r.FormValue("slug"), r.FormValue("tagline"), r.FormValue("text"), r.FormValue("tags"), article.ID)
	if err != nil {
		panic(err)
	}

	http.Redirect(w, r, "/article/"+r.FormValue("slug"), http.StatusFound)
}
Пример #6
0
func GetToken(r *http.Request) Tokens {
	s := sessions.GetSession(r)
	t := unmarshallToken(s)

	//not doing this doesn't pass through the
	//nil return, causing a test to fail - not sure why??
	if t == nil {
		return nil
	} else {
		return t
	}
}
Пример #7
0
// render write the given template on a response writer.
func render(w http.ResponseWriter, r *http.Request, name string, data map[string]interface{}) {
	data["Logged"] = sessions.GetSession(r).Get("logged")
	data["Configuration"] = configuration

	var rawErrors = sessions.GetSession(r).Flashes("_errors")
	if len(rawErrors) != 0 {
		data["Errors"] = rawErrors[0].([]string)
	}

	var rawInputs = sessions.GetSession(r).Flashes("_inputs")
	if len(rawInputs) != 0 {
		data["Inputs"] = rawInputs[0].(*url.Values)
	}

	out, err := templates.Render(name, data)
	if err != nil {
		http.Error(w, "error while generating the page:"+err.Error(), http.StatusInternalServerError)
	}

	w.Write([]byte(out))
}
Пример #8
0
// Write display the form for writing articles.
func Write(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {

	// Ensure the user is logged.
	if sessions.GetSession(r).Get("logged") != true {
		http.Error(w, "Unauthorized", http.StatusUnauthorized)
		return
	}

	render(w, r, "article_form", map[string]interface{}{
		"Title": "Write",
	})
}
Пример #9
0
func SetToken(r *http.Request, t interface{}) {
	s := sessions.GetSession(r)
	val, _ := json.Marshal(t)
	s.Set(keyToken, val)
	//Check immediately to see if the token is expired
	tk := unmarshallToken(s)
	if tk != nil {
		// check if the access token is expired
		if !tk.Valid() && tk.Refresh() == "" {
			s.Delete(keyToken)
			tk = nil
		}
	}
}
Пример #10
0
// Authenticate check the user credentials.
func Authenticate(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {

	if subtle.ConstantTimeEq(int32(len(r.FormValue("password"))), int32(len(configuration.Password))) == 0 {
		http.Redirect(w, r, "/login", http.StatusFound)
		return
	}

	if subtle.ConstantTimeCompare([]byte(r.FormValue("password")), []byte(configuration.Password)) == 0 {
		http.Redirect(w, r, "/login", http.StatusFound)
		return
	}

	sessions.GetSession(r).Set("logged", true)
	http.Redirect(w, r, "/read", http.StatusFound)
}
Пример #11
0
// Create validate and add new articles in the database.
func Create(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {

	// Ensure the user is logged.
	if sessions.GetSession(r).Get("logged") != true {
		http.Error(w, "Unauthorized", http.StatusUnauthorized)
		return
	}

	// Validate the request form data.
	var v = NewValidator(r)
	v.NotEmpty("title")
	v.MaxLen("title", 150)
	v.NotEmpty("slug")
	v.MaxLen("slug", 150)
	v.DoesntExists("slug", "articles", "slug")
	v.NotEmpty("tagline")
	v.MaxLen("tagline", 450)
	v.NotEmpty("text")

	// In case of error, return the user to the previous page with a listing of
	// the errors and inputs.
	if v.HasErrors() {
		sessions.GetSession(r).AddFlash(v.Errors(), "_errors")
		sessions.GetSession(r).AddFlash(r.Form, "_inputs")
		http.Redirect(w, r, "/write", http.StatusFound)
		return
	}

	// Insert the new article in the database.
	_, err := database.Exec("INSERT INTO articles (title, slug, tagline, text, tags, is_published, created_at, updated_at, published_at) VALUES (?, ?, ?, ?, ?, ?, datetime('now'), datetime('now'), datetime('now'))", r.FormValue("title"), r.FormValue("slug"), r.FormValue("tagline"), r.FormValue("text"), r.FormValue("tags"), false)
	if err != nil {
		panic(err)
	}

	http.Redirect(w, r, "/article/"+r.FormValue("slug"), http.StatusFound)
}
Пример #12
0
// Delete remove articles.
func Delete(w http.ResponseWriter, r *http.Request, p httprouter.Params) {

	// Ensure the user is logged.
	if sessions.GetSession(r).Get("logged") != true {
		http.Error(w, "Unauthorized", http.StatusUnauthorized)
		return
	}

	// Remote the article from the database.
	_, err := database.Exec("DELETE FROM articles WHERE slug = ?", p.ByName("slug"))
	if err != nil {
		panic(err)
	}

	http.Redirect(w, r, "/read", http.StatusFound)
}
Пример #13
0
// Unpublish switch off visibility of an article.
func Unpublish(w http.ResponseWriter, r *http.Request, p httprouter.Params) {

	// Ensure the user is logged.
	if sessions.GetSession(r).Get("logged") != true {
		http.Error(w, "Unauthorized", http.StatusUnauthorized)
		return
	}

	// Switch the flag off.
	_, err := database.Exec("UPDATE articles SET is_published = ? WHERE slug = ?", false, p.ByName("slug"))
	if err != nil {
		panic(err)
	}

	http.Redirect(w, r, r.Referer(), http.StatusFound)
}
Пример #14
0
// List show all articles available to the user.
func List(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {

	var articles []*Article

	// If the user isn't logged, only show published articles and order them by publication date.
	// If the user is logged, show all articles and order them by creation date.
	var err error
	if sessions.GetSession(r).Get("logged") != true {
		err = database.Select(&articles, "SELECT * FROM articles WHERE is_published = ? ORDER BY published_at DESC", true)
	} else {
		err = database.Select(&articles, "SELECT * FROM articles ORDER BY published_at DESC")
	}
	if err != nil {
		panic(err)
	}

	render(w, r, "article_list", map[string]interface{}{
		"Title":    "Read",
		"Articles": articles,
	})
}
Пример #15
0
// Logout de-authenticate the user.
func Logout(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {

	sessions.GetSession(r).Clear()
	http.Redirect(w, r, r.Referer(), http.StatusFound)
}