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