Skip to content

Commit

Permalink
Merge pull request #4 from MessageDream/web-layout
Browse files Browse the repository at this point in the history
admin panel
  • Loading branch information
Jayden Zhao committed Jul 27, 2017
2 parents 2644687 + 07ce96b commit 56e08aa
Show file tree
Hide file tree
Showing 40 changed files with 927 additions and 305 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ log
vendor
debug
npm-debug.log
*.zip
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@ As we know microsoft CodePush cloud is slow in China, we can use goby to build o
[![Go Report Card](https://goreportcard.com/badge/github.com/MessageDream/goby)](https://goreportcard.com/report/github.com/MessageDream/goby)
## INSTALL FROM BINARY
#### Linux
* [386](https://github.com/MessageDream/goby/releases/download/v0.1.0/goby-v0.1.0-linux-386.zip)
* [amd64](https://github.com/MessageDream/goby/releases/download/v0.1.0/goby-v0.1.0-linux-amd64.zip)
* [386](https://github.com/MessageDream/goby/releases/download/v0.1.1/goby-v0.1.1-linux-386.zip)
* [amd64](https://github.com/MessageDream/goby/releases/download/v0.1.1/goby-v0.1.1-linux-amd64.zip)

#### Windows
* [386](https://github.com/MessageDream/goby/releases/download/v0.1.0/goby-v0.1.0-windows-386.zip)
* [amd64](https://github.com/MessageDream/goby/releases/download/v0.1.0/goby-v0.1.0-windows-amd64.zip)
* [386](https://github.com/MessageDream/goby/releases/download/v0.1.1/goby-v0.1.1-windows-386.zip)
* [amd64](https://github.com/MessageDream/goby/releases/download/v0.1.1/goby-v0.1.1-windows-amd64.zip)

#### Darwin
* [386](https://github.com/MessageDream/goby/releases/download/v0.1.0/goby-v0.1.0-darwin-386.zip)
* [amd64](https://github.com/MessageDream/goby/releases/download/v0.1.0/goby-v0.1.0-darwin-amd64.zip)
* [386](https://github.com/MessageDream/goby/releases/download/v0.1.1/goby-v0.1.1-darwin-386.zip)
* [amd64](https://github.com/MessageDream/goby/releases/download/v0.1.1/goby-v0.1.1-darwin-amd64.zip)


```shell
Expand Down
13 changes: 13 additions & 0 deletions cmd/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ func runWeb(cliCtx *cli.Context) {
reqSignIn := context.Toggle(&context.ToggleOptions{SignInRequire: true})
ignSignIn := context.Toggle(&context.ToggleOptions{SignInRequire: setting.Service.RequireSignInView})
reqSignOut := context.Toggle(&context.ToggleOptions{SignOutRequire: true})
reqAdmin := context.Toggle(&context.ToggleOptions{SignInRequire: true, AdminRequire: true})
bindIgnErr := binding.BindIgnErr

apiBind := binding.Bind
Expand All @@ -168,8 +169,20 @@ func runWeb(cliCtx *cli.Context) {
m.Combo("/list").Get(web.AccessKeysGet)
}, reqSignIn)

m.Group("/admin/api", func() {
m.Get("/users/:pageIndex/:pageCount", web.UsersQuery)
m.Post("/users/add", web.UserAddPost)
m.Patch("/users/:email/status", web.UserPatch)
m.Patch("/users/:email/role", web.UserPatch)
}, reqAdmin)

m.Group("/admin", func() {
m.Get("/users", web.UsersGet)
}, reqAdmin)

})

//cli
m.Group("/auth", func() {
m.Combo("/login").Get(auth.SignInGet)
m.Combo("/register").Get(auth.SignUpGet)
Expand Down
2 changes: 2 additions & 0 deletions core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ const (
INTENT_ERROR_CODE_USER_ACTIVATE_VERIFY_FAILED

INTENT_ERROR_CODE_USER_USERNAME_OR_PWD_INVALID
INTENT_ERROR_CODE_USER_FORBIDDEN
)

var (
Expand All @@ -91,6 +92,7 @@ var (
ErrUserAlreadyActivated = WrapIntentError(errors.New("User has been activated before"), INTENT_ERROR_CODE_USER_ACTIVATE_HAS_ACTIVATED)
ErrUserActivateTimeLimitCodeLength = WrapIntentError(errors.New("Time limit code length is too short"), INTENT_ERROR_CODE_USER_ACTIVATE_TIME_LIMIT_LENGTH)
ErrUserActivateVerifyFailed = WrapIntentError(errors.New("Active code is invalid"), INTENT_ERROR_CODE_USER_ACTIVATE_VERIFY_FAILED)
ErrUserForbidden = WrapIntentError(errors.New("User is forbidden"), INTENT_ERROR_CODE_USER_FORBIDDEN)
)

//Token
Expand Down
4 changes: 4 additions & 0 deletions core/tokenService/token_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ func checkToken(token string) (*model.User, *model.UserToken, error) {
return nil, nil, err
}

if user.Status == model.USER_STATUS_FORBIDDEN {
return nil, nil, ErrUserForbidden
}

tok := &model.UserToken{UID: user.ID, Token: token}

if exist, err := tok.GetUnexpired(); err != nil || !exist {
Expand Down
87 changes: 81 additions & 6 deletions core/userService/user_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ import (
"unicode/utf8"

"github.com/Unknwon/com"
. "gopkg.in/ahmetb/go-linq.v3"

. "github.com/MessageDream/goby/core"
"github.com/MessageDream/goby/model"
"github.com/MessageDream/goby/model/dto"
"github.com/MessageDream/goby/module/infrastructure"
"github.com/MessageDream/goby/module/setting"
)
Expand Down Expand Up @@ -84,11 +86,11 @@ func Active(code string) (*model.User, error) {
return nil, err
}

if user.IsActive {
if user.Status != model.USER_STATUS_UN_ACTIVE {
return nil, ErrUserAlreadyActivated
}

user.IsActive = true
user.Status = model.USER_STATUS_NORMAL
user.GenerateRands()
if err := user.Update(nil, "is_active", "rands"); err != nil {
return nil, err
Expand All @@ -97,7 +99,7 @@ func Active(code string) (*model.User, error) {
return user, nil
}

func Create(uname, pwd, email string, isActive, isAdmin bool) (*model.User, error) {
func Create(uname, pwd, email string, status int, isAdmin bool) (*model.User, error) {

if err := isUsableName(reservedUsernames, reservedUserPatterns, uname); err != nil {
return nil, err
Expand All @@ -108,7 +110,7 @@ func Create(uname, pwd, email string, isActive, isAdmin bool) (*model.User, erro
LowerName: strings.ToLower(uname),
Password: pwd,
Email: email,
IsActive: isActive,
Status: status,
IsAdmin: isAdmin,
}
if exist, err := user.Exist(); err != nil || exist {
Expand Down Expand Up @@ -153,7 +155,7 @@ func GetByRands(rands string) (*model.User, error) {
return user, nil
}

func GetByUserName(uname string) (*model.User, error) {
func SignInWithUserName(uname string) (*model.User, error) {
user := &model.User{LowerName: strings.ToLower(uname)}

if exist, err := user.Get(); err != nil || !exist {
Expand All @@ -162,10 +164,15 @@ func GetByUserName(uname string) (*model.User, error) {
}
return nil, err
}

if user.Status == model.USER_STATUS_FORBIDDEN {
return nil, ErrUserForbidden
}

return user, nil
}

func Signin(emailOrName, pwd string) (*model.User, error) {
func SignIn(emailOrName, pwd string) (*model.User, error) {
var user *model.User
if strings.Contains(emailOrName, "@") {
if !infrastructure.VerifyEmail(emailOrName) || len(pwd) <= 0 {
Expand All @@ -190,5 +197,73 @@ func Signin(emailOrName, pwd string) (*model.User, error) {
if !user.ValidatePassword(pwd) {
return nil, ErrUserNameOrPasswordInvalide
}
if user.Status == model.USER_STATUS_FORBIDDEN {
return nil, ErrUserForbidden
}
return user, nil
}

func QueryUsers(uid uint64, pageIndex, pageCount int, email string) (*dto.Pager, error) {
if pageCount > 100 {
pageCount = 100
}
pager, err := model.QueryUsers(uid, pageIndex, pageCount, email)
if err != nil {
return nil, err
}

var results []*dto.UserDetail

From(pager.Data).Select(func(item interface{}) interface{} {
u := item.(*model.User)
var role = 0
if u.IsAdmin {
role = 1
}
return &dto.UserDetail{
Email: u.Email,
UserName: u.UserName,
Role: role,
Status: u.Status,
JoinedAt: u.CreatedAt,
}
}).ToSlice(&results)

return &dto.Pager{
TotalCount: pager.TotalCount,
TotalPageCount: pager.TotalPageCount,
PageIndex: pager.PageIndex,
PageCount: pager.PageCount,
Data: results,
}, nil
}

func UpdateRole(email string, role int) error {

user := &model.User{Email: email}
if exist, err := user.Get(); err != nil || !exist {
if !exist {
return ErrUserNotExist
}
return err
}

user.IsAdmin = role == 1

return user.Update(nil, "is_admin")
}

func UpdateStatus(email string, status int) error {

user := &model.User{Email: email}
if exist, err := user.Get(); err != nil || !exist {
if !exist {
return ErrUserNotExist
}
return err
}

user.Status = status

return user.Update(nil, "status")
}
2 changes: 1 addition & 1 deletion goby.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"github.com/MessageDream/goby/module/setting"
)

const APP_VER = "0.1.0"
const APP_VER = "0.1.1"

func init() {
runtime.GOMAXPROCS(runtime.NumCPU())
Expand Down
16 changes: 16 additions & 0 deletions model/dto/dto_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,19 @@ type Collaborator struct {
IsCurrentAccount bool `json:"isCurrentAccount"`
Permission string `json:"permission"`
}

type Pager struct {
PageIndex int `json:"pageIndex"`
PageCount int `json:"pageCount"`
TotalCount int64 `json:"totalCount"`
TotalPageCount int64 `json:"totalPageCount"`
Data interface{} `json:"data"`
}

type UserDetail struct {
Email string `json:"email"`
UserName string `json:"userName"`
Role int `json:"role"`
Status int `json:"status"`
JoinedAt time.Time `json:"joinedTime"`
}
45 changes: 44 additions & 1 deletion model/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,18 @@ import (
"github.com/Unknwon/com"
"golang.org/x/crypto/pbkdf2"

"math"

"github.com/MessageDream/goby/model/dto"
"github.com/MessageDream/goby/module/infrastructure"
"github.com/MessageDream/goby/module/mailer"
"github.com/go-xorm/xorm"
)

const (
USER_STATUS_UN_ACTIVE = iota
USER_STATUS_NORMAL
USER_STATUS_FORBIDDEN
)

type User struct {
Expand All @@ -24,7 +33,7 @@ type User struct {
UserName string
LowerName string `xorm:"unique notnull"`
IsAdmin bool `xorm:"notnull default(0)"`
IsActive bool `xorm:"notnull default(0)"`
Status int `xorm:"notnull default(0)"`
Salt string
CreatedAt time.Time `xorm:"created"`
UpdatedAt time.Time `xorm:"updated"`
Expand Down Expand Up @@ -124,6 +133,40 @@ func FindUserByIDs(ids []uint64) ([]*User, error) {
return users, x.In("id", ids).Find(&users)
}

func QueryUsers(currentUserID uint64, pageIndex, pageCount int, email string) (*dto.Pager, error) {
users := make([]*User, 0, 50)
var sess *xorm.Session
if len(email) != 0 {
sess = x.Where("id > ? and id != ? and email like ?", 1, currentUserID, "%"+email+"%")
} else {
sess = x.Where("id > ? and id != ?", 1, currentUserID)
}
total, err := sess.Count(new(User))
if err != nil {
return nil, err
}

if len(email) != 0 {
sess = x.Where("id > ? and id != ? and email like ?", 1, currentUserID, "%"+email+"%")
} else {
sess = x.Where("id > ? and id != ?", 1, currentUserID)
}

err = sess.Desc("created_at").Limit(pageCount, pageIndex*pageCount).Find(&users)
if err != nil {
return nil, err
}

return &dto.Pager{
TotalCount: total,
TotalPageCount: int64(math.Ceil(float64(total) / float64(pageCount))),
PageIndex: pageIndex,
PageCount: pageCount,
Data: users,
}, nil

}

type mailerUser struct {
user *User
activeCodeLives int
Expand Down
3 changes: 3 additions & 0 deletions module/context/api_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,10 @@ func (ctx *APIContext) Auth() {
if len(token) > 0 {
u, err := checkAccessToken(token, ctx.Cache)
if err != nil {
ctx.SignError = err
return
}

ctx.User = u
ctx.IsSigned = true
ctx.IsBasicAuth = true
Expand Down Expand Up @@ -118,6 +120,7 @@ func APIContexter() macaron.Handler {
ctx := &APIContext{
Context: c,
}
ctx.Auth()
c.Map(ctx)
}
}
Loading

0 comments on commit 56e08aa

Please sign in to comment.