Skip to content

Commit

Permalink
add token support
Browse files Browse the repository at this point in the history
  • Loading branch information
xujianhai666 committed Sep 13, 2019
1 parent cf198d0 commit 7a0101d
Show file tree
Hide file tree
Showing 9 changed files with 192 additions and 2 deletions.
2 changes: 1 addition & 1 deletion common/constant/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const (
const (
DEFAULT_KEY = "default"
PREFIX_DEFAULT_KEY = "default."
DEFAULT_SERVICE_FILTERS = "echo"
DEFAULT_SERVICE_FILTERS = "echo,token"
DEFAULT_REFERENCE_FILTERS = ""
GENERIC_REFERENCE_FILTERS = "generic"
GENERIC = "$invoke"
Expand Down
1 change: 1 addition & 0 deletions common/constant/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const (
TIMEOUT_KEY = "timeout"
BEAN_NAME_KEY = "bean.name"
GENERIC_KEY = "generic"
TOKEN_KEY = "token"
)

const (
Expand Down
13 changes: 13 additions & 0 deletions common/url.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (

import (
perrors "github.com/pkg/errors"
"github.com/satori/go.uuid"
)

import (
Expand Down Expand Up @@ -148,6 +149,18 @@ func WithLocation(location string) option {
}
}

func WithToken(token string) option {
return func(url *URL) {
if len(token) > 0 {
value := token
if strings.ToLower(token) == "true" || strings.ToLower(token) == "default" {
value = uuid.NewV4().String()
}
url.baseUrl.Params.Set(constant.TOKEN_KEY, value)
}
}
}

func NewURLWithOptions(opts ...option) *URL {
url := &URL{}
for _, opt := range opts {
Expand Down
5 changes: 4 additions & 1 deletion config/service_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ type ServiceConfig struct {
Warmup string `yaml:"warmup" json:"warmup,omitempty" property:"warmup"`
Retries string `yaml:"retries" json:"retries,omitempty" property:"retries"`
Params map[string]string `yaml:"params" json:"params,omitempty" property:"params"`
Token string `yaml:"token" json:"token,omitempty" property:"token"`
unexported *atomic.Bool
exported *atomic.Bool
rpcService common.RPCService
Expand Down Expand Up @@ -111,7 +112,9 @@ func (srvconfig *ServiceConfig) Export() error {
common.WithPort(proto.Port),
common.WithParams(urlMap),
common.WithParamsValue(constant.BEAN_NAME_KEY, srvconfig.id),
common.WithMethods(strings.Split(methods, ",")))
common.WithMethods(strings.Split(methods, ",")),
common.WithToken(srvconfig.Token),
)

if len(regUrls) > 0 {
for _, regUrl := range regUrls {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ services:
- name: "GetUser"
retries: "1"
loadbalance: "random"
token: "true"

protocols:
"dubbo":
Expand Down
68 changes: 68 additions & 0 deletions filter/impl/token_filter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package impl

import (
"strings"
)

import (
perrors "github.com/pkg/errors"
)

import (
"github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/common/extension"
"github.com/apache/dubbo-go/filter"
"github.com/apache/dubbo-go/protocol"
)

const (
token = "token"
)

func init() {
extension.SetFilter(token, GetTokenFilter)
}

type TokenFilter struct{}

func (tf *TokenFilter) Invoke(invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
invokerTkn := invoker.GetUrl().GetParam(constant.TOKEN_KEY, "")
if len(invokerTkn) > 0 {
attachs := invocation.Attachments()
if len(attachs) > 0 {
remoteTkn, exist := attachs[constant.TOKEN_KEY]
if exist && strings.EqualFold(invokerTkn, remoteTkn) {
return invoker.Invoke(invocation)
}
}
return &protocol.RPCResult{Err: perrors.Errorf("Invalid token! Forbid invoke remote service %s method %s ",
invoker, invocation.MethodName())}
}

return invoker.Invoke(invocation)
}

func (tf *TokenFilter) OnResponse(result protocol.Result, invoker protocol.Invoker, invocation protocol.Invocation) protocol.Result {
return result
}

func GetTokenFilter() filter.Filter {
return &TokenFilter{}
}
85 changes: 85 additions & 0 deletions filter/impl/token_filter_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package impl

import (
"net/url"
"testing"
)

import (
"github.com/stretchr/testify/assert"
)

import (
"github.com/apache/dubbo-go/common"
"github.com/apache/dubbo-go/common/constant"
"github.com/apache/dubbo-go/protocol"
"github.com/apache/dubbo-go/protocol/invocation"
)

func TestTokenFilter_Invoke(t *testing.T) {
filter := GetTokenFilter()

url := common.NewURLWithOptions(
common.WithParams(url.Values{}),
common.WithParamsValue(constant.TOKEN_KEY, "ori_key"))
attch := make(map[string]string, 0)
attch[constant.TOKEN_KEY] = "ori_key"
result := filter.Invoke(protocol.NewBaseInvoker(*url),
invocation.NewRPCInvocation("MethodName", []interface{}{"OK"}, attch))
assert.Nil(t, result.Error())
assert.Nil(t, result.Result())
}

func TestTokenFilter_InvokeEmptyToken(t *testing.T) {
filter := GetTokenFilter()

url := common.URL{}
attch := make(map[string]string, 0)
attch[constant.TOKEN_KEY] = "ori_key"
result := filter.Invoke(protocol.NewBaseInvoker(url),
invocation.NewRPCInvocation("MethodName", []interface{}{"OK"}, attch))
assert.Nil(t, result.Error())
assert.Nil(t, result.Result())
}

func TestTokenFilter_InvokeEmptyAttach(t *testing.T) {
filter := GetTokenFilter()

url := common.NewURLWithOptions(
common.WithParams(url.Values{}),
common.WithParamsValue(constant.TOKEN_KEY, "ori_key"))
attch := make(map[string]string, 0)
result := filter.Invoke(protocol.NewBaseInvoker(*url),
invocation.NewRPCInvocation("MethodName", []interface{}{"OK"}, attch))
assert.NotNil(t, result.Error())
}

func TestTokenFilter_InvokeNotEqual(t *testing.T) {
filter := GetTokenFilter()

url := common.NewURLWithOptions(
common.WithParams(url.Values{}),
common.WithParamsValue(constant.TOKEN_KEY, "ori_key"))
attch := make(map[string]string, 0)
attch[constant.TOKEN_KEY] = "err_key"
result := filter.Invoke(protocol.NewBaseInvoker(*url),
invocation.NewRPCInvocation("MethodName", []interface{}{"OK"}, attch))
assert.NotNil(t, result.Error())
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ require (
github.com/pkg/errors v0.8.1
github.com/prometheus/client_golang v1.1.0 // indirect
github.com/samuel/go-zookeeper v0.0.0-20180130194729-c4fab1ac1bec
github.com/satori/go.uuid v1.2.0
github.com/smartystreets/goconvey v0.0.0-20190710185942-9d28bd7c0945 // indirect
github.com/soheilhy/cmux v0.1.4 // indirect
github.com/stretchr/testify v1.3.0
Expand Down
18 changes: 18 additions & 0 deletions protocol/dubbo/dubbo_invoker.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,29 @@ import (

var Err_No_Reply = perrors.New("request need @response")

var (
attachmentKey = []string{constant.INTERFACE_KEY, constant.GROUP_KEY, constant.TOKEN_KEY, constant.TIMEOUT_KEY}
)

type DubboInvoker struct {
protocol.BaseInvoker
client *Client
attachment map[string]string
destroyLock sync.Mutex
}

func NewDubboInvoker(url common.URL, client *Client) *DubboInvoker {
attachment := make(map[string]string, 0)
for _, k := range attachmentKey {
if v := url.GetParam(k, ""); len(v) > 0 {
attachment[k] = v
}
}

return &DubboInvoker{
BaseInvoker: *protocol.NewBaseInvoker(url),
client: client,
attachment: attachment,
}
}

Expand All @@ -57,6 +70,11 @@ func (di *DubboInvoker) Invoke(invocation protocol.Invocation) protocol.Result {
)

inv := invocation.(*invocation_impl.RPCInvocation)
if len(di.attachment) > 0 {
for k, v := range di.attachment {
inv.SetAttachments(k, v)
}
}
url := di.GetUrl()
// async
async, err := strconv.ParseBool(inv.AttachmentsByKey(constant.ASYNC_KEY, "false"))
Expand Down

0 comments on commit 7a0101d

Please sign in to comment.