Added new readonly role: Reporter

pull/81/head
Doflatango 2018-05-05 10:17:05 +08:00
parent 6fe9c2f4ec
commit d3d40e4e92
10 changed files with 65 additions and 48 deletions

View File

@ -29,11 +29,12 @@ type Role int
const ( const (
Administrator Role = 1 Administrator Role = 1
Developer Role = 2 Developer Role = 2
Reporter Role = 3
) )
func (r Role) Defined() bool { func (r Role) Defined() bool {
switch r { switch r {
case Administrator, Developer: case Administrator, Developer, Reporter:
return true return true
} }
return false return false
@ -45,6 +46,8 @@ func (r Role) String() string {
return "Administrator" return "Administrator"
case Developer: case Developer:
return "Developer" return "Developer"
case Reporter:
return "Reporter"
} }
return "Undefined" return "Undefined"
} }

View File

@ -5,7 +5,7 @@ import (
"runtime" "runtime"
) )
const VersionNumber = "0.3.1" const VersionNumber = "0.3.2"
var ( var (
Version = fmt.Sprintf("v%s (build %s)", VersionNumber, runtime.Version()) Version = fmt.Sprintf("v%s (build %s)", VersionNumber, runtime.Version())

View File

@ -17,16 +17,7 @@ import (
type Administrator struct{} type Administrator struct{}
func adminAuthHandler(ctx *Context) (abort bool) { func adminAuthHandler(ctx *Context) (abort bool) {
if abort = authHandler(true)(ctx); abort { return authHandler(true, cronsun.Administrator)(ctx)
return
}
abort = ctx.Session.Data["role"].(cronsun.Role) != cronsun.Administrator
if abort {
outJSONWithCode(ctx.W, http.StatusForbidden, "access deny.")
}
return
} }
func NewAdminAuthHandler(f func(ctx *Context)) BaseHandler { func NewAdminAuthHandler(f func(ctx *Context)) BaseHandler {

View File

@ -65,19 +65,19 @@ type BaseHandler struct {
func NewBaseHandler(f func(ctx *Context)) BaseHandler { func NewBaseHandler(f func(ctx *Context)) BaseHandler {
return BaseHandler{ return BaseHandler{
BeforeHandle: authHandler(false), BeforeHandle: authHandler(false, 0),
Handle: f, Handle: f,
} }
} }
func NewAuthHandler(f func(ctx *Context)) BaseHandler { func NewAuthHandler(f func(ctx *Context), reqRole cronsun.Role) BaseHandler {
return BaseHandler{ return BaseHandler{
BeforeHandle: authHandler(true), BeforeHandle: authHandler(true, reqRole),
Handle: f, Handle: f,
} }
} }
func authHandler(needAuth bool) func(*Context) bool { func authHandler(needAuth bool, reqRole cronsun.Role) func(*Context) bool {
return func(ctx *Context) (abort bool) { return func(ctx *Context) (abort bool) {
var err error var err error
ctx.Session, err = sessManager.Get(ctx.W, ctx.R) ctx.Session, err = sessManager.Get(ctx.W, ctx.R)
@ -104,6 +104,21 @@ func authHandler(needAuth bool) func(*Context) bool {
abort = true abort = true
return return
} }
if r, ok := ctx.Session.Data["role"]; !ok {
outJSONWithCode(ctx.W, http.StatusUnauthorized, "role unknow.")
abort = true
return
} else if role, ok := r.(cronsun.Role); !ok {
outJSONWithCode(ctx.W, http.StatusUnauthorized, "role unknow.")
abort = true
return
} else if role > reqRole { // Lower number has more power.
outJSONWithCode(ctx.W, http.StatusUnauthorized, "higher role permission is required.")
abort = true
return
}
return return
} }
} }

View File

@ -45,65 +45,65 @@ func initRouters() (s *http.Server, err error) {
subrouter.Handle("/admin/account", h).Methods("POSt") subrouter.Handle("/admin/account", h).Methods("POSt")
// get job list // get job list
h = NewAuthHandler(jobHandler.GetList) h = NewAuthHandler(jobHandler.GetList, cronsun.Reporter)
subrouter.Handle("/jobs", h).Methods("GET") subrouter.Handle("/jobs", h).Methods("GET")
// get a job group list // get a job group list
h = NewAuthHandler(jobHandler.GetGroups) h = NewAuthHandler(jobHandler.GetGroups, cronsun.Reporter)
subrouter.Handle("/job/groups", h).Methods("GET") subrouter.Handle("/job/groups", h).Methods("GET")
// create/update a job // create/update a job
h = NewAuthHandler(jobHandler.UpdateJob) h = NewAuthHandler(jobHandler.UpdateJob, cronsun.Developer)
subrouter.Handle("/job", h).Methods("PUT") subrouter.Handle("/job", h).Methods("PUT")
// pause/start // pause/start
h = NewAuthHandler(jobHandler.ChangeJobStatus) h = NewAuthHandler(jobHandler.ChangeJobStatus, cronsun.Developer)
subrouter.Handle("/job/{group}-{id}", h).Methods("POST") subrouter.Handle("/job/{group}-{id}", h).Methods("POST")
// batch pause/start // batch pause/start
h = NewAuthHandler(jobHandler.BatchChangeJobStatus) h = NewAuthHandler(jobHandler.BatchChangeJobStatus, cronsun.Developer)
subrouter.Handle("/jobs/{op}", h).Methods("POST") subrouter.Handle("/jobs/{op}", h).Methods("POST")
// get a job // get a job
h = NewAuthHandler(jobHandler.GetJob) h = NewAuthHandler(jobHandler.GetJob, cronsun.Reporter)
subrouter.Handle("/job/{group}-{id}", h).Methods("GET") subrouter.Handle("/job/{group}-{id}", h).Methods("GET")
// remove a job // remove a job
h = NewAuthHandler(jobHandler.DeleteJob) h = NewAuthHandler(jobHandler.DeleteJob, cronsun.Developer)
subrouter.Handle("/job/{group}-{id}", h).Methods("DELETE") subrouter.Handle("/job/{group}-{id}", h).Methods("DELETE")
h = NewAuthHandler(jobHandler.GetJobNodes) h = NewAuthHandler(jobHandler.GetJobNodes, cronsun.Reporter)
subrouter.Handle("/job/{group}-{id}/nodes", h).Methods("GET") subrouter.Handle("/job/{group}-{id}/nodes", h).Methods("GET")
h = NewAuthHandler(jobHandler.JobExecute) h = NewAuthHandler(jobHandler.JobExecute, cronsun.Developer)
subrouter.Handle("/job/{group}-{id}/execute", h).Methods("PUT") subrouter.Handle("/job/{group}-{id}/execute", h).Methods("PUT")
// query executing job // query executing job
h = NewAuthHandler(jobHandler.GetExecutingJob) h = NewAuthHandler(jobHandler.GetExecutingJob, cronsun.Reporter)
subrouter.Handle("/job/executing", h).Methods("GET") subrouter.Handle("/job/executing", h).Methods("GET")
// get job log list // get job log list
h = NewAuthHandler(jobLogHandler.GetList) h = NewAuthHandler(jobLogHandler.GetList, cronsun.Reporter)
subrouter.Handle("/logs", h).Methods("GET") subrouter.Handle("/logs", h).Methods("GET")
// get job log // get job log
h = NewAuthHandler(jobLogHandler.GetDetail) h = NewAuthHandler(jobLogHandler.GetDetail, cronsun.Developer)
subrouter.Handle("/log/{id}", h).Methods("GET") subrouter.Handle("/log/{id}", h).Methods("GET")
h = NewAuthHandler(nodeHandler.GetNodes) h = NewAuthHandler(nodeHandler.GetNodes, cronsun.Developer)
subrouter.Handle("/nodes", h).Methods("GET") subrouter.Handle("/nodes", h).Methods("GET")
h = NewAuthHandler(nodeHandler.DeleteNode) h = NewAuthHandler(nodeHandler.DeleteNode, cronsun.Developer)
subrouter.Handle("/node/{ip}", h).Methods("DELETE") subrouter.Handle("/node/{ip}", h).Methods("DELETE")
// get node group list // get node group list
h = NewAuthHandler(nodeHandler.GetGroups) h = NewAuthHandler(nodeHandler.GetGroups, cronsun.Reporter)
subrouter.Handle("/node/groups", h).Methods("GET") subrouter.Handle("/node/groups", h).Methods("GET")
// get a node group by group id // get a node group by group id
h = NewAuthHandler(nodeHandler.GetGroupByGroupId) h = NewAuthHandler(nodeHandler.GetGroupByGroupId, cronsun.Reporter)
subrouter.Handle("/node/group/{id}", h).Methods("GET") subrouter.Handle("/node/group/{id}", h).Methods("GET")
// create/update a node group // create/update a node group
h = NewAuthHandler(nodeHandler.UpdateGroup) h = NewAuthHandler(nodeHandler.UpdateGroup, cronsun.Developer)
subrouter.Handle("/node/group", h).Methods("PUT") subrouter.Handle("/node/group", h).Methods("PUT")
// delete a node group // delete a node group
h = NewAuthHandler(nodeHandler.DeleteGroup) h = NewAuthHandler(nodeHandler.DeleteGroup, cronsun.Developer)
subrouter.Handle("/node/group/{id}", h).Methods("DELETE") subrouter.Handle("/node/group/{id}", h).Methods("DELETE")
h = NewAuthHandler(infoHandler.Overview) h = NewAuthHandler(infoHandler.Overview, cronsun.Reporter)
subrouter.Handle("/info/overview", h).Methods("GET") subrouter.Handle("/info/overview", h).Methods("GET")
h = NewAuthHandler(configHandler.Configuratios) h = NewAuthHandler(configHandler.Configuratios, cronsun.Reporter)
subrouter.Handle("/configurations", h).Methods("GET") subrouter.Handle("/configurations", h).Methods("GET")
r.PathPrefix("/ui/").Handler(http.StripPrefix("/ui/", newEmbeddedFileServer("", "index.html"))) r.PathPrefix("/ui/").Handler(http.StripPrefix("/ui/", newEmbeddedFileServer("", "index.html")))

View File

@ -16,6 +16,7 @@ import (
func init() { func init() {
gob.Register(cronsun.Administrator) gob.Register(cronsun.Administrator)
gob.Register(cronsun.Developer) gob.Register(cronsun.Developer)
gob.Register(cronsun.Reporter)
} }
var Manager SessionManager var Manager SessionManager

File diff suppressed because one or more lines are too long

View File

@ -61,7 +61,7 @@
<div id="app"> <div id="app">
<div id="initloader"></div> <div id="initloader"></div>
</div> </div>
<script src="build.js?v=75b49bd"></script> <script src="build.js?v=6fe9c2f"></script>
</body> </body>
</html> </html>

View File

@ -64,6 +64,7 @@ export default {
switch (s){ switch (s){
case 1: return 'Administrator'; case 1: return 'Administrator';
case 2: return 'Developer'; case 2: return 'Developer';
case 3: return 'Repoter';
} }
return ''; return '';
} }

View File

@ -23,6 +23,12 @@
<label>Developer</label> <label>Developer</label>
</div> </div>
</div> </div>
<div class="field">
<div class="ui radio checkbox">
<input type="radio" name="role" value="3" v-model="account.role" class="hidden">
<label>Reporter(ReadOnly)</label>
</div>
</div>
</div> </div>
<div v-show="action === 'UPDATE'"> <div v-show="action === 'UPDATE'">
<div class="inline fields" ref="status"> <div class="inline fields" ref="status">