Skip to content

Commit

Permalink
Refactoring Code
Browse files Browse the repository at this point in the history
  • Loading branch information
ishanjain28 committed Oct 3, 2017
1 parent 5fbb1e3 commit fc7d3dd
Show file tree
Hide file tree
Showing 5 changed files with 277 additions and 140 deletions.
30 changes: 30 additions & 0 deletions auth/auth.go
@@ -0,0 +1,30 @@
package auth

import (
"net/http"

"github.com/ishanjain28/pogo/common"
)

func RequireAuthorization() common.Handler {
return func(rc *common.RouterContext, w http.ResponseWriter, r *http.Request) *common.HTTPError {
if usr := DecryptSession(r); usr != nil {
rc.User = usr
return nil
}
return &common.HTTPError{
Message: "Unauthorized!",
StatusCode: http.StatusUnauthorized,
}
}
}

func CreateSession() common.Handler {
return func(rc *common.RouterContext, w http.ResponseWriter, r *http.Request) *common.HTTPError {
return nil
}
}

func DecryptSession(r *http.Request) *common.User {
return nil
}
66 changes: 66 additions & 0 deletions common/common.go
@@ -0,0 +1,66 @@
package common

import (
"fmt"
"io"
"log"
"net/http"
"os"
"strconv"
)

// Handler is the signature of HTTP Handler that is passed to Handle function
type Handler func(rc *RouterContext, w http.ResponseWriter, r *http.Request) *HTTPError

// HTTPError is any error that occurs in middlewares or the code that handles HTTP Frontend of application
// Message is logged to console and Status Code is sent in response
// If a Middleware sends an HTTPError, No middlewares further up in chain are executed
type HTTPError struct {
// Message to log in console
Message string
// Status code that'll be sent in response
StatusCode int
}

// RouterContext contains any information to be shared with middlewares.
type RouterContext struct {
User *User
}

// User struct denotes the data is stored in the cookie
type User struct {
Name string `json:"name"`
}

// ReadAndServeFile reads the file from specified location and sends it in response
func ReadAndServeFile(name string, w http.ResponseWriter) *HTTPError {
f, err := os.Open(name)
if err != nil {

if os.IsNotExist(err) {
return &HTTPError{
Message: fmt.Sprintf("%s not found", name),
StatusCode: http.StatusNotFound,
}
}

return &HTTPError{
Message: fmt.Sprintf("error in reading %s: %v\n", name, err),
StatusCode: http.StatusInternalServerError,
}
}

defer f.Close()
stats, err := f.Stat()
if err != nil {
log.Printf("error in fetching %s's stats: %v\n", name, err)
} else {
w.Header().Add("Content-Length", strconv.FormatInt(stats.Size(), 10))
}

_, err = io.Copy(w, f)
if err != nil {
log.Printf("error in copying %s to response: %v\n", name, err)
}
return nil
}
148 changes: 148 additions & 0 deletions router/router.go
@@ -0,0 +1,148 @@
package router

import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"strings"

"github.com/gorilla/mux"
"github.com/ishanjain28/pogo/auth"
"github.com/ishanjain28/pogo/common"
)

type NewConfig struct {
Name string
Host string
Email string
Description string
Image string
PodcastURL string
}

// Handle takes multiple Handler and executes them in a serial order starting from first to last.
// In case, Any middle ware returns an error, The error is logged to console and sent to the user, Middlewares further up in chain are not executed.
func Handle(handlers ...common.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

rc := &common.RouterContext{}
for _, handler := range handlers {
err := handler(rc, w, r)
if err != nil {
log.Printf("%v", err)

w.Write([]byte(http.StatusText(err.StatusCode)))

return
}
}
})
}

func Init() *mux.Router {

r := mux.NewRouter()

// "Static" paths
r.PathPrefix("/assets/").Handler(http.StripPrefix("/assets/", http.FileServer(http.Dir("assets/web/static"))))
r.PathPrefix("/download/").Handler(http.StripPrefix("/download/", http.FileServer(http.Dir("podcasts"))))

// Paths that require specific handlers
r.Handle("/", Handle(
rootHandler(),
)).Methods("GET")

r.Handle("/rss", Handle(
rootHandler(),
)).Methods("GET")

r.Handle("/json", Handle(
rootHandler(),
)).Methods("GET")

// Authenticated endpoints should be passed to BasicAuth()
// first
r.Handle("/admin", Handle(
auth.RequireAuthorization(),
adminHandler(),
))
// r.HandleFunc("/admin/publish", BasicAuth(CreateEpisode))
// r.HandleFunc("/admin/delete", BasicAuth(RemoveEpisode))
// r.HandleFunc("/admin/css", BasicAuth(CustomCss))

r.Handle("/setup", Handle(
serveSetup(),
)).Methods("GET", "POST")

return r
}

// Handles /, /feed and /json endpoints
func rootHandler() common.Handler {
return func(rc *common.RouterContext, w http.ResponseWriter, r *http.Request) *common.HTTPError {

var file string
switch r.URL.Path {
case "/rss":
w.Header().Set("Content-Type", "application/rss+xml")
file = "assets/web/feed.rss"
case "/json":
w.Header().Set("Content-Type", "application/json")
file = "assets/web/feed.json"
case "/":
w.Header().Set("Content-Type", "text/html")
file = "assets/web/index.html"
default:
return &common.HTTPError{
Message: fmt.Sprintf("%s: Not Found", r.URL.Path),
StatusCode: http.StatusNotFound,
}
}

return common.ReadAndServeFile(file, w)
}
}

func adminHandler() common.Handler {
return func(rc *common.RouterContext, w http.ResponseWriter, r *http.Request) *common.HTTPError {
return common.ReadAndServeFile("assets/web/admin.html", w)
}
}

// Serve setup.html and config parameters
func serveSetup() common.Handler {
return func(rc *common.RouterContext, w http.ResponseWriter, r *http.Request) *common.HTTPError {
if r.Method == "GET" {
return common.ReadAndServeFile("assets/web/setup.html", w)
}
r.ParseMultipartForm(32 << 20)

// Parse form and convert to JSON
cnf := NewConfig{
strings.Join(r.Form["podcastname"], ""), // Podcast name
strings.Join(r.Form["podcasthost"], ""), // Podcast host
strings.Join(r.Form["podcastemail"], ""), // Podcast host email
"", // Podcast image
"", // Podcast location
"", // Podcast location
}

b, err := json.Marshal(cnf)
if err != nil {
panic(err)
}

ioutil.WriteFile("assets/config/config.json", b, 0644)
w.Write([]byte("Done"))
return nil
}
}

func redirectHandler() common.Handler {
return func(rc *common.RouterContext, w http.ResponseWriter, r *http.Request) *common.HTTPError {

return nil
}
}
50 changes: 0 additions & 50 deletions setup.go

This file was deleted.

0 comments on commit fc7d3dd

Please sign in to comment.