Implement remote embedding of guestbooks #25
| @ -8,87 +8,94 @@ import ( | ||||
| 	"github.com/justinas/nosurf" | ||||
| ) | ||||
| 
 | ||||
| func (app *application) logRequest (next http.Handler) http.Handler { | ||||
|     return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||||
|         var ( | ||||
|             ip = r.RemoteAddr | ||||
|             proto = r.Proto | ||||
|             method = r.Method | ||||
|             uri = r.URL.RequestURI() | ||||
|         ) | ||||
|         app.logger.Info("received request", "ip", ip, "proto", proto, "method", method, "uri", uri) | ||||
|         next.ServeHTTP(w, r) | ||||
|     }) | ||||
| func (app *application) logRequest(next http.Handler) http.Handler { | ||||
| 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||||
| 		var ( | ||||
| 			ip     = r.RemoteAddr | ||||
| 			proto  = r.Proto | ||||
| 			method = r.Method | ||||
| 			uri    = r.URL.RequestURI() | ||||
| 		) | ||||
| 		app.logger.Info("received request", "ip", ip, "proto", proto, "method", method, "uri", uri) | ||||
| 		next.ServeHTTP(w, r) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func commonHeaders (next http.Handler) http.Handler { | ||||
|     return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||||
|         w.Header().Set("Content-Security-Policy", "default-src 'self'; style-src 'self' fonts.googleapis.com; font-src fonts.gstatic.com") | ||||
|         w.Header().Set("Referrer-Policy", "origin-when-cross-origin") | ||||
|         w.Header().Set("X-Content-Type-Options", "nosniff") | ||||
|         // w.Header().Set("X-Frame-Options", "deny") | ||||
|         w.Header().Set("X-XSS-Protection", "0") | ||||
|         next.ServeHTTP(w, r) | ||||
|     }) | ||||
| func commonHeaders(next http.Handler) http.Handler { | ||||
| 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||||
| 		w.Header().Set("Content-Security-Policy", "default-src 'self'; style-src 'self' fonts.googleapis.com; font-src fonts.gstatic.com") | ||||
| 		w.Header().Set("Referrer-Policy", "origin-when-cross-origin") | ||||
| 		w.Header().Set("X-Content-Type-Options", "nosniff") | ||||
| 		// w.Header().Set("X-Frame-Options", "deny") | ||||
| 		w.Header().Set("X-XSS-Protection", "0") | ||||
| 		next.ServeHTTP(w, r) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func (app *application) recoverPanic(next http.Handler) http.Handler { | ||||
|     return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||||
|         defer func() { | ||||
|             if err := recover(); err != nil { | ||||
|                 w.Header().Set("Connection", "close") | ||||
|                 app.serverError(w, r, fmt.Errorf("%s", err)) | ||||
|             } | ||||
|         }() | ||||
| 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||||
| 		defer func() { | ||||
| 			if err := recover(); err != nil { | ||||
| 				w.Header().Set("Connection", "close") | ||||
| 				app.serverError(w, r, fmt.Errorf("%s", err)) | ||||
| 			} | ||||
| 		}() | ||||
| 
 | ||||
|         next.ServeHTTP(w, r) | ||||
|     }) | ||||
| 		next.ServeHTTP(w, r) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func (app *application) requireAuthentication(next http.Handler) http.Handler { | ||||
|     return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||||
|         if !app.isAuthenticated(r) { | ||||
|             http.Redirect(w, r, "/users/login", http.StatusSeeOther) | ||||
|             return | ||||
|         } | ||||
|         w.Header().Add("Cache-Control", "no-store") | ||||
|         next.ServeHTTP(w, r) | ||||
|     }) | ||||
| 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||||
| 		if !app.isAuthenticated(r) { | ||||
| 			http.Redirect(w, r, "/users/login", http.StatusSeeOther) | ||||
| 			return | ||||
| 		} | ||||
| 		w.Header().Add("Cache-Control", "no-store") | ||||
| 		next.ServeHTTP(w, r) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func noSurf(next http.Handler) http.Handler { | ||||
|     csrfHandler := nosurf.New(next) | ||||
|     csrfHandler.SetBaseCookie(http.Cookie{ | ||||
|         HttpOnly: true, | ||||
|         Path: "/", | ||||
|         Secure: true, | ||||
|     }) | ||||
| 	csrfHandler := nosurf.New(next) | ||||
| 	csrfHandler.SetBaseCookie(http.Cookie{ | ||||
| 		HttpOnly: true, | ||||
| 		Path:     "/", | ||||
| 		Secure:   true, | ||||
| 	}) | ||||
| 
 | ||||
|     return csrfHandler | ||||
| 	return csrfHandler | ||||
| } | ||||
| 
 | ||||
| func (app *application) authenticate(next http.Handler) http.Handler { | ||||
|     return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||||
|         id := app.sessionManager.GetInt64(r.Context(), "authenticatedUserId") | ||||
|         if id == 0 { | ||||
|             next.ServeHTTP(w, r) | ||||
|             return | ||||
|         } | ||||
|         exists, err := app.users.Exists(id) | ||||
|         if err != nil { | ||||
|             app.serverError(w, r, err) | ||||
|             return | ||||
|         } | ||||
|         user, err := app.users.GetById(id) | ||||
|         if err != nil { | ||||
|             app.serverError(w, r, err) | ||||
|             return | ||||
|         } | ||||
|         if exists { | ||||
|             ctx := context.WithValue(r.Context(), isAuthenticatedContextKey, true) | ||||
|             ctx = context.WithValue(ctx, userNameContextKey, user) | ||||
|             r = r.WithContext(ctx) | ||||
|         } | ||||
|         next.ServeHTTP(w, r) | ||||
|     }) | ||||
| 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||||
| 		id := app.sessionManager.GetInt64(r.Context(), "authenticatedUserId") | ||||
| 		if id == 0 { | ||||
| 			next.ServeHTTP(w, r) | ||||
| 			return | ||||
| 		} | ||||
| 		exists, err := app.users.Exists(id) | ||||
| 		if err != nil { | ||||
| 			app.serverError(w, r, err) | ||||
| 			return | ||||
| 		} | ||||
| 		user, err := app.users.GetById(id) | ||||
| 		if err != nil { | ||||
| 			app.serverError(w, r, err) | ||||
| 			return | ||||
| 		} | ||||
| 		if exists { | ||||
| 			ctx := context.WithValue(r.Context(), isAuthenticatedContextKey, true) | ||||
| 			ctx = context.WithValue(ctx, userNameContextKey, user) | ||||
| 			r = r.WithContext(ctx) | ||||
| 		} | ||||
| 		next.ServeHTTP(w, r) | ||||
| 	}) | ||||
| } | ||||
| 
 | ||||
| func (app *application) enableCors(next http.Handler) http.Handler { | ||||
| 	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||||
| 		w.Header().Set("Access-Control-Allow-Origin", "*") | ||||
| 		next.ServeHTTP(w, r) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| @ -15,10 +15,11 @@ func (app *application) routes() http.Handler { | ||||
| 
 | ||||
| 	dynamic := alice.New(app.sessionManager.LoadAndSave, noSurf, app.authenticate) | ||||
| 	standard := alice.New(app.recoverPanic, app.logRequest, commonHeaders) | ||||
| 	withCors := standard.Append(app.enableCors) | ||||
| 
 | ||||
| 	mux.Handle("/{$}", dynamic.ThenFunc(app.home)) | ||||
| 	mux.Handle("GET /websites/{id}/guestbook", dynamic.ThenFunc(app.getGuestbook)) | ||||
| 	mux.Handle("GET /websites/{id}/guestbook/comments", standard.ThenFunc(app.getGuestbookCommentsSerialized)) | ||||
| 	mux.Handle("GET /websites/{id}/guestbook/comments", withCors.ThenFunc(app.getGuestbookCommentsSerialized)) | ||||
| 	mux.Handle("GET /websites/{id}/guestbook/comments/create", dynamic.ThenFunc(app.getGuestbookCommentCreate)) | ||||
| 	mux.Handle("POST /websites/{id}/guestbook/comments/create", dynamic.ThenFunc(app.postGuestbookCommentCreate)) | ||||
| 	mux.Handle("GET /users/register", dynamic.ThenFunc(app.getUserRegister)) | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user