Skip to content

Commit

Permalink
add para hmac
Browse files Browse the repository at this point in the history
  • Loading branch information
Dot-Liu committed Oct 31, 2024
1 parent a342973 commit add599e
Show file tree
Hide file tree
Showing 5 changed files with 226 additions and 0 deletions.
22 changes: 22 additions & 0 deletions application/auth/para-hmac/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package para_hmac

import "github.com/eolinker/apinto/application"

type Config struct {
application.Auth
Users []*User `json:"users" label:"用户列表"`
}

type User struct {
Pattern Pattern `json:"pattern" label:"用户信息"`
application.User
}

type Pattern struct {
AppID string `json:"app_id"`
AppKey string `json:"app_key"`
}

func (u *User) Username() string {
return u.Pattern.AppID
}
95 changes: 95 additions & 0 deletions application/auth/para-hmac/executor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package para_hmac

import (
"net/url"

"github.com/eolinker/apinto/application"
)

import (
"fmt"

http_service "github.com/eolinker/eosc/eocontext/http-context"
)

var _ application.IAuth = (*executor)(nil)

type executor struct {
id string
tokenName string
position string
users application.IUserManager
}

func (a *executor) GetUser(ctx http_service.IHttpContext) (*application.UserInfo, bool) {
token, has := application.GetToken(ctx, a.tokenName, a.position)
if !has || token == "" {
return nil, false
}
appId := ctx.Request().Header().GetHeader("X-App-Id")
if appId == "" {
return nil, false
}
user, has := a.users.Get(appId)
if !has {
return nil, false
}
sequenceNo := ctx.Request().Header().GetHeader("X-Sequence-No")
timestamp := ctx.Request().Header().GetHeader("X-Timestamp")
body, _ := ctx.Request().Body().RawBody()
signText := ctx.Request().Header().GetHeader("X-Signature")
verifySign := sign(appId, user.Value, timestamp, sequenceNo, string(body))
escapeSign := url.QueryEscape(verifySign)
if verifySign == signText || escapeSign == signText {
return user, true
}

return nil, false
}

func (a *executor) ID() string {
return a.id
}

func (a *executor) Driver() string {
return driverName
}

func (a *executor) Check(appID string, users []application.ITransformConfig) error {
us := make([]application.IUser, 0, len(users))
for _, u := range users {
v, ok := u.Config().(*User)
if !ok {
return fmt.Errorf("%s check error: invalid config type", driverName)
}
us = append(us, v)
}
return a.users.Check(appID, driverName, us)
}

func (a *executor) Set(app application.IApp, users []application.ITransformConfig) {
infos := make([]*application.UserInfo, 0, len(users))
for _, u := range users {
v, _ := u.Config().(*User)

infos = append(infos, &application.UserInfo{
Name: v.Username(),
Value: v.Pattern.AppKey,
Expire: v.Expire,
Labels: v.Labels,
HideCredential: v.HideCredential,
App: app,
TokenName: a.tokenName,
Position: a.position,
})
}
a.users.Set(app.Id(), infos)
}

func (a *executor) Del(appID string) {
a.users.DelByAppID(appID)
}

func (a *executor) UserCount() int {
return a.users.Count()
}
71 changes: 71 additions & 0 deletions application/auth/para-hmac/factory.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package para_hmac

import (
"fmt"
"reflect"

"github.com/eolinker/eosc/utils/schema"

"github.com/eolinker/apinto/application"
"github.com/eolinker/apinto/application/auth"
)

var _ auth.IAuthFactory = (*factory)(nil)

var driverName = "para-hmac"

// Register 注册auth驱动工厂
func Register() {
auth.FactoryRegister(driverName, NewFactory())
}

type factory struct {
configType reflect.Type
render *schema.Schema
userType reflect.Type
}

func (f *factory) Render() interface{} {
return f.render
}

func (f *factory) ConfigType() reflect.Type {
return f.configType
}

func (f *factory) UserType() reflect.Type {
return f.userType
}

func (f *factory) Alias() []string {
return []string{
"para_hmac",
"para-hmac",
}
}

func (f *factory) PreRouters() []*auth.PreRouter {
return nil
}

func (f *factory) Create(tokenName string, position string, rule interface{}) (application.IAuth, error) {
a := &executor{
id: toId(tokenName, position),
tokenName: tokenName,
position: position,
users: application.NewUserManager(),
}
return a, nil
}

// NewFactory 生成一个 auth_apiKey工厂
func NewFactory() auth.IAuthFactory {
typ := reflect.TypeOf((*Config)(nil))
render, _ := schema.Generate(typ, nil)

return &factory{configType: typ, render: render, userType: reflect.TypeOf((*User)(nil))}
}

func toId(tokenName, position string) string {
return fmt.Sprintf("%s@%s@%s", tokenName, position, driverName)
}
35 changes: 35 additions & 0 deletions application/auth/para-hmac/sign.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package para_hmac

import (
"crypto/sha256"
"encoding/base64"
"fmt"
"strings"
)

var signSort = []string{
"Body",
"X-App-Id",
"X-Sequence-No",
"X-Timestamp",
}

func sign(appId string, appKey string, timestamp string, sequenceNo string, body string) string {
headerMap := make(map[string]string)
headerMap["X-App-Id"] = appId
headerMap["X-Sequence-No"] = sequenceNo
headerMap["X-Timestamp"] = timestamp
headerMap["Body"] = base64.StdEncoding.EncodeToString([]byte(body))
builder := strings.Builder{}
for _, key := range signSort {
v, ok := headerMap[key]
if !ok || v == "" {
continue
}
builder.WriteString(fmt.Sprintf("%s=%s&", key, v))
}
builder.WriteString(appKey)
h := sha256.New()
h.Write([]byte(builder.String()))
return base64.StdEncoding.EncodeToString(h.Sum(nil))
}
3 changes: 3 additions & 0 deletions drivers/app/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package app
import (
"sync"

para_hmac "github.com/eolinker/apinto/application/auth/para-hmac"

openid_connect_jwt "github.com/eolinker/apinto/application/auth/openid-connect-jwt"

"github.com/eolinker/apinto/application/auth"
Expand Down Expand Up @@ -39,6 +41,7 @@ func NewFactory() eosc.IExtenderDriverFactory {
jwt.Register()
oauth2.Register()
openid_connect_jwt.Register()
para_hmac.Register()
appManager = manager.NewManager(auth.Alias(), auth.Keys())
bean.Injection(&appManager)
})
Expand Down

0 comments on commit add599e

Please sign in to comment.