http api method 목록 리턴하는 함수 추가
This commit is contained in:
@ -1,216 +0,0 @@
|
|||||||
package apicaller
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"sync"
|
|
||||||
"sync/atomic"
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"repositories.action2quare.com/ayo/gocommon/flagx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ApiCaller interface {
|
|
||||||
HasAuthority(authPath string) bool
|
|
||||||
GetMyAuthority() []string
|
|
||||||
}
|
|
||||||
|
|
||||||
type ApiCallerAuths interface {
|
|
||||||
NewApiCaller(user string) ApiCaller
|
|
||||||
NewApiCallerByServer() ApiCaller
|
|
||||||
Update(newusers map[string]*map[string]bool) error
|
|
||||||
Serialize() []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
type apiCallerAuths struct {
|
|
||||||
sync.Mutex
|
|
||||||
serialized unsafe.Pointer // *[]byte
|
|
||||||
users map[string]*map[string]bool // email -> authoriries
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *apiCallerAuths) Serialize() []byte {
|
|
||||||
btptr := atomic.LoadPointer(&a.serialized)
|
|
||||||
return *(*[]byte)(btptr)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *apiCallerAuths) getAuthority(email string) []string {
|
|
||||||
a.Lock()
|
|
||||||
defer a.Unlock()
|
|
||||||
|
|
||||||
auths := a.users[email]
|
|
||||||
if auths == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var out []string
|
|
||||||
for k, v := range *auths {
|
|
||||||
if v {
|
|
||||||
out = append(out, k)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *apiCallerAuths) Update(newAuths map[string]*map[string]bool) error {
|
|
||||||
src := map[string][]string{}
|
|
||||||
for user, auths := range newAuths {
|
|
||||||
for cat, has := range *auths {
|
|
||||||
if has {
|
|
||||||
arr := append(src[cat], user)
|
|
||||||
src[cat] = arr
|
|
||||||
} else if _, ok := src[cat]; !ok {
|
|
||||||
src[cat] = []string{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
a.Lock()
|
|
||||||
defer a.Unlock()
|
|
||||||
|
|
||||||
file, err := os.Create(*userAuthsFileName)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
enc := json.NewEncoder(file)
|
|
||||||
err = enc.Encode(src)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
a.users = newAuths
|
|
||||||
bt, _ := json.Marshal(newAuths)
|
|
||||||
atomic.StorePointer(&a.serialized, unsafe.Pointer(&bt))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *apiCallerAuths) hasAuthority(email string, authPath string) bool {
|
|
||||||
a.Lock()
|
|
||||||
defer a.Unlock()
|
|
||||||
|
|
||||||
auths, ok := a.users[email]
|
|
||||||
if !ok {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*auths)[authPath] {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
for k, v := range *auths {
|
|
||||||
if strings.HasPrefix(k, authPath+"/") {
|
|
||||||
return v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
var userAuthsFileName = flagx.String("userauth", "userauths.json", "-userauth=[json file path]")
|
|
||||||
|
|
||||||
func NewApiCallerAuths() ApiCallerAuths {
|
|
||||||
var out apiCallerAuths
|
|
||||||
f, _ := os.Open(*userAuthsFileName)
|
|
||||||
if f == nil {
|
|
||||||
emptyAuths := map[string][]string{
|
|
||||||
"/admins": {"enter_first_admin_email@action2quare.com"},
|
|
||||||
}
|
|
||||||
newf, _ := os.Create(*userAuthsFileName)
|
|
||||||
if newf != nil {
|
|
||||||
enc := json.NewEncoder(newf)
|
|
||||||
enc.Encode(emptyAuths)
|
|
||||||
newf.Close()
|
|
||||||
|
|
||||||
f, _ = os.Open(*userAuthsFileName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if f != nil {
|
|
||||||
defer f.Close()
|
|
||||||
|
|
||||||
var src map[string][]string
|
|
||||||
dec := json.NewDecoder(f)
|
|
||||||
dec.Decode(&src)
|
|
||||||
|
|
||||||
compiled := make(map[string]*map[string]bool)
|
|
||||||
|
|
||||||
// 전체 유저 목록을 먼저 뽑고나서
|
|
||||||
for _, users := range src {
|
|
||||||
for _, user := range users {
|
|
||||||
if _, ok := compiled[user]; !ok {
|
|
||||||
compiled[user] = &map[string]bool{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 전체 유저한테 모든 카테고리를 설정한다.
|
|
||||||
for _, auths := range compiled {
|
|
||||||
for cat := range src {
|
|
||||||
(*auths)[cat] = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 이제 유저별 권한을 설정
|
|
||||||
for category, users := range src {
|
|
||||||
for _, user := range users {
|
|
||||||
(*compiled[user])[category] = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
out = apiCallerAuths{
|
|
||||||
users: compiled,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
|
|
||||||
out = apiCallerAuths{
|
|
||||||
users: map[string]*map[string]bool{},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
marshaled, _ := json.Marshal(out.users)
|
|
||||||
out.serialized = unsafe.Pointer(&marshaled)
|
|
||||||
|
|
||||||
return &out
|
|
||||||
}
|
|
||||||
|
|
||||||
type apiCaller struct {
|
|
||||||
userAuths *apiCallerAuths
|
|
||||||
caller string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *apiCallerAuths) NewApiCaller(user string) ApiCaller {
|
|
||||||
if len(user) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return &apiCaller{
|
|
||||||
userAuths: a,
|
|
||||||
caller: user,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *apiCallerAuths) NewApiCallerByServer() ApiCaller {
|
|
||||||
return &apiCaller{
|
|
||||||
userAuths: a,
|
|
||||||
caller: "",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ac apiCaller) callByServer() bool {
|
|
||||||
return len(ac.caller) == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ac apiCaller) HasAuthority(authPath string) bool {
|
|
||||||
if ac.callByServer() {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return ac.userAuths.hasAuthority(ac.caller, authPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ac apiCaller) GetMyAuthority() []string {
|
|
||||||
if !ac.callByServer() {
|
|
||||||
return ac.userAuths.getAuthority(ac.caller)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@ -826,6 +826,14 @@ func (hc *HttpApiBroker) AddHandler(receiver HttpApiHandler) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (hc *HttpApiBroker) AllMethods() (out []string) {
|
||||||
|
out = make([]string, 0, len(hc.methods))
|
||||||
|
for name := range hc.methods {
|
||||||
|
out = append(out, name)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (hc *HttpApiBroker) CallByHeader(w http.ResponseWriter, r *http.Request) {
|
func (hc *HttpApiBroker) CallByHeader(w http.ResponseWriter, r *http.Request) {
|
||||||
funcname := r.Header.Get("AS-X-CALL")
|
funcname := r.Header.Get("AS-X-CALL")
|
||||||
if len(funcname) == 0 {
|
if len(funcname) == 0 {
|
||||||
|
|||||||
Reference in New Issue
Block a user