[host] add signup and delete
This commit is contained in:
parent
0649adf82a
commit
b2ccc6c987
|
@ -2,6 +2,7 @@ package host
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/jinzhu/gorm"
|
"github.com/jinzhu/gorm"
|
||||||
"goji.io"
|
"goji.io"
|
||||||
|
@ -10,6 +11,7 @@ import (
|
||||||
|
|
||||||
libapi "dev.sum7.eu/sum7/warehost/lib/api"
|
libapi "dev.sum7.eu/sum7/warehost/lib/api"
|
||||||
liblog "dev.sum7.eu/sum7/warehost/lib/log"
|
liblog "dev.sum7.eu/sum7/warehost/lib/log"
|
||||||
|
system "dev.sum7.eu/sum7/warehost/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
//MODULNAME to get global name for the modul
|
//MODULNAME to get global name for the modul
|
||||||
|
@ -23,13 +25,45 @@ func BindAPI(db *gorm.DB, router *goji.Mux, prefix string) {
|
||||||
dbconnection = db
|
dbconnection = db
|
||||||
log = liblog.NewModulLog(MODULNAME)
|
log = liblog.NewModulLog(MODULNAME)
|
||||||
|
|
||||||
router.HandleFuncC(pat.Get(prefix+"/status"), libapi.SessionHandler(status))
|
router.HandleFuncC(pat.Post(prefix+"/signup"), libapi.SessionHandler(system.LoginHandler(signup)))
|
||||||
|
router.HandleFuncC(pat.Delete(prefix+"/delete"), libapi.SessionHandler(system.LoginHandler(ProfilHandler(delete))))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status to get Login and Server status
|
func signup(ctx context.Context, w http.ResponseWriter, r *http.Request) (returndata interface{}, returnerr *libapi.ErrorResult) {
|
||||||
func status(ctx context.Context, w http.ResponseWriter, r *http.Request) (returndata interface{}, returnerr *libapi.ErrorResult) {
|
login := ctx.Value("login").(*system.Login)
|
||||||
|
returndata = false
|
||||||
|
logger := log.GetLog(r, "signup")
|
||||||
|
run := login.Superadmin
|
||||||
|
if !run {
|
||||||
|
var profil Profil
|
||||||
|
dbconnection.Joins("LEFT JOIN invite invite ON invite.login=host_profil.login").Where("invite.invited=?", login.ID).Find(&profil)
|
||||||
|
run = profil.Reseller
|
||||||
|
}
|
||||||
|
if run {
|
||||||
|
profil := &Profil{LoginID: login.ID}
|
||||||
|
if err := dbconnection.Create(profil).Error; err != nil {
|
||||||
|
if strings.Contains(err.Error(), "duplicate key") {
|
||||||
|
returndata = false
|
||||||
|
logger.Warning("exists already")
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
logger.Error("database: during create host profil: ", err)
|
||||||
|
returnerr = &libapi.ErrorResult{Message: "Internal Database Error"}
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
returndata = true
|
returndata = true
|
||||||
logger := log.GetLog(r, "status")
|
logger.Info("done")
|
||||||
logger.Info("status")
|
return
|
||||||
|
}
|
||||||
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
|
logger.Info("not allowed")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
func delete(ctx context.Context, w http.ResponseWriter, r *http.Request) (returndata interface{}, returnerr *libapi.ErrorResult) {
|
||||||
|
profil := ctx.Value("profil").(*Profil)
|
||||||
|
returndata = true
|
||||||
|
dbconnection.Unscoped().Delete(profil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
package host
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"dev.sum7.eu/sum7/warehost/system"
|
||||||
|
"dev.sum7.eu/sum7/warehost/test"
|
||||||
|
)
|
||||||
|
|
||||||
|
func loginTest(session *test.Request, assertion *assert.Assertions) {
|
||||||
|
result, w := session.JSONRequest("POST", "/login", system.RequestLogin{Username: "root", Password: "root"})
|
||||||
|
assertion.Equal(w.StatusCode, http.StatusOK)
|
||||||
|
assertion.Equal(result.Data, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAPI(t *testing.T) {
|
||||||
|
|
||||||
|
assertion, db, router := test.Init(t)
|
||||||
|
defer db.Close()
|
||||||
|
|
||||||
|
//load system Models to database
|
||||||
|
system.SyncModels(db)
|
||||||
|
db.Unscoped().Delete(Profil{})
|
||||||
|
SyncModels(db)
|
||||||
|
|
||||||
|
// Bind API
|
||||||
|
system.BindAPI(db, router, "")
|
||||||
|
BindAPI(db, router, "/host")
|
||||||
|
session := test.NewSession(router)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TEST signup
|
||||||
|
*/
|
||||||
|
result, w := session.JSONRequest("POST", "/host/signup", nil)
|
||||||
|
assertion.Equal(w.StatusCode, http.StatusUnauthorized)
|
||||||
|
assertion.Equal(result.Data, false)
|
||||||
|
|
||||||
|
loginTest(session, assertion)
|
||||||
|
|
||||||
|
result, w = session.JSONRequest("POST", "/host/signup", nil)
|
||||||
|
assertion.Equal(w.StatusCode, http.StatusOK)
|
||||||
|
assertion.Equal(result.Data, true)
|
||||||
|
|
||||||
|
result, w = session.JSONRequest("POST", "/host/signup", nil)
|
||||||
|
assertion.Equal(w.StatusCode, http.StatusOK)
|
||||||
|
assertion.Equal(result.Data, false)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TEST delete
|
||||||
|
*/
|
||||||
|
session.Clean()
|
||||||
|
result, w = session.JSONRequest("DELETE", "/host/delete", nil)
|
||||||
|
assertion.Equal(w.StatusCode, http.StatusUnauthorized)
|
||||||
|
assertion.Equal(result.Data, false)
|
||||||
|
|
||||||
|
loginTest(session, assertion)
|
||||||
|
|
||||||
|
result, w = session.JSONRequest("DELETE", "/host/delete", nil)
|
||||||
|
assertion.Equal(w.StatusCode, http.StatusOK)
|
||||||
|
assertion.Equal(result.Data, true)
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package host
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
|
||||||
|
libapi "dev.sum7.eu/sum7/warehost/lib/api"
|
||||||
|
liblog "dev.sum7.eu/sum7/warehost/lib/log"
|
||||||
|
libsystem "dev.sum7.eu/sum7/warehost/system"
|
||||||
|
)
|
||||||
|
|
||||||
|
//ProfilHandler for api function to get host.Profil
|
||||||
|
func ProfilHandler(h libapi.Handle) libapi.Handle {
|
||||||
|
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) (returndata interface{}, returnerr *libapi.ErrorResult) {
|
||||||
|
login := ctx.Value("login").(*libsystem.Login)
|
||||||
|
returnerr = &libapi.ErrorResult{Fields: []string{"session"}, Message: "no profil found"}
|
||||||
|
returndata = false
|
||||||
|
|
||||||
|
profil := &Profil{LoginID: login.ID}
|
||||||
|
res := dbconnection.Find(profil)
|
||||||
|
if !res.RecordNotFound() {
|
||||||
|
ctx = context.WithValue(ctx, "profil", profil)
|
||||||
|
returndata, returnerr = h(ctx, w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
liblog.Log.Warn("no profil found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ import (
|
||||||
// Profil struct
|
// Profil struct
|
||||||
type Profil struct {
|
type Profil struct {
|
||||||
ID int64
|
ID int64
|
||||||
LoginID int64 `sql:"type:bigint NOT NULL REFERENCES login(id) ON UPDATE CASCADE ON DELETE CASCADE;column:login" json:"login"`
|
LoginID int64 `sql:"type:bigint NOT NULL UNIQUE REFERENCES login(id) ON UPDATE CASCADE ON DELETE CASCADE;column:login" json:"login"`
|
||||||
Reseller bool `sql:"default:false;column:reseller" json:"reseller"`
|
Reseller bool `sql:"default:false;column:reseller" json:"reseller"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/astaxie/session"
|
|
||||||
"goji.io/pat"
|
"goji.io/pat"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
|
||||||
|
@ -13,18 +12,16 @@ import (
|
||||||
libsystem "dev.sum7.eu/sum7/warehost/system"
|
libsystem "dev.sum7.eu/sum7/warehost/system"
|
||||||
)
|
)
|
||||||
|
|
||||||
//InvolveWebsiteHandler for api function to Verifie User ist libloggedin
|
//InvolveWebsiteHandler for api function to Verifie User ist loggedin
|
||||||
func InvolveWebsiteHandler(h libapi.Handle) libapi.Handle {
|
func InvolveWebsiteHandler(h libapi.Handle) libapi.Handle {
|
||||||
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) (returndata interface{}, returnerr *libapi.ErrorResult) {
|
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) (returndata interface{}, returnerr *libapi.ErrorResult) {
|
||||||
sess := ctx.Value("session").(session.Session)
|
login := ctx.Value("login").(libsystem.Login)
|
||||||
returnerr = &libapi.ErrorResult{Fields: []string{"session"}, Message: "Not liblogged in"}
|
returnerr = &libapi.ErrorResult{Fields: []string{"session"}, Message: "Not logged in"}
|
||||||
returndata = false
|
returndata = false
|
||||||
|
|
||||||
if login := sess.Get("login"); login != nil {
|
|
||||||
if loginObj := login.(libsystem.Login); loginObj.Active {
|
|
||||||
id, err := strconv.ParseInt(pat.Param(ctx, "websiteid"), 10, 64)
|
id, err := strconv.ParseInt(pat.Param(ctx, "websiteid"), 10, 64)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
res := dbconnection.Where(map[string]int64{"website": id, "login": loginObj.ID}).Find(&Manager{})
|
res := dbconnection.Where(map[string]int64{"website": id, "login": login.ID}).Find(&Manager{})
|
||||||
if !res.RecordNotFound() {
|
if !res.RecordNotFound() {
|
||||||
ctx = context.WithValue(ctx, "websiteid", id)
|
ctx = context.WithValue(ctx, "websiteid", id)
|
||||||
returndata, returnerr = h(ctx, w, r)
|
returndata, returnerr = h(ctx, w, r)
|
||||||
|
@ -38,10 +35,4 @@ func InvolveWebsiteHandler(h libapi.Handle) libapi.Handle {
|
||||||
liblog.Log.Warn("invalid websiteid, no integer")
|
liblog.Log.Warn("invalid websiteid, no integer")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
liblog.Log.Warn("user not active")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
liblog.Log.Warn("not libloggedin")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,20 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
"dev.sum7.eu/sum7/warehost/test"
|
"dev.sum7.eu/sum7/warehost/test"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func loginTest(session *test.Request, assertion *assert.Assertions) {
|
||||||
|
result, w := session.JSONRequest("POST", "/login", RequestLogin{Username: "root", Password: "root"})
|
||||||
|
assertion.Equal(w.StatusCode, http.StatusOK)
|
||||||
|
assertion.Equal(result.Data, true)
|
||||||
|
}
|
||||||
|
|
||||||
func TestAPI(t *testing.T) {
|
func TestAPI(t *testing.T) {
|
||||||
|
|
||||||
assert, db, router := test.Init(t)
|
assertion, db, router := test.Init(t)
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
//load system Models to database
|
//load system Models to database
|
||||||
|
@ -23,105 +31,98 @@ func TestAPI(t *testing.T) {
|
||||||
* TEST status
|
* TEST status
|
||||||
*/
|
*/
|
||||||
result, w := session.JSONRequest("GET", "/status", nil)
|
result, w := session.JSONRequest("GET", "/status", nil)
|
||||||
assert.Equal(w.StatusCode, http.StatusOK)
|
assertion.Equal(w.StatusCode, http.StatusOK)
|
||||||
assert.Nil(result.Error)
|
assertion.Nil(result.Error)
|
||||||
assert.Equal(result.Data, true)
|
assertion.Equal(result.Data, true)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TEST login
|
* TEST login
|
||||||
*/
|
*/
|
||||||
result, w = session.JSONRequest("POST", "/login", RequestLogin{Username: "root", Password: "root2"})
|
result, w = session.JSONRequest("POST", "/login", RequestLogin{Username: "root", Password: "root2"})
|
||||||
assert.Equal(w.StatusCode, http.StatusOK)
|
assertion.Equal(w.StatusCode, http.StatusOK)
|
||||||
assert.Equal(result.Data, false)
|
assertion.Equal(result.Data, false)
|
||||||
assert.Equal(result.Error.Fields[0], "password")
|
assertion.Equal(result.Error.Fields[0], "password")
|
||||||
|
|
||||||
result, w = session.JSONRequest("POST", "/login", RequestLogin{Username: "root2", Password: "root"})
|
result, w = session.JSONRequest("POST", "/login", RequestLogin{Username: "root2", Password: "root"})
|
||||||
assert.Equal(w.StatusCode, http.StatusOK)
|
assertion.Equal(w.StatusCode, http.StatusOK)
|
||||||
assert.Equal(result.Data, false)
|
assertion.Equal(result.Data, false)
|
||||||
assert.Equal(result.Error.Fields[0], "username")
|
assertion.Equal(result.Error.Fields[0], "username")
|
||||||
|
|
||||||
result, w = session.JSONRequest("POST", "/login", []byte{2, 3})
|
result, w = session.JSONRequest("POST", "/login", []byte{2, 3})
|
||||||
assert.Equal(w.StatusCode, http.StatusBadRequest)
|
assertion.Equal(w.StatusCode, http.StatusBadRequest)
|
||||||
|
|
||||||
result, w = session.JSONRequest("POST", "/login", RequestLogin{Username: "root", Password: "root"})
|
//login before
|
||||||
assert.Equal(w.StatusCode, http.StatusOK)
|
loginTest(session, assertion)
|
||||||
assert.Equal(result.Data, true)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TEST logout
|
* TEST logout
|
||||||
*/
|
*/
|
||||||
result, w = session.JSONRequest("GET", "/logout", nil)
|
result, w = session.JSONRequest("GET", "/logout", nil)
|
||||||
assert.Equal(w.StatusCode, http.StatusOK)
|
assertion.Equal(w.StatusCode, http.StatusOK)
|
||||||
assert.Equal(result.Data, true)
|
assertion.Equal(result.Data, true)
|
||||||
|
|
||||||
// Test if crash on if not login in
|
// Test if crash on if not login in
|
||||||
result, w = session.JSONRequest("GET", "/logout", nil)
|
result, w = session.JSONRequest("GET", "/logout", nil)
|
||||||
assert.Equal(w.StatusCode, http.StatusOK)
|
assertion.Equal(w.StatusCode, http.StatusOK)
|
||||||
assert.Equal(result.Data, false)
|
assertion.Equal(result.Data, false)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TEST password
|
* TEST password
|
||||||
*/
|
*/
|
||||||
|
|
||||||
result, w = session.JSONRequest("POST", "/password", ChangePasswordRequest{CurrentPassword: "root", NewPassword: "root-bug"})
|
result, w = session.JSONRequest("POST", "/password", ChangePasswordRequest{CurrentPassword: "root", NewPassword: "root-bug"})
|
||||||
assert.Equal(w.StatusCode, http.StatusOK)
|
assertion.Equal(w.StatusCode, http.StatusOK)
|
||||||
assert.Equal(result.Data, false)
|
assertion.Equal(result.Data, false)
|
||||||
|
|
||||||
//login before
|
//login before
|
||||||
result, w = session.JSONRequest("POST", "/login", RequestLogin{Username: "root", Password: "root"})
|
loginTest(session, assertion)
|
||||||
assert.Equal(w.StatusCode, http.StatusOK)
|
|
||||||
assert.Equal(result.Data, true)
|
|
||||||
|
|
||||||
result, w = session.JSONRequest("POST", "/password", []byte{2, 3})
|
result, w = session.JSONRequest("POST", "/password", []byte{2, 3})
|
||||||
assert.Equal(w.StatusCode, http.StatusBadRequest)
|
assertion.Equal(w.StatusCode, http.StatusBadRequest)
|
||||||
|
|
||||||
result, w = session.JSONRequest("POST", "/password", ChangePasswordRequest{CurrentPassword: "root-wrong", NewPassword: "root-bug"})
|
result, w = session.JSONRequest("POST", "/password", ChangePasswordRequest{CurrentPassword: "root-wrong", NewPassword: "root-bug"})
|
||||||
assert.Equal(w.StatusCode, http.StatusOK)
|
assertion.Equal(w.StatusCode, http.StatusOK)
|
||||||
assert.Equal(result.Data, false)
|
assertion.Equal(result.Data, false)
|
||||||
assert.Equal(result.Error.Fields[0], "currentpassword")
|
assertion.Equal(result.Error.Fields[0], "currentpassword")
|
||||||
|
|
||||||
result, w = session.JSONRequest("POST", "/password", ChangePasswordRequest{CurrentPassword: "root", NewPassword: ""})
|
result, w = session.JSONRequest("POST", "/password", ChangePasswordRequest{CurrentPassword: "root", NewPassword: ""})
|
||||||
assert.Equal(w.StatusCode, http.StatusOK)
|
assertion.Equal(w.StatusCode, http.StatusOK)
|
||||||
assert.Equal(result.Data, false)
|
assertion.Equal(result.Data, false)
|
||||||
assert.Equal(result.Error.Fields[0], "newpassword")
|
assertion.Equal(result.Error.Fields[0], "newpassword")
|
||||||
|
|
||||||
result, w = session.JSONRequest("POST", "/password", ChangePasswordRequest{CurrentPassword: "root", NewPassword: "root-tmp"})
|
result, w = session.JSONRequest("POST", "/password", ChangePasswordRequest{CurrentPassword: "root", NewPassword: "root-tmp"})
|
||||||
assert.Equal(w.StatusCode, http.StatusOK)
|
assertion.Equal(w.StatusCode, http.StatusOK)
|
||||||
assert.Equal(result.Data, true)
|
assertion.Equal(result.Data, true)
|
||||||
|
|
||||||
result, w = session.JSONRequest("POST", "/password", ChangePasswordRequest{CurrentPassword: "root-tmp", NewPassword: "root"})
|
result, w = session.JSONRequest("POST", "/password", ChangePasswordRequest{CurrentPassword: "root-tmp", NewPassword: "root"})
|
||||||
assert.Equal(w.StatusCode, http.StatusOK)
|
assertion.Equal(w.StatusCode, http.StatusOK)
|
||||||
assert.Equal(result.Data, true)
|
assertion.Equal(result.Data, true)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TEST inviteList
|
* TEST inviteList
|
||||||
*/
|
*/
|
||||||
session.Clean()
|
session.Clean()
|
||||||
result, w = session.JSONRequest("GET", "/invite", nil)
|
result, w = session.JSONRequest("GET", "/invite", nil)
|
||||||
assert.Equal(w.StatusCode, http.StatusOK)
|
assertion.Equal(w.StatusCode, http.StatusOK)
|
||||||
assert.Equal(result.Data, false)
|
assertion.Equal(result.Data, false)
|
||||||
|
|
||||||
//login before
|
//login before
|
||||||
result, w = session.JSONRequest("POST", "/login", RequestLogin{Username: "root", Password: "root"})
|
loginTest(session, assertion)
|
||||||
assert.Equal(w.StatusCode, http.StatusOK)
|
|
||||||
assert.Equal(result.Data, true)
|
|
||||||
|
|
||||||
result, w = session.JSONRequest("GET", "/invite", nil)
|
result, w = session.JSONRequest("GET", "/invite", nil)
|
||||||
assert.Equal(w.StatusCode, http.StatusOK)
|
assertion.Equal(w.StatusCode, http.StatusOK)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TEST loginList
|
* TEST loginList
|
||||||
*/
|
*/
|
||||||
session.Clean()
|
session.Clean()
|
||||||
result, w = session.JSONRequest("GET", "/user", nil)
|
result, w = session.JSONRequest("GET", "/user", nil)
|
||||||
assert.Equal(w.StatusCode, http.StatusOK)
|
assertion.Equal(w.StatusCode, http.StatusOK)
|
||||||
assert.Equal(result.Data, false)
|
assertion.Equal(result.Data, false)
|
||||||
|
|
||||||
//login before
|
//login before
|
||||||
result, w = session.JSONRequest("POST", "/login", RequestLogin{Username: "root", Password: "root"})
|
loginTest(session, assertion)
|
||||||
assert.Equal(w.StatusCode, http.StatusOK)
|
|
||||||
assert.Equal(result.Data, true)
|
|
||||||
|
|
||||||
result, w = session.JSONRequest("GET", "/user", nil)
|
result, w = session.JSONRequest("GET", "/user", nil)
|
||||||
assert.Equal(w.StatusCode, http.StatusOK)
|
assertion.Equal(w.StatusCode, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,9 +23,11 @@ func LoginHandler(h libapi.Handle) libapi.Handle {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
returnerr = &libapi.ErrorResult{Fields: []string{"session"}, Message: "Not active user"}
|
returnerr = &libapi.ErrorResult{Fields: []string{"session"}, Message: "Not active user"}
|
||||||
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
liblog.Log.Warn("user not active")
|
liblog.Log.Warn("user not active")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
w.WriteHeader(http.StatusUnauthorized)
|
||||||
returnerr = &libapi.ErrorResult{Fields: []string{"session"}, Message: "Not logged in"}
|
returnerr = &libapi.ErrorResult{Fields: []string{"session"}, Message: "Not logged in"}
|
||||||
liblog.Log.Warn("not loggedin")
|
liblog.Log.Warn("not loggedin")
|
||||||
return
|
return
|
||||||
|
|
Reference in New Issue