mirror of
https://github.com/ICKelin/cframe.git
synced 2025-12-24 13:28:19 +08:00
feature: add usercenter
- add usercenter manager for user/auth
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -3,4 +3,5 @@ bin
|
||||
log
|
||||
*.log
|
||||
dist
|
||||
webui
|
||||
webui
|
||||
tool
|
||||
41
usercenter/config.go
Normal file
41
usercenter/config.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/pelletier/go-toml"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
ListenAddr string `toml:"listenAddr"`
|
||||
MongoUrl string `toml:"mongoUrl"`
|
||||
DBName string `toml:"dbname"`
|
||||
Log Log `toml:"log"`
|
||||
}
|
||||
|
||||
type Log struct {
|
||||
Level string `toml:"level"`
|
||||
Path string `toml:"path"`
|
||||
Days int64 `toml:"days"`
|
||||
}
|
||||
|
||||
func ParseConfig(path string) (*Config, error) {
|
||||
cnt, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var cfg Config
|
||||
err = toml.Unmarshal(cnt, &cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &cfg, nil
|
||||
}
|
||||
|
||||
func (c *Config) String() string {
|
||||
b, _ := json.MarshalIndent(c, "", "\t")
|
||||
return string(b)
|
||||
}
|
||||
26
usercenter/main.go
Normal file
26
usercenter/main.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
"github.com/ICKelin/cframe/pkg/database"
|
||||
log "github.com/ICKelin/cframe/pkg/logs"
|
||||
)
|
||||
|
||||
func main() {
|
||||
flgConf := flag.String("c", "", "config file")
|
||||
flag.Parse()
|
||||
conf, err := ParseConfig(*flgConf)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
log.Init(conf.Log.Path, conf.Log.Level, conf.Log.Days)
|
||||
// initial mongodb url
|
||||
database.NewModelManager(conf.MongoUrl, conf.DBName)
|
||||
|
||||
s := NewServer(conf.ListenAddr)
|
||||
fmt.Println(s.ListenAndServe())
|
||||
}
|
||||
49
usercenter/models/authorize.go
Normal file
49
usercenter/models/authorize.go
Normal file
@@ -0,0 +1,49 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/ICKelin/cframe/pkg/database"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
)
|
||||
|
||||
var (
|
||||
C_AUTH = "authorize"
|
||||
)
|
||||
|
||||
type Auth struct {
|
||||
database.Model `bson:",inline"`
|
||||
UserId bson.ObjectId `json:"userId" bson:"userId"`
|
||||
Token string `json:"token" bson:"token"`
|
||||
ExpiredIn int64 `json:"expiredIn" bson:"expiredIn"`
|
||||
}
|
||||
|
||||
type AuthManager struct {
|
||||
database.ModelManager
|
||||
}
|
||||
|
||||
func GetAuthManager() *AuthManager {
|
||||
return &AuthManager{}
|
||||
}
|
||||
|
||||
func (m *AuthManager) AddAuth(authInfo *Auth) (*Auth, error) {
|
||||
authInfo.CreatedAt = time.Now().Unix()
|
||||
authInfo.UpdatedAt = time.Now().Unix()
|
||||
err := m.Insert(C_AUTH, authInfo)
|
||||
return authInfo, err
|
||||
}
|
||||
|
||||
func (m *AuthManager) GetAuthByToken(token string) (*Auth, error) {
|
||||
var result *Auth
|
||||
var query = bson.M{}
|
||||
query["invalid"] = false
|
||||
query["token"] = token
|
||||
// query["expiredIn"] = bson.M{"$gte": time.Now().Unix()}
|
||||
|
||||
err := m.FindOne(C_AUTH, query, &result)
|
||||
if result == nil {
|
||||
return nil, fmt.Errorf("not found")
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
106
usercenter/models/user.go
Normal file
106
usercenter/models/user.go
Normal file
@@ -0,0 +1,106 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/ICKelin/cframe/pkg/database"
|
||||
"gopkg.in/mgo.v2/bson"
|
||||
)
|
||||
|
||||
var (
|
||||
C_USER = "user"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
database.Model `bson:",inline"`
|
||||
Username string `json:"username" bson:"username"`
|
||||
Password string `json:"-" bson:"password"`
|
||||
Secret string `json:"secret" bson:"secret"`
|
||||
Email string `json:"email" bson:"email"`
|
||||
About string `json:"about" bson:"about"`
|
||||
}
|
||||
|
||||
type UserManager struct {
|
||||
database.ModelManager
|
||||
}
|
||||
|
||||
func GetUserManager() *UserManager {
|
||||
return &UserManager{}
|
||||
}
|
||||
|
||||
func (m *UserManager) CreateUser(user *User) (*User, error) {
|
||||
user.CreatedAt = time.Now().Unix()
|
||||
user.UpdatedAt = time.Now().Unix()
|
||||
user.Id = bson.NewObjectId()
|
||||
err := m.Insert(C_USER, user)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return user, err
|
||||
}
|
||||
|
||||
func (m *UserManager) GetUserBySecret(secret string) (*User, error) {
|
||||
var result *User
|
||||
var query = bson.M{}
|
||||
query["secret"] = secret
|
||||
query["invalid"] = false
|
||||
|
||||
err := m.FindOne(C_USER, query, &result)
|
||||
if result == nil {
|
||||
return nil, fmt.Errorf("not found")
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (m *UserManager) GetUserByName(name string) (*User, error) {
|
||||
var result *User
|
||||
var query = bson.M{}
|
||||
query["username"] = name
|
||||
query["invalid"] = false
|
||||
|
||||
err := m.FindOne(C_USER, query, &result)
|
||||
if result == nil {
|
||||
return nil, fmt.Errorf("not found")
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
func (m *UserManager) GetUserByEmail(email string) (*User, error) {
|
||||
var result *User
|
||||
var query = bson.M{}
|
||||
query["email"] = email
|
||||
query["invalid"] = false
|
||||
|
||||
err := m.FindOne(C_USER, query, &result)
|
||||
if result == nil {
|
||||
return nil, fmt.Errorf("not found")
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
func (m *UserManager) GetUserById(userId bson.ObjectId) (*User, error) {
|
||||
var result *User
|
||||
var query = bson.M{}
|
||||
query["_id"] = userId
|
||||
query["invalid"] = false
|
||||
|
||||
err := m.FindOne(C_USER, query, &result)
|
||||
if result == nil {
|
||||
return nil, fmt.Errorf("not found")
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (m *UserManager) VerifyUser(username, password string) (*User, error) {
|
||||
var result *User
|
||||
var query = bson.M{}
|
||||
query["username"] = username
|
||||
query["password"] = password
|
||||
query["invalid"] = false
|
||||
|
||||
err := m.FindOne(C_USER, query, &result)
|
||||
if result == nil {
|
||||
return nil, fmt.Errorf("not found")
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
179
usercenter/server.go
Normal file
179
usercenter/server.go
Normal file
@@ -0,0 +1,179 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/ICKelin/cframe/codec/proto"
|
||||
log "github.com/ICKelin/cframe/pkg/logs"
|
||||
"github.com/ICKelin/cframe/usercenter/models"
|
||||
uuid "github.com/satori/go.uuid"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
addr string
|
||||
userManager *models.UserManager
|
||||
authManager *models.AuthManager
|
||||
}
|
||||
|
||||
func NewServer(addr string) *Server {
|
||||
return &Server{
|
||||
addr: addr,
|
||||
userManager: models.GetUserManager(),
|
||||
authManager: models.GetAuthManager(),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) ListenAndServe() error {
|
||||
listener, err := net.Listen("tcp", s.addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Info("listenning %v success", s.addr)
|
||||
srv := grpc.NewServer()
|
||||
proto.RegisterUserServiceServer(srv, s)
|
||||
return srv.Serve(listener)
|
||||
}
|
||||
|
||||
func (s *Server) GetUserBySecret(ctx context.Context,
|
||||
req *proto.GetUserBySecretReq) (*proto.GetUserBySecretReply, error) {
|
||||
user, err := s.userManager.GetUserBySecret(req.Secret)
|
||||
if err != nil {
|
||||
log.Error("get user by secret %s fail: %v", req.Secret, err)
|
||||
return &proto.GetUserBySecretReply{Code: 50000, Message: err.Error()}, nil
|
||||
}
|
||||
|
||||
return &proto.GetUserBySecretReply{
|
||||
UserInfo: &proto.UserInfo{
|
||||
UserId: user.Id.Hex(),
|
||||
UserName: user.Username,
|
||||
UserSecret: user.Secret,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) AddUser(ctx context.Context,
|
||||
req *proto.AddUserReq) (*proto.AddUserReply, error) {
|
||||
|
||||
badReq := &proto.AddUserReply{Code: 40000, Message: "Bad Param"}
|
||||
if len(req.UserName) <= 0 ||
|
||||
len(req.Password) <= 0 ||
|
||||
len(req.Email) <= 0 {
|
||||
return badReq, nil
|
||||
}
|
||||
|
||||
// verify user
|
||||
exist, _ := s.userManager.GetUserByName(req.UserName)
|
||||
if exist != nil {
|
||||
return &proto.AddUserReply{Code: 50000, Message: "user exist"}, nil
|
||||
}
|
||||
|
||||
exist, _ = s.userManager.GetUserByEmail(req.Email)
|
||||
if exist != nil {
|
||||
return &proto.AddUserReply{Code: 50000, Message: "email exist"}, nil
|
||||
}
|
||||
|
||||
userInfo := &models.User{
|
||||
Username: req.UserName,
|
||||
Password: req.Password,
|
||||
Email: req.Email,
|
||||
About: req.About,
|
||||
Secret: generateSecret(),
|
||||
}
|
||||
|
||||
r, err := s.userManager.CreateUser(userInfo)
|
||||
if err != nil {
|
||||
return &proto.AddUserReply{Code: 50000, Message: err.Error()}, nil
|
||||
}
|
||||
return &proto.AddUserReply{
|
||||
UserInfo: &proto.UserInfo{
|
||||
UserId: r.Id.Hex(),
|
||||
UserName: r.Username,
|
||||
UserEmail: r.Email,
|
||||
About: r.About,
|
||||
UserSecret: r.Secret,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) GetUserInfo(ctx context.Context,
|
||||
req *proto.GetUserInfoReq) (*proto.GetUserInfoReply, error) {
|
||||
user, err := s.userManager.VerifyUser(req.UserName, req.Password)
|
||||
if err != nil {
|
||||
return &proto.GetUserInfoReply{Code: 50000, Message: err.Error()}, nil
|
||||
}
|
||||
return &proto.GetUserInfoReply{
|
||||
UserInfo: &proto.UserInfo{
|
||||
UserId: user.Id.Hex(),
|
||||
UserName: user.Username,
|
||||
UserSecret: user.Secret,
|
||||
UserEmail: user.Email,
|
||||
CreatedAt: user.CreatedAt,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) Authorize(ctx context.Context,
|
||||
req *proto.AuthorizeReq) (*proto.AuthorizeReply, error) {
|
||||
userInfo, err := s.userManager.VerifyUser(req.Username, req.Password)
|
||||
if err != nil {
|
||||
// TODO: verify by email
|
||||
return &proto.AuthorizeReply{Code: 50000, Message: err.Error()}, nil
|
||||
}
|
||||
|
||||
authInfo := &models.Auth{
|
||||
UserId: userInfo.Id,
|
||||
Token: generateToken(),
|
||||
ExpiredIn: time.Now().Add(time.Hour * 1).Unix(),
|
||||
}
|
||||
|
||||
r, err := s.authManager.AddAuth(authInfo)
|
||||
if err != nil {
|
||||
return &proto.AuthorizeReply{Code: 50000, Message: err.Error()}, nil
|
||||
}
|
||||
|
||||
return &proto.AuthorizeReply{Data: &proto.AuthorizeReplyBody{
|
||||
UserId: userInfo.Id.Hex(),
|
||||
Token: r.Token,
|
||||
ExpiredIn: r.ExpiredIn,
|
||||
}}, nil
|
||||
|
||||
}
|
||||
|
||||
func (s *Server) GetUserByToken(ctx context.Context,
|
||||
req *proto.GetUserByTokenReq) (*proto.GetUserByTokenReply, error) {
|
||||
authInfo, err := s.authManager.GetAuthByToken(req.Token)
|
||||
if err != nil {
|
||||
log.Error("get user by token fail: %v", err)
|
||||
return &proto.GetUserByTokenReply{Code: 50000, Message: err.Error()}, nil
|
||||
}
|
||||
|
||||
userInfo, err := s.userManager.GetUserById(authInfo.UserId)
|
||||
if err != nil {
|
||||
log.Error("get user info fail: %v", err)
|
||||
return &proto.GetUserByTokenReply{Code: 50000, Message: err.Error()}, nil
|
||||
}
|
||||
|
||||
return &proto.GetUserByTokenReply{Data: &proto.UserInfo{
|
||||
UserId: userInfo.Id.Hex(),
|
||||
UserName: userInfo.Username,
|
||||
UserEmail: userInfo.Email,
|
||||
UserSecret: userInfo.Secret,
|
||||
About: userInfo.About,
|
||||
CreatedAt: userInfo.CreatedAt,
|
||||
}}, nil
|
||||
}
|
||||
|
||||
func generateSecret() string {
|
||||
uniq := uuid.NewV4()
|
||||
return base64.StdEncoding.EncodeToString(uniq.Bytes())
|
||||
}
|
||||
|
||||
func generateToken() string {
|
||||
uniq := uuid.NewV4()
|
||||
return base64.StdEncoding.EncodeToString(uniq.Bytes())
|
||||
}
|
||||
Reference in New Issue
Block a user