diff --git a/assets/web/login.html b/assets/web/login.html
new file mode 100644
index 0000000..14bbadf
--- /dev/null
+++ b/assets/web/login.html
@@ -0,0 +1,25 @@
+
+
+
+
+ Login to Pogo Admin Page
+
+
+
+ Login
+
+
+
+
+
\ No newline at end of file
diff --git a/auth/auth.go b/auth/auth.go
index 2580d90..f354faa 100644
--- a/auth/auth.go
+++ b/auth/auth.go
@@ -1,17 +1,36 @@
package auth
import (
+ "crypto/aes"
+ "crypto/cipher"
+ "crypto/rand"
+ "encoding/hex"
+ "encoding/json"
+ "fmt"
+ "log"
"net/http"
+ "strings"
"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 {
+ if usr := decryptSession(r); usr != nil {
rc.User = usr
return nil
}
+
+ if strings.Contains(r.Header.Get("Accept"), "html") || r.Method == "GET" {
+ http.Redirect(w, r, "/login", http.StatusTemporaryRedirect)
+ return nil
+ } else {
+ return &common.HTTPError{
+ Message: "Unauthorized!",
+ StatusCode: http.StatusUnauthorized,
+ }
+ }
+
return &common.HTTPError{
Message: "Unauthorized!",
StatusCode: http.StatusUnauthorized,
@@ -19,12 +38,53 @@ func RequireAuthorization() common.Handler {
}
}
-func CreateSession() common.Handler {
- return func(rc *common.RouterContext, w http.ResponseWriter, r *http.Request) *common.HTTPError {
- return nil
- }
-}
+func CreateSession(u *common.User, w http.ResponseWriter) error {
+
+ // n_J6vaKjmmw4WB95DMorjQ.UMYdBLfttwPgQw9T0u0wdK7bGwDT9vwxoPAKWhjSAcpoiMsjh4eSfBkA4WB2deSoQu_cjCaJrcp77rvG67xkOeXsYpiclx2b-Oi7MHM3Kms.1507140277977.604800000.2CdxwiKAJT4SYJTVK-Du5jokr-CCnxo1ukdaVBkLRJg
+
+ iv, err := generateRandomString(16)
+ if err != nil {
+ return err
+ }
+ userJSON, err := json.Marshal(u)
+ if err != nil {
+ return err
+
+ }
+ var hexedJSON []byte
+ hex.Encode(hexedJSON, userJSON)
+
+ fmt.Println(iv, string(userJSON), hexedJSON)
+
+ block, err := aes.NewCipher(hexedJSON)
+ if err != nil {
+ return err
+ }
+ mode := cipher.NewCBCEncrypter(block, iv)
-func DecryptSession(r *http.Request) *common.User {
return nil
}
+
+func decryptSession(r *http.Request) *common.User {
+
+ c, err := r.Cookie("POGO_SESSION")
+ if err != nil {
+ if err != http.ErrNoCookie {
+ log.Printf("error in reading Cookie: %v", err)
+ }
+ return nil
+ }
+ fmt.Println(c)
+
+ return nil
+}
+
+func generateRandomString(l int) ([]byte, error) {
+ rBytes := make([]byte, l)
+
+ _, err := rand.Read(rBytes)
+ if err != nil {
+ return nil, err
+ }
+ return rBytes, nil
+}
diff --git a/common/common.go b/common/common.go
index 68bccb9..8b5b198 100644
--- a/common/common.go
+++ b/common/common.go
@@ -29,7 +29,7 @@ type RouterContext struct {
// User struct denotes the data is stored in the cookie
type User struct {
- Name string `json:"name"`
+ Username string `json:"username"`
}
// ReadAndServeFile reads the file from specified location and sends it in response
diff --git a/router/router.go b/router/router.go
index 1cc79d8..5a63fc3 100644
--- a/router/router.go
+++ b/router/router.go
@@ -65,9 +65,14 @@ func Init() *mux.Router {
// Authenticated endpoints should be passed to BasicAuth()
// first
r.Handle("/admin", Handle(
- auth.RequireAuthorization(),
+ // auth.RequireAuthorization(),
adminHandler(),
))
+
+ r.Handle("/login", Handle(
+ loginHandler(),
+ ))
+
// r.HandleFunc("/admin/publish", BasicAuth(CreateEpisode))
// r.HandleFunc("/admin/delete", BasicAuth(RemoveEpisode))
// r.HandleFunc("/admin/css", BasicAuth(CustomCss))
@@ -79,6 +84,71 @@ func Init() *mux.Router {
return r
}
+func loginHandler() common.Handler {
+ return func(rc *common.RouterContext, w http.ResponseWriter, r *http.Request) *common.HTTPError {
+
+ if r.Method == "GET" {
+ w.Header().Set("Content-Type", "text/html")
+ return common.ReadAndServeFile("assets/web/login.html", w)
+ }
+
+ d, err := ioutil.ReadFile("assets/config/users.json")
+ if err != nil {
+
+ return &common.HTTPError{
+ Message: fmt.Sprintf("error in reading users.json: %v", err),
+ StatusCode: http.StatusInternalServerError,
+ }
+
+ }
+
+ err = r.ParseForm()
+
+ if err != nil {
+ return &common.HTTPError{
+ Message: fmt.Sprintf("error in parsing form: %v", err),
+ StatusCode: http.StatusBadRequest,
+ }
+ }
+
+ username := r.Form.Get("username")
+ password := r.Form.Get("password")
+ if username == "" || password == "" {
+ return &common.HTTPError{
+ Message: "username or password is empty",
+ StatusCode: http.StatusBadRequest,
+ }
+ }
+
+ var u map[string]string
+ err = json.Unmarshal(d, &u) // Unmarshal into interface
+
+ // Iterate through map until we find matching username
+ for k, v := range u {
+ if k == username && v == password {
+ // Create a cookie here because the credentials are correct
+ err = auth.CreateSession(&common.User{
+ Username: k,
+ }, w)
+ if err != nil {
+ return &common.HTTPError{
+ Message: err.Error(),
+ StatusCode: http.StatusInternalServerError,
+ }
+ }
+ // And now redirect the user to admin page
+ http.Redirect(w, r, "/admin", http.StatusTemporaryRedirect)
+ return nil
+ }
+ }
+
+ return &common.HTTPError{
+ Message: "Invalid credentials!",
+ StatusCode: http.StatusUnauthorized,
+ }
+ }
+}
+
// Handles /, /feed and /json endpoints
func rootHandler() common.Handler {
return func(rc *common.RouterContext, w http.ResponseWriter, r *http.Request) *common.HTTPError {
@@ -139,10 +209,3 @@ func serveSetup() common.Handler {
return nil
}
}
-
-func redirectHandler() common.Handler {
- return func(rc *common.RouterContext, w http.ResponseWriter, r *http.Request) *common.HTTPError {
-
- return nil
- }
-}