maingate는 admin 계정으로 통일 또는 ApiToken

This commit is contained in:
2023-06-19 21:19:45 +09:00
parent 4bb25a1eff
commit 09328575ad
3 changed files with 91 additions and 113 deletions

View File

@ -86,7 +86,7 @@ func (caller apiCaller) isGlobalAdmin() bool {
return false
}
if _, ok := caller.admins[email.(string)]; ok {
if _, ok := caller.globalAdmins[email.(string)]; ok {
return true
}
@ -125,7 +125,7 @@ func (caller apiCaller) getAccessableServices() ([]*serviceDescription, []string
}
email = v.(string)
_, admin = caller.admins[email]
_, admin = caller.globalAdmins[email]
}
var output []*serviceDescription
@ -134,11 +134,9 @@ func (caller apiCaller) getAccessableServices() ([]*serviceDescription, []string
if admin {
output = append(output, desc)
editable = append(editable, desc.ServiceName)
} else if desc.isValidAPIUser("*", email) {
} else if caller.isAdminOrValidToken(email) {
output = append(output, desc)
if desc.isValidAPIUser("service", email) {
editable = append(editable, desc.ServiceName)
}
editable = append(editable, desc.ServiceName)
}
}
@ -149,60 +147,49 @@ func (caller apiCaller) getAccessableServices() ([]*serviceDescription, []string
return output, editable
}
func (caller apiCaller) isValidUser(service any, category string) (valid bool, admin bool) {
func (caller apiCaller) isAdmin(service any) bool {
if *noauth {
return true, true
return true
}
v, ok := caller.userinfo["email"]
if !ok {
logger.Println("isVaidUser failed. email is missing :", caller.userinfo)
return false, false
return false
}
email := v.(string)
if _, ok := caller.admins[email]; ok {
return true, true
if _, ok := caller.globalAdmins[email]; ok {
return true
}
svcdesc := caller.mg.services.get(service)
if svcdesc == nil {
logger.Println("isVaidUser failed. service is missing :", service)
return false, false
return false
}
return svcdesc.isValidAPIUser(category, email), false
return svcdesc.isAdmin(email)
}
func (caller apiCaller) isAdminOrValidToken(service any) bool {
if caller.isAdmin(service) {
return true
}
sh := caller.mg.services.get(service)
if sh == nil {
return false
}
return sh.isValidToken(caller.apiToken)
}
func (caller apiCaller) filesAPI(w http.ResponseWriter, r *http.Request) error {
if r.Method == "GET" {
hasAuth := caller.isGlobalAdmin()
var email string
if !*noauth {
v, ok := caller.userinfo["email"]
if !ok {
return nil
}
email = v.(string)
_, hasAuth = caller.admins[email]
}
servicename := r.FormValue("service")
sh := caller.mg.services.get(servicename)
if sh == nil {
w.WriteHeader(http.StatusBadRequest)
return nil
}
if !hasAuth {
if hasAuth = sh.isValidAPIUser("maintenance", email); !hasAuth {
hasAuth = sh.isValidAPIUser("service", email)
}
}
if !hasAuth {
w.WriteHeader(http.StatusBadRequest)
if !caller.isAdminOrValidToken(servicename) {
w.WriteHeader(http.StatusUnauthorized)
return nil
}
@ -228,6 +215,11 @@ func (caller apiCaller) filesAPI(w http.ResponseWriter, r *http.Request) error {
return nil
}
if !caller.isAdminOrValidToken(servicename) {
w.WriteHeader(http.StatusUnauthorized)
return nil
}
_, err := caller.mg.mongoClient.Delete(CollectionFile, bson.M{
"service": servicename,
"key": key,
@ -309,14 +301,12 @@ func (caller apiCaller) whitelistAPI(w http.ResponseWriter, r *http.Request) err
queryvals := r.URL.Query()
if r.Method == "GET" {
service := queryvals.Get("service")
if valid, _ := caller.isValidUser(service, "whitelist"); !valid {
logger.Println("whitelistAPI failed. not vaild user :", r.Method, caller.userinfo)
w.WriteHeader(http.StatusBadRequest)
return nil
}
if len(service) > 0 {
if !caller.isAdminOrValidToken(service) {
logger.Println("whitelistAPI failed. not vaild user :", r.Method, caller.userinfo)
w.WriteHeader(http.StatusUnauthorized)
return nil
}
all, err := mg.mongoClient.FindAll(CollectionWhitelist, bson.M{
"service": service,
@ -344,9 +334,10 @@ func (caller apiCaller) whitelistAPI(w http.ResponseWriter, r *http.Request) err
if err := json.Unmarshal(body, &member); err != nil {
return err
}
if valid, _ := caller.isValidUser(member.Service, "whitelist"); !valid {
if !caller.isAdminOrValidToken(member.Service) {
logger.Println("whitelistAPI failed. not vaild user :", r.Method, caller.userinfo)
w.WriteHeader(http.StatusBadRequest)
w.WriteHeader(http.StatusUnauthorized)
return nil
}
@ -391,16 +382,13 @@ func (caller apiCaller) serviceAPI(w http.ResponseWriter, r *http.Request) error
if r.Method == "GET" {
name := queryvals.Get("name")
if len(name) > 0 {
if valid, _ := caller.isValidUser(name, "*"); !valid {
if !caller.isAdminOrValidToken(name) {
logger.Println("serviceAPI failed. not vaild user :", r.Method, caller.userinfo)
w.WriteHeader(http.StatusBadRequest)
return nil
}
if valid, admin := caller.isValidUser(name, "service"); valid || admin {
w.Header().Add("MG-X-SERVICE-EDITABLE", name)
}
w.Header().Add("MG-X-SERVICE-EDITABLE", name)
serptr := atomic.LoadPointer(&mg.services.get(name).serviceSerialized)
w.Write(*(*[]byte)(serptr))
} else {
@ -421,7 +409,7 @@ func (caller apiCaller) serviceAPI(w http.ResponseWriter, r *http.Request) error
w.WriteHeader(http.StatusBadRequest)
return nil
}
} else if valid, _ := caller.isValidUser(service.Id, "service"); !valid {
} else if !caller.isAdminOrValidToken(service.Id) {
logger.Println("serviceAPI failed. not vaild user :", r.Method, caller.userinfo)
w.WriteHeader(http.StatusBadRequest)
return nil
@ -461,15 +449,11 @@ func (caller apiCaller) maintenanceAPI(w http.ResponseWriter, r *http.Request) e
if r.Method == "GET" {
name := queryvals.Get("name")
if len(name) > 0 {
if valid, _ := caller.isValidUser(name, "*"); !valid {
w.WriteHeader(http.StatusBadRequest)
if !caller.isAdminOrValidToken(name) {
w.WriteHeader(http.StatusUnauthorized)
return nil
}
if valid, admin := caller.isValidUser(name, "maintenance"); valid || admin {
w.Header().Add("MG-X-SERVICE-EDITABLE", name)
}
w.Header().Add("MG-X-SERVICE-EDITABLE", name)
serptr := atomic.LoadPointer(&mg.services.get(name).divisionsSerialized)
w.Write(*(*[]byte)(serptr))
} else {
@ -477,7 +461,7 @@ func (caller apiCaller) maintenanceAPI(w http.ResponseWriter, r *http.Request) e
}
} else if r.Method == "POST" {
servicename := queryvals.Get("name")
if valid, _ := caller.isValidUser(servicename, "service"); !valid {
if !caller.isAdminOrValidToken(servicename) {
logger.Println("maintenanceAPI failed. not vaild user :", r.Method, caller.userinfo)
w.WriteHeader(http.StatusBadRequest)
return nil
@ -514,9 +498,9 @@ func (caller apiCaller) accountAPI(w http.ResponseWriter, r *http.Request) error
return nil
}
if valid, _ := caller.isValidUser(service, "account"); !valid {
if !caller.isAdminOrValidToken(service) {
logger.Println("accountAPI failed. not vaild user :", r.Method, caller.userinfo)
w.WriteHeader(http.StatusBadRequest)
w.WriteHeader(http.StatusUnauthorized)
return nil
}
@ -641,9 +625,10 @@ func (caller apiCaller) configAPI(w http.ResponseWriter, r *http.Request) error
var noauth = flag.Bool("noauth", false, "")
type apiCaller struct {
userinfo map[string]any
admins map[string]bool
mg *Maingate
userinfo map[string]any
globalAdmins map[string]bool
mg *Maingate
apiToken primitive.ObjectID
}
func (mg *Maingate) api(w http.ResponseWriter, r *http.Request) {
@ -704,11 +689,24 @@ func (mg *Maingate) api(w http.ResponseWriter, r *http.Request) {
}
}
apiToken := r.Header.Get("MG-X-API-TOKEN")
var apiTokenObj primitive.ObjectID
if len(apiToken) > 0 {
obj, err := primitive.ObjectIDFromHex(apiToken)
if err != nil {
logger.Error(err)
w.WriteHeader(http.StatusBadRequest)
return
}
apiTokenObj = obj
}
logger.Println("api call :", r.URL.Path, r.Method, r.URL.Query(), userinfo)
caller := apiCaller{
userinfo: userinfo,
admins: adminsptr.emails,
mg: mg,
userinfo: userinfo,
globalAdmins: adminsptr.emails,
mg: mg,
apiToken: apiTokenObj,
}
var err error