josephspurrier / gowebapp

Basic MVC Web Application in Go
MIT License
1.14k stars 197 forks source link

enhancement: decorator-like func for controller actions #10

Closed cleesmith closed 8 years ago

cleesmith commented 8 years ago

Just thought it might be useful in larger web apps that allow only authenticated users for most actions and pages to have a LoginRequired func somewhere in the package controller like:

func LoginRequired(w http.ResponseWriter, r *http.Request) *sessions.Session {
    // kind of like a decorator for controller actions
    // similar to rails controller "before_action :authenticate_user!"
    session := session.Instance(r)
    if session.Values["id"] == nil {
        // user has not logged in, so redirect to login page:
        http.Redirect(w, r, "/login", http.StatusFound)
        return session
    }
    return session
}

func Index(w http.ResponseWriter, r *http.Request) {
    session := LoginRequired(w, r)
    v := view.New(r)
    v.Name = "home/index"
    v.Vars["name"] = session.Values["name"]
    v.Render(w)
    // the previous code which is often repeated in controller actions:
    // session := session.Instance(r)
    // if session.Values["id"] != nil {
    //  v := view.New(r)
    //  v.Name = "home/index"
    //  v.Vars["name"] = session.Values["name"]
    //  v.Render(w)
    // } else {
    //  http.Redirect(w, r, "/login", http.StatusFound)
    //  return
    // }
}

... this would be much DRY-er code wise. See: nsmsearch Not really a proper decorator like here but it works. Thoughts?

josephspurrier commented 8 years ago

Current, I control permissions through middleware and routes because I feel it's easier to change those permissions in routes than having to modify code in the controller: https://github.com/josephspurrier/gowebapp/blob/master/route/route.go#L66

Is it a better practice to add that code to the controller?

cleesmith commented 8 years ago

I was just repeating a pattern that's common in ruby/Rails and python/Flask apps. So there should be something like acl.AuthenticatedOnly in route/middleware/acl/acl.go ?

josephspurrier commented 8 years ago

Ah, gotcha. Yeah, you can use acl.DisallowAnon. It does the same thing.

https://github.com/josephspurrier/gowebapp/blob/master/route/middleware/acl/acl.go#L26

cleesmith commented 8 years ago

I see. This is better, even DRY-er. Thanks.