Adding group creation support.
This commit is contained in:
parent
b0e9e7c35c
commit
cc509ec22a
177
wwwshop/controller/groupcontroller/groupcontroller.go
Normal file
177
wwwshop/controller/groupcontroller/groupcontroller.go
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
package groupcontroller
|
||||||
|
|
||||||
|
import (
|
||||||
|
d "WWWShop/wwwshop/dao/database"
|
||||||
|
u "WWWShop/wwwshop/dao/groupmanager"
|
||||||
|
"WWWShop/wwwshop/model/group"
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GroupController struct{}
|
||||||
|
|
||||||
|
func New() GroupController {
|
||||||
|
return GroupController{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self GroupController) DELETE(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ids, groupnames, _, err := self.SetupInputForFilter(w, r)
|
||||||
|
group_manager := u.New(d.DB())
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
if err != nil {
|
||||||
|
json_response,_ := EncodeJSONResponse(NewResponseError(err.Error()))
|
||||||
|
fmt.Fprintf(w, json_response)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deleted_groups, err := group_manager.Delete(ids, groupnames)
|
||||||
|
if err != nil {
|
||||||
|
json_response, _ := EncodeJSONResponse(NewResponseError(err.Error()))
|
||||||
|
fmt.Fprintf(w, json_response)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
deleted_groups_json, _ := EncodeJSONResponse(deleted_groups)
|
||||||
|
fmt.Fprintf(w, deleted_groups_json)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self GroupController) SetupInputForFilter(w http.ResponseWriter, r *http.Request) ([]int64, []string, *int64, error) {
|
||||||
|
query := r.URL.Query()
|
||||||
|
groupnames, _ := query["groupname"]
|
||||||
|
ids, _ := query["id"]
|
||||||
|
pages, _ := query["page"]
|
||||||
|
var page int64
|
||||||
|
if len(pages) == 0 {
|
||||||
|
page = 0
|
||||||
|
} else {
|
||||||
|
var err error
|
||||||
|
page, err = strconv.ParseInt(pages[0], 0, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, errors.New("Unable to parse int page.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ids_int := make([]int64, 0)
|
||||||
|
for _, id := range ids {
|
||||||
|
id_int, err := strconv.ParseInt(id, 0, 64)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, nil, errors.New("Unable to parse int id.")
|
||||||
|
}
|
||||||
|
ids_int = append(ids_int, id_int)
|
||||||
|
}
|
||||||
|
return ids_int, groupnames, &page, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self GroupController) PUT(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var decoded_group_struct group.Group
|
||||||
|
decoder := json.NewDecoder(r.Body)
|
||||||
|
err := decoder.Decode(&decoded_group_struct)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
|
||||||
|
json_response, _ := EncodeJSONResponse(NewResponseError("Failed to decode json group on update."))
|
||||||
|
fmt.Fprintf(w, json_response)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if decoded_group_struct.Id == nil && decoded_group_struct.Groupname == nil {
|
||||||
|
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
|
||||||
|
json_response, _ := EncodeJSONResponse(NewResponseError("Failed to get groupname or id needed to update groups."))
|
||||||
|
fmt.Fprintf(w, json_response)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if decoded_group_struct.Permissions == nil {
|
||||||
|
decoded_group_struct.Permissions = make(map[string]string)
|
||||||
|
}
|
||||||
|
group_manager := u.New(d.DB())
|
||||||
|
group, err := group_manager.Update(decoded_group_struct)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||||
|
json_response, _ := EncodeJSONResponse(NewResponseError(strings.Join([]string{"Failed to update group with the given data, may be our fault: ", err.Error()}, "")))
|
||||||
|
fmt.Fprintf(w, json_response)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
json_response, _ := EncodeJSONResponse(group)
|
||||||
|
fmt.Fprintf(w, json_response)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self GroupController) GET(w http.ResponseWriter, r *http.Request) {
|
||||||
|
group_manager := u.New(d.DB())
|
||||||
|
ids, groupnames, page, err := self.SetupInputForFilter(w, r)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
|
||||||
|
json_response, _ := EncodeJSONResponse(NewResponseError(err.Error()))
|
||||||
|
fmt.Fprintf(w, json_response)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
groups, err := group_manager.Retrieve(*page, ids, groupnames)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||||
|
json_response, _ := EncodeJSONResponse(NewResponseError(strings.Join([]string{"Unable to retrieve groups ", err.Error()}, "")))
|
||||||
|
fmt.Fprintf(w, json_response)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
json_response, _ := EncodeJSONResponse(groups)
|
||||||
|
fmt.Fprintf(w, json_response)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self GroupController) POST(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var decoded_group_struct POSTGroup
|
||||||
|
decoder := json.NewDecoder(r.Body)
|
||||||
|
err := decoder.Decode(&decoded_group_struct)
|
||||||
|
if err != nil {
|
||||||
|
json_response, _ := EncodeJSONResponse(NewResponseError("Unable to decode json"))
|
||||||
|
fmt.Fprintf(w, json_response)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if decoded_group_struct.Groupname == "" {
|
||||||
|
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
|
||||||
|
json_response, _ := EncodeJSONResponse(NewResponseError("Unable to get groupname"))
|
||||||
|
fmt.Fprintf(w, json_response)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if decoded_group_struct.Permissions == nil {
|
||||||
|
decoded_group_struct.Permissions = make(map[string]string)
|
||||||
|
}
|
||||||
|
group_manager := u.New(d.DB())
|
||||||
|
group, err := group_manager.Add(decoded_group_struct.Groupname, decoded_group_struct.Permissions)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||||
|
json_response, _ := EncodeJSONResponse(NewResponseError(strings.Join(
|
||||||
|
[]string{"Unable to create group ", err.Error()},
|
||||||
|
"")))
|
||||||
|
fmt.Fprintf(w, json_response)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
json_response, err := EncodeJSONResponse(group)
|
||||||
|
fmt.Fprintf(w, json_response)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Response interface{}
|
||||||
|
|
||||||
|
type ResponseError struct {
|
||||||
|
Error string `json:"error"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewResponseError(error_str string) ResponseError {
|
||||||
|
return ResponseError{
|
||||||
|
Error: error_str,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type POSTGroup struct {
|
||||||
|
Groupname string `json:"groupname"`
|
||||||
|
Permissions map[string]string `json:"permissions"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func EncodeJSONResponse(response Response) (string, error) {
|
||||||
|
var buffer bytes.Buffer
|
||||||
|
encoder := json.NewEncoder(&buffer)
|
||||||
|
err := encoder.Encode(response)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return buffer.String(), nil
|
||||||
|
}
|
217
wwwshop/dao/groupmanager/groupmanager.go
Normal file
217
wwwshop/dao/groupmanager/groupmanager.go
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
package groupmanager
|
||||||
|
|
||||||
|
import (
|
||||||
|
"WWWShop/wwwshop/model/group"
|
||||||
|
"database/sql"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/lib/pq/hstore"
|
||||||
|
"log"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GroupManager struct {
|
||||||
|
db *sql.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(db *sql.DB) GroupManager {
|
||||||
|
return GroupManager{db}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self GroupManager) Add(groupname string, permissions map[string]string) (*group.Group, error) {
|
||||||
|
var id int64
|
||||||
|
if permissions == nil {
|
||||||
|
permissions = make(map[string]string)
|
||||||
|
}
|
||||||
|
permissions_null := hstore.Hstore{
|
||||||
|
Map: make(map[string]sql.NullString),
|
||||||
|
}
|
||||||
|
for key, value := range permissions {
|
||||||
|
permissions_null.Map[key] = sql.NullString{
|
||||||
|
String: value,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result := self.db.QueryRow("INSERT INTO groups(groupname, permissions) VALUES ($1, $2) RETURNING id", groupname, permissions_null)
|
||||||
|
err := result.Scan(&id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
group := group.New(id, groupname, permissions)
|
||||||
|
return &group, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type QueryParameter interface{}
|
||||||
|
|
||||||
|
func (self GroupManager) GenerateWhere(cur_key *int64, ids []int64, groupnames []string) string {
|
||||||
|
where_string := "WHERE false "
|
||||||
|
if groupnames != nil && len(groupnames) > 0 {
|
||||||
|
where_string = strings.Join([]string{where_string, "OR ( false"}, "")
|
||||||
|
for range groupnames {
|
||||||
|
where_string = strings.Join([]string{where_string, fmt.Sprintf(" OR groupname = $%d", *cur_key)}, "")
|
||||||
|
(*cur_key)++
|
||||||
|
}
|
||||||
|
where_string = strings.Join([]string{where_string, " ) "}, "")
|
||||||
|
}
|
||||||
|
if ids != nil && len(ids) > 0 {
|
||||||
|
where_string = strings.Join([]string{where_string, "OR ( false"}, "")
|
||||||
|
for range ids {
|
||||||
|
where_string = strings.Join([]string{where_string, fmt.Sprintf(" OR id = $%d", *cur_key)}, "")
|
||||||
|
(*cur_key)++
|
||||||
|
}
|
||||||
|
where_string = strings.Join([]string{where_string, " ) "}, "")
|
||||||
|
}
|
||||||
|
return where_string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self GroupManager) Update(group group.Group) (*group.Group, error) {
|
||||||
|
if group.Id == nil && group.Groupname == nil {
|
||||||
|
return nil, errors.New("Both Id and Groupname cannot be null on the same time on UPDATE.")
|
||||||
|
}
|
||||||
|
if group.Permissions == nil {
|
||||||
|
return nil, errors.New("Should be at least a field for update .")
|
||||||
|
}
|
||||||
|
query := "UPDATE groups SET permissions = $1 WHERE true "
|
||||||
|
parameters := make([]interface{}, 0)
|
||||||
|
permissions_null := hstore.Hstore{
|
||||||
|
Map: make(map[string]sql.NullString),
|
||||||
|
}
|
||||||
|
for key, value := range group.Permissions {
|
||||||
|
log.Println(value)
|
||||||
|
permissions_null.Map[key] = sql.NullString{
|
||||||
|
String: value,
|
||||||
|
Valid: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parameters = append(parameters, permissions_null)
|
||||||
|
if group.Id != nil {
|
||||||
|
query = strings.Join([]string{query, "AND id = $2 "}, "")
|
||||||
|
parameters = append(parameters, *(group.Id))
|
||||||
|
} else {
|
||||||
|
query = strings.Join([]string{query, "AND groupname = $2 "}, "")
|
||||||
|
|
||||||
|
parameters = append(parameters, *(group.Groupname))
|
||||||
|
}
|
||||||
|
query = strings.Join([]string{query, " RETURNING id"}, "")
|
||||||
|
var id int64
|
||||||
|
result := self.db.QueryRow(query, parameters...)
|
||||||
|
err := result.Scan(&id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
groups, err := self.Retrieve(0, []int64{id}, nil)
|
||||||
|
group = groups[0]
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &group, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self GroupManager) Delete(ids []int64, groupnames []string) ([]string, error) {
|
||||||
|
var where bool
|
||||||
|
var cur_key int64
|
||||||
|
var where_string string
|
||||||
|
cur_key = 1
|
||||||
|
|
||||||
|
if ids != nil && len(ids) > 0 {
|
||||||
|
where = true
|
||||||
|
}
|
||||||
|
if groupnames != nil && len(groupnames) > 0 {
|
||||||
|
where = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if where {
|
||||||
|
where_string = self.GenerateWhere(&cur_key, ids, groupnames)
|
||||||
|
} else {
|
||||||
|
return nil, errors.New("Cannot delete without a clause")
|
||||||
|
}
|
||||||
|
|
||||||
|
query_parameters := make([]interface{}, 0)
|
||||||
|
for _, groupname := range groupnames {
|
||||||
|
query_parameters = append(query_parameters, groupname)
|
||||||
|
}
|
||||||
|
for _, id := range ids {
|
||||||
|
query_parameters = append(query_parameters, id)
|
||||||
|
}
|
||||||
|
query_string := fmt.Sprintf("DELETE FROM groups %s RETURNING groupname", where_string)
|
||||||
|
result, err := self.db.Query(
|
||||||
|
query_string,
|
||||||
|
query_parameters...,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer result.Close()
|
||||||
|
var deleted_groups []string
|
||||||
|
for result.Next() {
|
||||||
|
var groupname string
|
||||||
|
err := result.Scan(&groupname)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
deleted_groups = append(deleted_groups, groupname)
|
||||||
|
}
|
||||||
|
if deleted_groups == nil {
|
||||||
|
deleted_groups = make([]string, 0)
|
||||||
|
}
|
||||||
|
return deleted_groups, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self GroupManager) Retrieve(page int64, ids []int64, groupnames []string) ([]group.Group, error) {
|
||||||
|
var where bool
|
||||||
|
var cur_key int64
|
||||||
|
|
||||||
|
if ids != nil && len(ids) > 0 {
|
||||||
|
where = true
|
||||||
|
}
|
||||||
|
if groupnames != nil && len(groupnames) > 0 {
|
||||||
|
where = true
|
||||||
|
}
|
||||||
|
cur_key = 1
|
||||||
|
where_string := ""
|
||||||
|
if where {
|
||||||
|
where_string = self.GenerateWhere(&cur_key, ids, groupnames)
|
||||||
|
}
|
||||||
|
page = (10 * page)
|
||||||
|
page_string := fmt.Sprintf("LIMIT 10 OFFSET %d", page)
|
||||||
|
query_parameters := make([]interface{}, 0)
|
||||||
|
for _, groupname := range groupnames {
|
||||||
|
query_parameters = append(query_parameters, groupname)
|
||||||
|
}
|
||||||
|
for _, id := range ids {
|
||||||
|
query_parameters = append(query_parameters, id)
|
||||||
|
}
|
||||||
|
query_string := fmt.Sprintf("SELECT id, groupname, permissions from groups %s %s;", where_string, page_string)
|
||||||
|
result, err := self.db.Query(
|
||||||
|
query_string,
|
||||||
|
query_parameters...,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer result.Close()
|
||||||
|
var groups []group.Group
|
||||||
|
for result.Next() {
|
||||||
|
var (
|
||||||
|
id_group int64
|
||||||
|
groupname_group string
|
||||||
|
permissions_group_null hstore.Hstore
|
||||||
|
)
|
||||||
|
err := result.Scan(&id_group, &groupname_group, &permissions_group_null)
|
||||||
|
permissions_group := make(map[string]string)
|
||||||
|
for key, permission_null := range permissions_group_null.Map {
|
||||||
|
if permission_null.Valid {
|
||||||
|
permissions_group[key] = permission_null.String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
u := group.New(id_group, groupname_group, permissions_group)
|
||||||
|
groups = append(groups, u)
|
||||||
|
}
|
||||||
|
if groups == nil {
|
||||||
|
groups = make([]group.Group, 0)
|
||||||
|
}
|
||||||
|
return groups, nil
|
||||||
|
}
|
33
wwwshop/model/group/group.go
Normal file
33
wwwshop/model/group/group.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package group
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Group struct {
|
||||||
|
Id *int64 `json:"id"`
|
||||||
|
Groupname *string `json:"groupname"`
|
||||||
|
Permissions map[string]string `json:"permissions"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(id int64, groupname string, permissions map[string]string) Group {
|
||||||
|
return Group{
|
||||||
|
Id: &id,
|
||||||
|
Groupname: &groupname,
|
||||||
|
Permissions: permissions,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self Group) HasPermission(permission string) string {
|
||||||
|
perm_value, ok := self.Permissions[permission]
|
||||||
|
if ok {
|
||||||
|
if perm_value == "yes" {
|
||||||
|
return "yes"
|
||||||
|
}
|
||||||
|
if perm_value == "no" {
|
||||||
|
return "no"
|
||||||
|
}
|
||||||
|
log.Printf("Invalid permission value for %s in group %s.\n", permission, self.Groupname)
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
@ -4,6 +4,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
c "WWWShop/wwwshop/controller"
|
c "WWWShop/wwwshop/controller"
|
||||||
u "WWWShop/wwwshop/controller/usercontroller"
|
u "WWWShop/wwwshop/controller/usercontroller"
|
||||||
|
g "WWWShop/wwwshop/controller/groupcontroller"
|
||||||
d "WWWShop/wwwshop/dao/database"
|
d "WWWShop/wwwshop/dao/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -18,7 +19,8 @@ func New() WWWShop {
|
|||||||
func (self WWWShop) Init() {
|
func (self WWWShop) Init() {
|
||||||
d.Migrate(d.DB())
|
d.Migrate(d.DB())
|
||||||
user_controller := c.GenerateController(u.New())
|
user_controller := c.GenerateController(u.New())
|
||||||
|
group_controller := c.GenerateController(g.New())
|
||||||
|
http.Handle("/group", group_controller)
|
||||||
http.Handle("/user", user_controller)
|
http.Handle("/user", user_controller)
|
||||||
http.Handle("/user/", user_controller)
|
|
||||||
http.ListenAndServe(":8080", nil)
|
http.ListenAndServe(":8080", nil)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user