作者 唐旭辉

新增

... ... @@ -10,6 +10,7 @@ require (
github.com/lib/pq v1.2.0 // indirect
github.com/onsi/ginkgo v1.10.3 // indirect
github.com/onsi/gomega v1.7.1 // indirect
github.com/satori/go.uuid v1.2.0
github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 // indirect
github.com/sony/sonyflake v1.0.0
golang.org/x/crypto v0.0.0-20191119213627-4f8c1d86b1ba // indirect
... ...
... ... @@ -45,6 +45,8 @@ github.com/onsi/gomega v1.7.1 h1:K0jcRCwNQM3vFGh1ppMtDh/+7ApJrjldlX8fA0jDTLQ=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644 h1:X+yvsM2yrEktyI+b2qND5gpH8YhURn0k8OCaeRnkINo=
github.com/shiena/ansicolor v0.0.0-20151119151921-a422bbe96644/go.mod h1:nkxAfR/5quYxwPZhyDxgasBMnRtBZd0FCEpawpjMUFg=
github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
... ...
... ... @@ -11,7 +11,7 @@ import (
)
type User struct {
Id int `orm:"column(id);pk" description:"用户id"`
Id int64 `orm:"column(id);pk" description:"用户id"`
NickName string `orm:"column(nick_name);size(100)" description:"昵称"`
Phone string `orm:"column(phone);size(40)" description:"手机号码"`
Passwd string `orm:"column(passwd);size(128)" description:"密码"`
... ... @@ -42,7 +42,7 @@ func AddUser(m *User) (id int64, err error) {
// GetUserById retrieves User by Id. Returns error if
// Id doesn't exist
func GetUserById(id int) (v *User, err error) {
func GetUserById(id int64) (v *User, err error) {
o := orm.NewOrm()
v = &User{Id: id}
if err = o.Read(v); err == nil {
... ... @@ -146,7 +146,7 @@ func UpdateUserById(m *User) (err error) {
// DeleteUser deletes User by Id and returns error if
// the record to be deleted doesn't exist
func DeleteUser(id int) (err error) {
func DeleteUser(id int64) (err error) {
o := orm.NewOrm()
v := User{Id: id}
// ascertain id exists in the database
... ... @@ -158,3 +158,12 @@ func DeleteUser(id int) (err error) {
}
return
}
func GetUserByPhone(phone string) (v *User, err error) {
o := orm.NewOrm()
v = &User{Phone: phone}
if err = o.Read(v, "Phone"); err == nil {
return v, nil
}
return nil, err
}
... ...
package models
import (
"errors"
"fmt"
"reflect"
"strings"
"time"
"github.com/astaxie/beego/orm"
)
type UserAuth struct {
Id int `orm:"column(id);auto"`
Id int64 `orm:"column(id);auto"`
UserId int64 `orm:"column(user_id)" description:"表user.id "`
RefreshToken string `orm:"column(refresh_token);size(64)" description:"refresh token "`
RefreshTokenExp time.Time `orm:"column(refresh_token_exp);type(timestamp)" description:"refresh token 过期时间"`
... ... @@ -19,7 +16,7 @@ type UserAuth struct {
AccessTokenExp time.Time `orm:"column(access_token_exp);type(timestamp)" description:"access token 过期时间"`
AuthCode string `orm:"column(auth_code);size(64)" description:"auth_code"`
AuthCodeExp time.Time `orm:"column(auth_code_exp);type(timestamp)" description:"auth_code过期时间"`
DeviceType int8 `orm:"column(device_type)" description:"设备类型 0:ios 1:安卓 2:web "`
DeviceType int8 `orm:"column(device_type)" description:"设备类型 1:ios 2:安卓 3:web "`
ClientId string `orm:"column(client_id);size(100)" description:"设备识别码 推送标识"`
DeviceToken string `orm:"column(device_token);size(100)" description:"设备识别码 推送标识"`
CreateAt time.Time `orm:"column(create_at);type(timestamp)" description:"创建时间"`
... ... @@ -34,6 +31,21 @@ func init() {
orm.RegisterModel(new(UserAuth))
}
//设备类型 1:ios 2:安卓 3:web
const (
_ int8 = iota
DEVICE_TYPE_IOS
DEVICE_TYPE_ANDROID
DEVICE_TYPE_WEB
)
//过期时长设置,单位:秒
const (
REFRESH_TIME int64 = 60 * 60 * 4 //4小时
ACCESS_TIME int64 = 60 * 60 * 2 //2小时
AUTHCODE_TIME int64 = 60 * 60 * 2 //2小时
)
// AddUserAuth insert a new UserAuth into database and returns
// last inserted Id on success.
func AddUserAuth(m *UserAuth) (id int64, err error) {
... ... @@ -44,7 +56,7 @@ func AddUserAuth(m *UserAuth) (id int64, err error) {
// GetUserAuthById retrieves UserAuth by Id. Returns error if
// Id doesn't exist
func GetUserAuthById(id int) (v *UserAuth, err error) {
func GetUserAuthById(id int64) (v *UserAuth, err error) {
o := orm.NewOrm()
v = &UserAuth{Id: id}
if err = o.Read(v); err == nil {
... ... @@ -53,84 +65,6 @@ func GetUserAuthById(id int) (v *UserAuth, err error) {
return nil, err
}
// GetAllUserAuth retrieves all UserAuth matches certain condition. Returns empty list if
// no records exist
func GetAllUserAuth(query map[string]string, fields []string, sortby []string, order []string,
offset int64, limit int64) (ml []interface{}, err error) {
o := orm.NewOrm()
qs := o.QueryTable(new(UserAuth))
// query k=v
for k, v := range query {
// rewrite dot-notation to Object__Attribute
k = strings.Replace(k, ".", "__", -1)
if strings.Contains(k, "isnull") {
qs = qs.Filter(k, (v == "true" || v == "1"))
} else {
qs = qs.Filter(k, v)
}
}
// order by:
var sortFields []string
if len(sortby) != 0 {
if len(sortby) == len(order) {
// 1) for each sort field, there is an associated order
for i, v := range sortby {
orderby := ""
if order[i] == "desc" {
orderby = "-" + v
} else if order[i] == "asc" {
orderby = v
} else {
return nil, errors.New("Error: Invalid order. Must be either [asc|desc]")
}
sortFields = append(sortFields, orderby)
}
qs = qs.OrderBy(sortFields...)
} else if len(sortby) != len(order) && len(order) == 1 {
// 2) there is exactly one order, all the sorted fields will be sorted by this order
for _, v := range sortby {
orderby := ""
if order[0] == "desc" {
orderby = "-" + v
} else if order[0] == "asc" {
orderby = v
} else {
return nil, errors.New("Error: Invalid order. Must be either [asc|desc]")
}
sortFields = append(sortFields, orderby)
}
} else if len(sortby) != len(order) && len(order) != 1 {
return nil, errors.New("Error: 'sortby', 'order' sizes mismatch or 'order' size is not 1")
}
} else {
if len(order) != 0 {
return nil, errors.New("Error: unused 'order' fields")
}
}
var l []UserAuth
qs = qs.OrderBy(sortFields...)
if _, err = qs.Limit(limit, offset).All(&l, fields...); err == nil {
if len(fields) == 0 {
for _, v := range l {
ml = append(ml, v)
}
} else {
// trim unused fields
for _, v := range l {
m := make(map[string]interface{})
val := reflect.ValueOf(v)
for _, fname := range fields {
m[fname] = val.FieldByName(fname).Interface()
}
ml = append(ml, m)
}
}
return ml, nil
}
return nil, err
}
// UpdateUserAuth updates UserAuth by Id and returns error if
// the record to be updated doesn't exist
func UpdateUserAuthById(m *UserAuth) (err error) {
... ... @@ -148,7 +82,7 @@ func UpdateUserAuthById(m *UserAuth) (err error) {
// DeleteUserAuth deletes UserAuth by Id and returns error if
// the record to be deleted doesn't exist
func DeleteUserAuth(id int) (err error) {
func DeleteUserAuth(id int64) (err error) {
o := orm.NewOrm()
v := UserAuth{Id: id}
// ascertain id exists in the database
... ... @@ -160,3 +94,32 @@ func DeleteUserAuth(id int) (err error) {
}
return
}
func ValidateDdevice(deviceType int8) bool {
switch deviceType {
case DEVICE_TYPE_IOS:
return true
case DEVICE_TYPE_ANDROID:
return true
case DEVICE_TYPE_WEB:
return true
}
return false
}
//ReadUserAuthByDevice 读取或创建
func ReadUserAuthByDevice(userId int64, deviceType int8) (*UserAuth, error) {
o := orm.NewOrm()
if ok := ValidateDdevice(deviceType); !ok {
return nil, fmt.Errorf("unknown deviceType: %d", deviceType)
}
uAuth := &UserAuth{
UserId: userId,
DeviceType: deviceType,
}
err := o.Read(uAuth, "UserId", "DeviceType")
if err == nil {
return uAuth, nil
}
return nil, err
}
... ...
... ... @@ -33,6 +33,7 @@ type RequestLogin struct {
//ResponseLogin 登录响应
type ResponseLogin struct {
AuthCode string `json:"authcode"`
}
//RequestSwapCompany 切换公司
... ...
package protocol
//RequestPageInfo 分页获取数据
type RequestPageInfo struct {
PageIndex int `json:"page_index"`
PageSize int `json:"page_size`
}
//ResponsePageInfo 分页信息
type ResponsePageInfo struct {
TotalPage int `json:"total_page"`
CurrentPage int `json:"current_page"`
}
... ...
package protocol
var errmessge ErrorMap = map[string]string{
"1": "系统异常",
"101": "clientId或clientSecret无效",
"113": "签名验证失败",
"00000": "成功",
"1": "系统异常",
"101": "clientId或clientSecret无效",
"113": "签名验证失败",
}
... ...
... ... @@ -3,14 +3,10 @@ package protocol
//RequestRoleAdd 添加角色信息操作入参
type RequestRoleAdd struct {
CompanyID int `json:"company,omitempty"`
RoleName string `json:"role_name"`
Name string `json:"name"`
Descript string `json:"descript"`
}
// func (r RequestRoleAdd) Valid() error {
// return nil
// }
//RequestRoleDelete 删除一个角色数据
type RequestRoleDelete struct {
CompanyID int `json:"company_id"`
... ... @@ -19,8 +15,8 @@ type RequestRoleDelete struct {
//RequestRoleEdit 编辑角色信息入参
type RequestRoleEdit struct {
RoleID int `json:"role_id"`
RoleName string `json:"role_name"`
ID int `json:"id"`
Name string `json:"name"`
CompanyID int `json:"company_id"`
Descript string `json:"descript"`
}
... ... @@ -33,16 +29,23 @@ type RequestRoleOne struct {
//ResponseRoleInfo 响应数据
type ResponseRoleInfo struct {
RoleID int `json:"role_id"`
RoleName string `json:"role_name"`
Descript string `json:"descript"`
ID int `json:"id"`
Name string `json:"name"`
Descript string `json:"descript"`
CreateTime int64 `json:"create_time`
UpdateTime int64 `json:"update_time"`
}
//RequestRoleList 分页获取角色列表
type RequestRoleList struct {
PageIndex int `json:"page_index"`
PageSize int `json:"page_size"`
keyword string `json:"keyword"` // 搜索关键字
RequestPageInfo
CompanyId int `json:"company_id"`
Keyword string `json:"keyword"` // 搜索关键字
}
type ResponseRoleList struct {
ResponsePageInfo
Data []ResponseRoleInfo `json:"data`
}
type RequestRolePermission struct {
... ...
... ... @@ -5,22 +5,28 @@ import (
"oppmg/common/log"
"oppmg/models"
"oppmg/protocol"
"oppmg/utils"
"time"
)
func RoleAdd(param protocol.RequestRoleAdd) error {
func RoleAdd(param protocol.RequestRoleAdd) (*protocol.ResponseRoleInfo, error) {
role := models.Role{
CompanyId: param.CompanyID,
Name: param.RoleName,
Name: param.Name,
CreateAt: time.Now(),
Descript: param.Descript,
}
_, err := models.AddRole(&role)
roleid, err := models.AddRole(&role)
if err != nil {
log.Error("AddRole err:%s", err)
return protocol.NewErrWithMessage("1", err)
return nil, protocol.NewErrWithMessage("1", err)
}
return nil
r := &protocol.ResponseRoleInfo{
ID: int(roleid),
Name: role.Name,
Descript: role.Descript,
}
return r, nil
}
func RoleDelete(param protocol.RequestRoleDelete) error {
... ... @@ -44,40 +50,69 @@ func RoleDelete(param protocol.RequestRoleDelete) error {
return nil
}
func RoleEdit(param protocol.RequestRoleEdit) error {
func RoleEdit(param protocol.RequestRoleEdit) (*protocol.ResponseRoleInfo, error) {
var (
role *models.Role
err error
)
role, err = models.GetRoleById(param.RoleID)
role, err = models.GetRoleById(param.ID)
if err != nil {
e := fmt.Errorf("GetRoleById err:%s", err)
log.Error(e.Error())
return protocol.NewErrWithMessage("1", e)
return nil, protocol.NewErrWithMessage("1", e)
}
if role.CompanyId != param.CompanyID {
e := fmt.Errorf("role.CompanyId(%d) != param.CompanyID(%d)", role.CompanyId, param.CompanyID)
log.Error(e.Error())
return protocol.NewErrWithMessage("1", e)
return nil, protocol.NewErrWithMessage("1", e)
}
role.Descript = param.Descript
role.Name = param.RoleName
role.Name = param.Name
if err = models.UpdateRoleById(role); err != nil {
e := fmt.Errorf("UpdateRoleById err:%s", err)
log.Error(e.Error())
return protocol.NewErrWithMessage("1", e)
return nil, protocol.NewErrWithMessage("1", e)
}
return nil
r := &protocol.ResponseRoleInfo{
ID: param.ID,
Name: param.Name,
Descript: param.Descript,
}
return r, nil
}
func RoleGetOne(param protocol.RequestRoleOne) error {
func RoleGetOne(param protocol.RequestRoleOne) (*protocol.ResponseRoleInfo, error) {
return nil
return nil, nil
}
func RoleGetByPage(param protocol.RequestRoleList) error {
return nil
func RoleGetByPage(param protocol.RequestRoleList) (*protocol.ResponseRoleList, error) {
var (
where string = `a.company_id=? and a.delete_at=0`
dataSql string = `SELECT a.id,a.name,a.descript,a.create_at,a.update_at
FROM role AS a
where ` + where
countSql string = `SELECT COUNT(*) FROM role as a where ` + where
)
var (
roleList []protocol.ResponseRoleInfo
pageinfo protocol.ResponsePageInfo
err error
)
pagequery := utils.NewQueryDataByPage(countSql, dataSql)
pagequery.LimitPage(param.PageIndex, param.PageSize)
pagequery.AddParam(param.CompanyId)
pageinfo, err = pagequery.Query(&roleList)
if err != nil {
e := fmt.Errorf("SQL EXECUTE err:%s", err)
log.Error(e.Error())
return nil, protocol.NewErrWithMessage("1", e)
}
r := &protocol.ResponseRoleList{
ResponsePageInfo: pageinfo,
Data: roleList,
}
return r, nil
}
func RoleHasPermission() error {
... ...
... ... @@ -2,12 +2,18 @@ package serveauth
import (
"crypto/sha1"
"encoding/hex"
"fmt"
"io"
"oppmg/common/config"
"oppmg/common/log"
"oppmg/models"
"oppmg/protocol"
"oppmg/utils"
"strings"
"time"
"github.com/astaxie/beego/orm"
)
//GetAccessToken 获取accessToken
... ... @@ -21,11 +27,11 @@ func GetAccessToken(param protocol.RequestCheckSmsCode) (*protocol.DataUserInfo,
//ValidatePassword ...
//from:待校验的密码;to:比对用的密文
func ValidatePassword(from, to string) bool {
func validatePassword(from, to string) bool {
//密码加密方式sha1
h := sha1.New()
io.WriteString(h, from)
str := fmt.Sprintf("%x", h.Sum(nil))
str := hex.EncodeToString(h.Sum(nil))
if strings.Compare(str, to) == 0 {
return true
}
... ... @@ -33,7 +39,59 @@ func ValidatePassword(from, to string) bool {
}
//LoginAuth 登录认证
func LoginAuth(account, password string) error {
func LoginAuthByPassword(account, password string) error {
var (
user *models.User
uAuth *models.UserAuth
err error
)
user, err = models.GetUserByPhone(account)
if err != nil {
log.Error(err.Error())
return protocol.NewErrWithMessage("1", err)
}
if ok := validatePassword(password, user.Passwd); !ok {
return protocol.NewErrWithMessage("1", err)
}
uAuth, err = models.ReadUserAuthByDevice(user.Id, models.DEVICE_TYPE_WEB)
if err != nil && err != orm.ErrNoRows {
e := fmt.Errorf("ReadUserAuthByDevice(%d,%d) err:%s", user.Id, models.DEVICE_TYPE_WEB, err)
log.Error(e.Error())
return protocol.NewErrWithMessage("1", e)
}
var (
authcode string
authcodeExp time.Time
)
authcode = utils.GenerateIDByUUID()
authcodeExp = time.Now().Add(time.Duration(models.AUTHCODE_TIME) * time.Second)
if err == orm.ErrNoRows {
uAuth := &models.UserAuth{
UserId: user.Id,
AuthCode: authcode,
AuthCodeExp: authcodeExp,
CreateAt: time.Now(),
}
_, err = models.AddUserAuth(uAuth)
if err != nil {
e := fmt.Errorf("AddUserAuth err:%s", err)
log.Error(e.Error())
return protocol.NewErrWithMessage("1", e)
}
}
if err == nil {
uAuth.AuthCode = authcode
uAuth.AuthCodeExp = authcodeExp
uAuth.UpdateAt = time.Now()
err = models.UpdateUserAuthById(uAuth)
if err != nil {
e := fmt.Errorf("UpdateUserAuthById err:%s", err)
log.Error(e.Error())
return protocol.NewErrWithMessage("1", e)
}
}
return nil
}
... ... @@ -41,3 +99,10 @@ func LoginAuth(account, password string) error {
func RefreshAccessToken(account string, token string) error {
return nil
}
// func buildNewUserAuth(uid int64,) *models.UserAuth {
// m:=&models.UserAuth{
// User
// }
// return nil
// }
... ...
package utils
import (
"encoding/hex"
uuid "github.com/satori/go.uuid"
"github.com/sony/sonyflake"
)
var sf = sonyflake.NewSonyflake(sonyflake.Settings{})
func GetUniqueId() int64 {
func GenerateIDBySonyflake() int64 {
num, _ := sf.NextID()
return int64(num)
}
func GenerateIDByUUID() string {
ubyte := uuid.NewV4().Bytes()
s := hex.EncodeToString(ubyte)
return s
}
... ...
package utils
import (
"fmt"
"time"
jwt "github.com/dgrijalva/jwt-go"
... ... @@ -13,7 +14,8 @@ var (
//MyToken ...
type MyToken struct {
jwt.StandardClaims
ID int `json:"id"`
UID int `json:"uid"`
CompanyID int `json:"company_id"`
}
//CreateJWTToken ...
... ... @@ -26,7 +28,7 @@ func CreateJWTToken(id int) (string, error) {
ExpiresAt: 60 * 60 * 2, //过期时间
Issuer: "test_a",
},
ID: id,
UID: id,
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
... ... @@ -49,5 +51,5 @@ func ValidJWTToken(tokenString string) (*MyToken, error) {
return claims, nil
}
// 验证失败
return nil, err
return nil, fmt.Errorf("token Valid fail")
}
... ...
package utils
import (
"fmt"
"oppmg/common/log"
"oppmg/protocol"
"github.com/astaxie/beego/orm"
)
//PrintLogSql 打印sql语句
func PrintLogSql(sql string, param ...interface{}) {
format := `SQL EXCUTE:[%s]-%s`
log.Debug(format, sql, fmt.Sprint(param...))
}
//ExcuteSql 执行原生sql语句
func ExcuteSql(result interface{}, sqlstr string, param ...interface{}) error {
PrintLogSql(sqlstr, param...)
var err error
o := orm.NewOrm()
err = ExcuteSqlWithOrmer(o, result, sqlstr, param)
return err
}
//ExcuteSqlWithOrmer 执行原生sql语句
func ExcuteSqlWithOrmer(o orm.Ormer, result interface{}, sqlstr string, param ...interface{}) error {
PrintLogSql(sqlstr, param...)
var err error
err = o.Raw(sqlstr, param).QueryRow(result)
if err != nil {
return fmt.Errorf("SQL EXCUTE err:%s", err)
}
return nil
}
type QueryDataByPage struct {
CountSql string
DataSql string
Param []interface{}
offset int
num int
}
func NewQueryDataByPage(countsql, datasql string) *QueryDataByPage {
return &QueryDataByPage{
CountSql: countsql,
DataSql: datasql,
}
}
func (q *QueryDataByPage) AddParam(param ...interface{}) {
q.Param = param
}
func (q *QueryDataByPage) LimitPage(offset, num int) {
q.offset = offset
q.num = num
}
func (q *QueryDataByPage) Query(result interface{}) (pageinfo protocol.ResponsePageInfo, err error) {
pagebegin := (q.offset - 1) * q.num
if pagebegin < 0 {
pagebegin = 0
}
var (
total int
)
o := orm.NewOrm()
err = ExcuteSqlWithOrmer(o, &total, q.CountSql, q.Param...)
if err != nil {
return
}
if total == 0 {
return protocol.ResponsePageInfo{CurrentPage: q.offset, TotalPage: total}, nil
}
q.DataSql = fmt.Sprintf("%s limit %d,%d", q.DataSql, pagebegin, q.num)
err = ExcuteSqlWithOrmer(o, result, q.DataSql, q.Param...)
if err != nil {
return
}
return protocol.ResponsePageInfo{CurrentPage: q.offset, TotalPage: total}, nil
}
... ...