Added user permissions!

This commit is contained in:
gmemstr 2017-11-29 12:56:51 -08:00
parent ddc9ff3aeb
commit a3c6143014
4 changed files with 86 additions and 38 deletions

View file

@ -7,30 +7,32 @@
package admin package admin
import ( import (
"database/sql"
"encoding/json"
"fmt" "fmt"
"golang.org/x/crypto/bcrypt"
"io" "io"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"os" "os"
"strings" "strings"
"encoding/json"
"golang.org/x/crypto/bcrypt"
"database/sql"
_ "github.com/mattn/go-sqlite3"
"github.com/gorilla/mux" "github.com/gorilla/mux"
_ "github.com/mattn/go-sqlite3"
"github.com/gmemstr/pogo/common" "github.com/gmemstr/pogo/common"
) )
type User struct { type User struct {
Id int `json:"id"` Id int `json:"id"`
Dbun string `json:"username"` Dbun string `json:"username"`
Dbrn string `json:"realname"` Dbrn string `json:"realname"`
Dbem string `json:"email"` Dbem string `json:"email"`
} }
type UserList struct { type UserList struct {
Users []User Users []User
} }
/* /*
* The following is a set of admin commands * The following is a set of admin commands
* that the average user probably shouldn't be * that the average user probably shouldn't be
@ -71,7 +73,7 @@ func AddUser() common.Handler {
hash, err := bcrypt.GenerateFromPassword([]byte(password), 4) hash, err := bcrypt.GenerateFromPassword([]byte(password), 4)
_, err = statement.Exec(username,hash,realname,email) _, err = statement.Exec(username, hash, realname, email)
if err != nil { if err != nil {
return &common.HTTPError{ return &common.HTTPError{
Message: fmt.Sprintf("error executing sqlite3 statement: %v", err), Message: fmt.Sprintf("error executing sqlite3 statement: %v", err),
@ -160,7 +162,7 @@ func EditUser() common.Handler {
pwhash, err = bcrypt.GenerateFromPassword([]byte(newpassword), 4) pwhash, err = bcrypt.GenerateFromPassword([]byte(newpassword), 4)
} }
_, err = statement.Exec(username,pwhash,realname,email,id) _, err = statement.Exec(username, pwhash, realname, email, id)
if err != nil { if err != nil {
return &common.HTTPError{ return &common.HTTPError{
Message: fmt.Sprintf("error executing sqlite3 statement: %v", err), Message: fmt.Sprintf("error executing sqlite3 statement: %v", err),
@ -328,15 +330,15 @@ func EditEpisode() common.Handler {
fmt.Println(filename) fmt.Println(filename)
description := strings.Join(r.Form["description"], "") description := strings.Join(r.Form["description"], "")
if ("./podcasts" + PreviousFilename + ".mp3" != filename) { if "./podcasts"+PreviousFilename+".mp3" != filename {
err = os.Rename("./podcasts/" + PreviousFilename + ".mp3", filename) err = os.Rename("./podcasts/"+PreviousFilename+".mp3", filename)
if err != nil { if err != nil {
return &common.HTTPError{ return &common.HTTPError{
Message: err.Error(), Message: err.Error(),
StatusCode: http.StatusBadRequest, StatusCode: http.StatusBadRequest,
} }
} }
err = os.Rename("./podcasts/" + PreviousFilename + "_SHOWNOTES.md", shownotes) err = os.Rename("./podcasts/"+PreviousFilename+"_SHOWNOTES.md", shownotes)
if err != nil { if err != nil {
return &common.HTTPError{ return &common.HTTPError{
Message: err.Error(), Message: err.Error(),

Binary file not shown.

View file

@ -6,6 +6,7 @@ import (
"crypto/hmac" "crypto/hmac"
"crypto/rand" "crypto/rand"
"crypto/sha256" "crypto/sha256"
"database/sql"
"encoding/base64" "encoding/base64"
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
@ -13,8 +14,10 @@ import (
"fmt" "fmt"
"log" "log"
"net/http" "net/http"
"strings"
"os" "os"
"strings"
_ "github.com/mattn/go-sqlite3"
"github.com/gmemstr/pogo/common" "github.com/gmemstr/pogo/common"
) )
@ -27,7 +30,39 @@ const (
cookieExpiry = 60 * 60 * 24 * 30 // 30 days in seconds cookieExpiry = 60 * 60 * 24 * 30 // 30 days in seconds
) )
func RequireAuthorization() common.Handler { func UserPermissions(username string, permission int) (bool, error) {
db, err := sql.Open("sqlite3", "assets/config/users.db")
defer db.Close()
isAllowed := false
if err != nil {
return isAllowed, err
}
statement, err := db.Prepare("SELECT permissions FROM users WHERE username=?")
if err != nil {
return isAllowed, err
}
rows, err := statement.Query(username)
if err != nil {
return isAllowed, err
}
var level int
for rows.Next() {
err = rows.Scan(&level)
if err != nil {
return isAllowed, err
}
if level >= permission {
isAllowed = true
}
}
return isAllowed, nil
}
func RequireAuthorization(permission int) common.Handler {
return func(rc *common.RouterContext, w http.ResponseWriter, r *http.Request) *common.HTTPError { return func(rc *common.RouterContext, w http.ResponseWriter, r *http.Request) *common.HTTPError {
usr, err := DecryptCookie(r) usr, err := DecryptCookie(r)
if err != nil { if err != nil {
@ -46,6 +81,17 @@ func RequireAuthorization() common.Handler {
} }
rc.User = usr rc.User = usr
username := rc.User.Username
hasPermission, err := UserPermissions(string(username), permission)
if !hasPermission {
return &common.HTTPError{
Message: "Unauthorized! Redirecting to /admin",
StatusCode: http.StatusUnauthorized,
}
}
return nil return nil
} }
} }

View file

@ -1,21 +1,21 @@
package router package router
import ( import (
"database/sql"
"encoding/json" "encoding/json"
"fmt" "fmt"
"golang.org/x/crypto/bcrypt"
"io/ioutil" "io/ioutil"
"log" "log"
"net/http" "net/http"
"strings" "strings"
"golang.org/x/crypto/bcrypt"
"database/sql"
_ "github.com/mattn/go-sqlite3" _ "github.com/mattn/go-sqlite3"
"github.com/gorilla/mux"
"github.com/gmemstr/pogo/admin" "github.com/gmemstr/pogo/admin"
"github.com/gmemstr/pogo/auth" "github.com/gmemstr/pogo/auth"
"github.com/gmemstr/pogo/common" "github.com/gmemstr/pogo/common"
"github.com/gorilla/mux"
) )
type NewConfig struct { type NewConfig struct {
@ -70,7 +70,7 @@ func Init() *mux.Router {
// Authenticated endpoints should be passed to BasicAuth() // Authenticated endpoints should be passed to BasicAuth()
// first // first
r.Handle("/admin", Handle( r.Handle("/admin", Handle(
auth.RequireAuthorization(), auth.RequireAuthorization(0),
adminHandler(), adminHandler(),
)).Methods("GET", "POST") )).Methods("GET", "POST")
@ -79,45 +79,45 @@ func Init() *mux.Router {
)).Methods("GET", "POST") )).Methods("GET", "POST")
r.Handle("/admin/publish", Handle( r.Handle("/admin/publish", Handle(
auth.RequireAuthorization(), auth.RequireAuthorization(0),
admin.CreateEpisode(), admin.CreateEpisode(),
)).Methods("POST") )).Methods("POST")
r.Handle("/admin/edituser", Handle( r.Handle("/admin/edituser", Handle(
auth.RequireAuthorization(), auth.RequireAuthorization(2),
admin.EditUser(), admin.EditUser(),
)).Methods("POST") )).Methods("POST")
r.Handle("/admin/newuser", Handle( r.Handle("/admin/newuser", Handle(
auth.RequireAuthorization(), auth.RequireAuthorization(2),
admin.AddUser(), admin.AddUser(),
)).Methods("POST") )).Methods("POST")
r.Handle("/admin/deleteuser/{id}", Handle( r.Handle("/admin/deleteuser/{id}", Handle(
auth.RequireAuthorization(), auth.RequireAuthorization(2),
admin.DeleteUser(), admin.DeleteUser(),
)).Methods("GET") )).Methods("GET")
r.Handle("/admin/edit", Handle( r.Handle("/admin/edit", Handle(
auth.RequireAuthorization(), auth.RequireAuthorization(0),
admin.EditEpisode(), admin.EditEpisode(),
)).Methods("POST") )).Methods("POST")
r.Handle("/admin/delete", Handle( r.Handle("/admin/delete", Handle(
auth.RequireAuthorization(), auth.RequireAuthorization(0),
admin.RemoveEpisode(), admin.RemoveEpisode(),
)).Methods("GET") )).Methods("GET")
r.Handle("/admin/css", Handle( r.Handle("/admin/css", Handle(
auth.RequireAuthorization(), auth.RequireAuthorization(2),
admin.CustomCss(), admin.CustomCss(),
)).Methods("GET", "POST") )).Methods("GET", "POST")
r.Handle("/admin/adduser", Handle( r.Handle("/admin/adduser", Handle(
auth.RequireAuthorization(), auth.RequireAuthorization(1),
admin.AddUser(), admin.AddUser(),
)).Methods("POST") )).Methods("POST")
r.Handle("/admin/listusers", Handle( r.Handle("/admin/listusers", Handle(
auth.RequireAuthorization(), auth.RequireAuthorization(1),
admin.ListUsers(), admin.ListUsers(),
)).Methods("GET") )).Methods("GET")
@ -169,13 +169,14 @@ func loginHandler() common.Handler {
StatusCode: http.StatusBadRequest, StatusCode: http.StatusBadRequest,
} }
} }
var id int var id int
var dbun string var dbun string
var dbhsh string var dbhsh string
var dbrn string var dbrn string
var dbem string var dbem string
var dbperm int
for rows.Next() { for rows.Next() {
err := rows.Scan(&id,&dbun,&dbhsh,&dbrn,&dbem) err := rows.Scan(&id, &dbun, &dbhsh, &dbrn, &dbem, &dbperm)
if err != nil { if err != nil {
return &common.HTTPError{ return &common.HTTPError{
Message: fmt.Sprintf("error in decoding sql data", err), Message: fmt.Sprintf("error in decoding sql data", err),
@ -186,7 +187,7 @@ func loginHandler() common.Handler {
} }
// Create a cookie here because the credentials are correct // Create a cookie here because the credentials are correct
if dbun == username && bcrypt.CompareHashAndPassword([]byte(dbhsh), []byte(password)) == nil { if dbun == username && bcrypt.CompareHashAndPassword([]byte(dbhsh), []byte(password)) == nil {
c, err := auth.CreateSession(&common.User{ c, err := auth.CreateSession(&common.User{
Username: username, Username: username,
}) })
if err != nil { if err != nil {
@ -204,7 +205,6 @@ func loginHandler() common.Handler {
return nil return nil
} }
return &common.HTTPError{ return &common.HTTPError{
Message: "Invalid credentials!", Message: "Invalid credentials!",
StatusCode: http.StatusUnauthorized, StatusCode: http.StatusUnauthorized,