From 33f7f52f6facd04ee162dc6a3de12b446b5221b4 Mon Sep 17 00:00:00 2001 From: Martin Geno Date: Sun, 11 Sep 2016 18:40:33 +0200 Subject: [PATCH] [web] permissions added --- cmd/warehost/config.yml.example | 2 +- modul/web/api.go | 11 +++-- modul/web/apipermission.go | 71 ++++++++++++++++++++++++++++ modul/web/models.go | 10 ++-- system/api.go | 84 +++++++++++++++++++++++++++------ system/models.go | 5 +- webroot | 2 +- 7 files changed, 158 insertions(+), 27 deletions(-) create mode 100644 modul/web/apipermission.go diff --git a/cmd/warehost/config.yml.example b/cmd/warehost/config.yml.example index 4f2d6ad..32f39c2 100644 --- a/cmd/warehost/config.yml.example +++ b/cmd/warehost/config.yml.example @@ -7,7 +7,7 @@ log: path: test.log webroot: ./webroot/build database: "host=localhost user=warehost dbname=warehost password=hallo sslmode=disable" -databasedebug: true +databasedebug: false modules: web: enabled: true diff --git a/modul/web/api.go b/modul/web/api.go index 2021791..07d3cec 100644 --- a/modul/web/api.go +++ b/modul/web/api.go @@ -37,6 +37,9 @@ func NewAPI(config *libconfig.Config, sessions *session.Manager, dbconnection *g router.POST(prefix+"/website", libsystem.LoginHandler(api.WebsiteAdd, sessions)) router.PUT(prefix+"/website/:websiteid", InvolveWebsiteHandler(api.WebsiteEdit, sessions, dbconnection)) router.DELETE(prefix+"/website/:websiteid", InvolveWebsiteHandler(api.WebsiteDelete, sessions, dbconnection)) + router.GET(prefix+"/website/:websiteid/permission", InvolveWebsiteHandler(api.PermissionList, sessions, dbconnection)) + router.POST(prefix+"/website/:websiteid/permission/:loginid", InvolveWebsiteHandler(api.PermissionAdd, sessions, dbconnection)) + router.DELETE(prefix+"/website/:websiteid/permission/:loginid", InvolveWebsiteHandler(api.PermissionDelete, sessions, dbconnection)) } // Involve to get Website where loggend in user has privilegs @@ -45,7 +48,7 @@ func (api *API) Involve(w http.ResponseWriter, r *http.Request, _ httprouter.Par logger := api.log.GetLog(r, "involve") var involved []*Manager api.dbconnection.Where("login = ?", login.ID).Preload("Website").Find(&involved) - logger.Info("okay") + logger.Info("done") returndata = involved return } @@ -81,7 +84,7 @@ func (api *API) WebsiteAdd(w http.ResponseWriter, r *http.Request, _ httprouter. tx.Commit() returndata = true - logger.Info("okay") + logger.Info("done") return } @@ -104,7 +107,7 @@ func (api *API) WebsiteEdit(w http.ResponseWriter, r *http.Request, _ httprouter return } returndata = true - logger.Warn("okay") + logger.Info("done") return } @@ -121,6 +124,6 @@ func (api *API) WebsiteDelete(w http.ResponseWriter, r *http.Request, _ httprout return } returndata = true - logger.Warn("okay") + logger.Info("done") return } diff --git a/modul/web/apipermission.go b/modul/web/apipermission.go new file mode 100644 index 0000000..23bd879 --- /dev/null +++ b/modul/web/apipermission.go @@ -0,0 +1,71 @@ +package web + +import ( + "net/http" + "strconv" + + "github.com/astaxie/session" + "github.com/julienschmidt/httprouter" + + libapi "dev.sum7.de/sum7/warehost/lib/api" + libsystem "dev.sum7.de/sum7/warehost/system" +) + +// PermissionList to add permissions +func (api *API) PermissionList(w http.ResponseWriter, r *http.Request, _ httprouter.Params, sess session.Session, login *libsystem.Login, websiteid int64) (returndata interface{}, returnerr *libapi.ErrorResult) { + returndata = false + logger := api.log.GetLog(r, "permissionlist") + var involved []*Manager + api.dbconnection.Where("website = ?", websiteid).Preload("Login").Find(&involved) + logger.Info("done") + returndata = involved + return +} + +// PermissionAdd to add permissions +func (api *API) PermissionAdd(w http.ResponseWriter, r *http.Request, ps httprouter.Params, sess session.Session, login *libsystem.Login, websiteid int64) (returndata interface{}, returnerr *libapi.ErrorResult) { + returndata = false + logger := api.log.GetLog(r, "permissionadd") + loginid, err := strconv.ParseInt(ps.ByName("loginid"), 10, 64) + if err != nil { + returnerr = &libapi.ErrorResult{Fields: []string{"loginid"}, Message: "Not a valid loginid"} + logger.Warn("invalid loginid, no integer") + return + } + manager := &Manager{ + WebsiteID: websiteid, + LoginID: loginid, + } + if err := api.dbconnection.Create(manager).Error; err != nil { + logger.Error("database: during create website permission") + returnerr = &libapi.ErrorResult{Message: "Internal Database Error"} + return + } + returndata = true + logger.Info("done") + return +} + +// PermissionDelete to delete permissions +func (api *API) PermissionDelete(w http.ResponseWriter, r *http.Request, ps httprouter.Params, sess session.Session, login *libsystem.Login, websiteid int64) (returndata interface{}, returnerr *libapi.ErrorResult) { + returndata = false + logger := api.log.GetLog(r, "permissiondelete") + loginid, err := strconv.ParseInt(ps.ByName("loginid"), 10, 64) + if err != nil { + returnerr = &libapi.ErrorResult{Fields: []string{"loginid"}, Message: "Not a valid loginid"} + logger.Warn("invalid loginid, no integer") + return + } + manager := &Manager{ + WebsiteID: websiteid, + LoginID: loginid, + } + if err := api.dbconnection.Unscoped().Delete(manager).Error; err != nil { + logger.Error("database: during delete website permission") + returnerr = &libapi.ErrorResult{Message: "Internal Database Error"} + return + } + returndata = true + logger.Info("done") + return +} diff --git a/modul/web/models.go b/modul/web/models.go index cb84de4..8292b04 100644 --- a/modul/web/models.go +++ b/modul/web/models.go @@ -3,7 +3,8 @@ package web import ( "database/sql" "github.com/jinzhu/gorm" - //system "dev.sum7.de/sum7/warehost/system" + + system "dev.sum7.de/sum7/warehost/system" ) // Website struct @@ -27,9 +28,10 @@ func (Domain) TableName() string { return "web_domain" } // Manager struct type Manager struct { - LoginID int64 `sql:"type:bigint REFERENCES login(id) ON UPDATE CASCADE ON DELETE CASCADE;column:login;primary_key" json:"login"` - WebsiteID int64 `sql:"type:bigint REFERENCES web_website(id) ON UPDATE CASCADE ON DELETE CASCADE;column:website;primary_key" json:"-"` - Website Website `gorm:"foreignkey:Website" json:"website"` + LoginID int64 `sql:"type:bigint REFERENCES login(id) ON UPDATE CASCADE ON DELETE CASCADE;column:login;primary_key" json:"-"` + Login system.Login `gorm:"foreignkey:Login" json:"login"` + WebsiteID int64 `sql:"type:bigint REFERENCES web_website(id) ON UPDATE CASCADE ON DELETE CASCADE;column:website;primary_key" json:"-"` + Website Website `gorm:"foreignkey:Website" json:"website"` } // TableName of struct diff --git a/system/api.go b/system/api.go index 68dbd57..05391c2 100644 --- a/system/api.go +++ b/system/api.go @@ -43,8 +43,10 @@ func NewAPI(config *libconfig.Config, sessions *session.Manager, dbconnection *g router.GET(prefix+"/delete", LoginHandler(api.Delete, sessions)) router.GET(prefix+"/invite", LoginHandler(api.InviteList, sessions)) router.POST(prefix+"/invite", LoginHandler(api.InviteAdd, sessions)) - router.PUT(prefix+"/invite/:id", LoginHandler(api.LoginEdit, sessions)) - router.DELETE(prefix+"/invite/:id", LoginHandler(api.LoginDelete, sessions)) + router.GET(prefix+"/user", LoginHandler(api.LoginList, sessions)) + router.POST(prefix+"/user", LoginHandler(api.LoginAdd, sessions)) + router.PUT(prefix+"/user/:id", LoginHandler(api.LoginEdit, sessions)) + router.DELETE(prefix+"/user/:id", LoginHandler(api.LoginDelete, sessions)) router.GET(prefix+"/invitor", LoginHandler(api.Invitor, sessions)) router.PUT(prefix+"/invitor", LoginHandler(api.InvitorAdminToggle, sessions)) } @@ -58,7 +60,7 @@ func (api *API) Status(w http.ResponseWriter, r *http.Request, _ httprouter.Para if result > 0 { returndata = true } - logger.Info("status") + logger.Info("done") return } @@ -71,7 +73,7 @@ func (api *API) Logout(w http.ResponseWriter, r *http.Request, _ httprouter.Para } sess.Delete("login") sess.Delete("profil") - logger.Info("logout") + logger.Info("done") returndata = true return } @@ -104,7 +106,7 @@ func (api *API) Login(w http.ResponseWriter, r *http.Request, _ httprouter.Param returndata = true api.dbconnection.Model(&login).Update("LastLoginAt", time.Now()) sess.Set("login", login) - logger.Info("logged in") + logger.Info("done") } else { logger.Warn("wrong password") returnerr = &libapi.ErrorResult{Fields: []string{"password"}, Message: "Wrong Password"} @@ -149,7 +151,7 @@ func (api *API) Password(w http.ResponseWriter, r *http.Request, _ httprouter.Pa return } sess.Set("login", *login) - logger.Info("works") + logger.Info("done") returndata = true return } @@ -164,7 +166,7 @@ func (api *API) Delete(w http.ResponseWriter, r *http.Request, _ httprouter.Para returnerr = &libapi.ErrorResult{Message: "Error delete login"} return } - logger.Warn("login delete") + logger.Warn("done") returndata = true return } @@ -173,12 +175,12 @@ func (api *API) Delete(w http.ResponseWriter, r *http.Request, _ httprouter.Para func (api *API) InviteList(w http.ResponseWriter, r *http.Request, _ httprouter.Params, sess session.Session, login *Login) (returndata interface{}, returnerr *libapi.ErrorResult) { returndata = false logger := api.log.GetLog(r, "invitelist") - logger.Info("list invites") if err := api.dbconnection.Model(login).Preload("Invites.Invited").First(login).Error; err != nil { logger.Warn("error load own invites") returnerr = &libapi.ErrorResult{Message: "Could not load invites!"} return } + logger.Info("done") returndata = login.Invites return } @@ -208,7 +210,58 @@ func (api *API) InviteAdd(w http.ResponseWriter, r *http.Request, _ httprouter.P returnerr = &libapi.ErrorResult{Message: "Username exists already"} return } - logger.Info("invite") + logger.Info("done") + returndata = true + return +} + +// LoginList list all users in system +func (api *API) LoginList(w http.ResponseWriter, r *http.Request, ps httprouter.Params, sess session.Session, login *Login) (returndata interface{}, returnerr *libapi.ErrorResult) { + returndata = false + logger := api.log.GetLog(r, "loginlist") + var logins []Login + selectfield := "ID, mail" + if login.Superadmin { + selectfield = "ID, mail, superadmin" + } + if err := api.dbconnection.Select(selectfield).Find(&logins).Error; err != nil { + logger.Warn("sql edit login") + returnerr = &libapi.ErrorResult{Message: "Error during edit login"} + return + } + logger.Info("done") + returndata = logins + return +} + +// LoginAdd add a new Login +func (api *API) LoginAdd(w http.ResponseWriter, r *http.Request, ps httprouter.Params, sess session.Session, login *Login) (returndata interface{}, returnerr *libapi.ErrorResult) { + returndata = false + logger := api.log.GetLog(r, "loginadd") + if !login.Superadmin { + logger.Error("no superadmin") + returnerr = &libapi.ErrorResult{Message: "Error no permission to edit this invite"} + return + } + var newLogin RequestLogin + err := json.NewDecoder(r.Body).Decode(&newLogin) + if err != nil { + logger.Error("fetch request") + http.Error(w, err.Error(), http.StatusInternalServerError) + returnerr = &libapi.ErrorResult{Message: "Internal Request Error"} + return + } + loginObj := Login{ + Username: strings.ToLower(newLogin.Username), + Password: libpassword.NewHash(newLogin.Password), + Active: true, + } + if err := api.dbconnection.Create(loginObj).Error; err != nil { + logger.Warn("error create login") + returnerr = &libapi.ErrorResult{Message: "Username exists already"} + return + } + logger.Info("done") returndata = true return } @@ -238,7 +291,7 @@ func (api *API) LoginEdit(w http.ResponseWriter, r *http.Request, ps httprouter. invite := invitedLogin.GetInvitedby(api.dbconnection) if !login.Superadmin && !invite.Admin && invitedLogin.CreateAt.Before(invitedLogin.LastLoginAt) { logger.Warn("no permission") - returnerr = &libapi.ErrorResult{Message: "Error no permission to edit this invite"} + returnerr = &libapi.ErrorResult{Message: "Error no permission to edit this login"} return } if len(changeLogin.Password) > 0 { @@ -246,13 +299,14 @@ func (api *API) LoginEdit(w http.ResponseWriter, r *http.Request, ps httprouter. } if login.Superadmin { invitedLogin.Username = changeLogin.Username + invitedLogin.Superadmin = changeLogin.Superadmin } if err := api.dbconnection.Save(invitedLogin).Error; err != nil { logger.Warn("sql edit login") returnerr = &libapi.ErrorResult{Message: "Error during edit login"} return } - logger.Info("login edit") + logger.Info("done") returndata = true return } @@ -273,7 +327,7 @@ func (api *API) LoginDelete(w http.ResponseWriter, r *http.Request, ps httproute invite := invitedLogin.GetInvitedby(api.dbconnection) if !login.Superadmin && !invite.Admin && invitedLogin.CreateAt.Before(invitedLogin.LastLoginAt) { logger.Warn("no permission") - returnerr = &libapi.ErrorResult{Message: "Error no permission to delete this invite"} + returnerr = &libapi.ErrorResult{Message: "Error no permission to delete this login"} return } if err := api.dbconnection.Unscoped().Delete(invitedLogin).Error; err != nil { @@ -281,7 +335,7 @@ func (api *API) LoginDelete(w http.ResponseWriter, r *http.Request, ps httproute returnerr = &libapi.ErrorResult{Message: "Error during delete login"} return } - logger.Info("login deleted") + logger.Info("done") returndata = true return } @@ -291,7 +345,7 @@ func (api *API) Invitor(w http.ResponseWriter, r *http.Request, ps httprouter.Pa returndata = false logger := api.log.GetLog(r, "invitor") invite := login.GetInvitedby(api.dbconnection) - logger.Info("show invitor") + logger.Info("done") returndata = invite return } @@ -303,7 +357,7 @@ func (api *API) InvitorAdminToggle(w http.ResponseWriter, r *http.Request, ps ht invite := login.GetInvitedby(api.dbconnection) invite.Admin = !invite.Admin api.dbconnection.Model(invite).Save(&invite) - logger.Info("toggle saved") + logger.Info("done") returndata = true return } diff --git a/system/models.go b/system/models.go index 15e8c61..1892911 100644 --- a/system/models.go +++ b/system/models.go @@ -18,8 +18,9 @@ const MINPASSWORDLENTH = 3 // RequestLogin for api request to log in type RequestLogin struct { - Username string `json:"username"` - Password string `json:"password"` + Username string `json:"username"` + Password string `json:"password"` + Superadmin bool `json:"superadmin,oemitempty"` } // ChangePasswordRequest for api request of a new password diff --git a/webroot b/webroot index c9fd753..ed433dc 160000 --- a/webroot +++ b/webroot @@ -1 +1 @@ -Subproject commit c9fd753cfa6904337406706a94dbc5f4af43d4bb +Subproject commit ed433dc66f10a99f1a7ac3df538bc072e8e1881c