move auth module into a new project (#522)
* move auth module into a new project * upgrade go 1.22.2. to 1.22.4 --------- Co-authored-by: rick <LinuxSuRen@users.noreply.github.com>
This commit is contained in:
parent
ad1521bbd1
commit
f63520e765
|
@ -5,7 +5,7 @@ COPY console/atest-ui .
|
||||||
RUN npm install --ignore-scripts --registry=https://registry.npmmirror.com
|
RUN npm install --ignore-scripts --registry=https://registry.npmmirror.com
|
||||||
RUN npm run build-only
|
RUN npm run build-only
|
||||||
|
|
||||||
FROM docker.io/golang:1.22.2 AS builder
|
FROM docker.io/golang:1.22.4 AS builder
|
||||||
|
|
||||||
ARG VERSION
|
ARG VERSION
|
||||||
ARG GOPROXY
|
ARG GOPROXY
|
||||||
|
|
|
@ -42,7 +42,6 @@ import (
|
||||||
"github.com/linuxsuren/api-testing/pkg/downloader"
|
"github.com/linuxsuren/api-testing/pkg/downloader"
|
||||||
"github.com/linuxsuren/api-testing/pkg/logging"
|
"github.com/linuxsuren/api-testing/pkg/logging"
|
||||||
"github.com/linuxsuren/api-testing/pkg/mock"
|
"github.com/linuxsuren/api-testing/pkg/mock"
|
||||||
"github.com/linuxsuren/api-testing/pkg/oauth"
|
|
||||||
template "github.com/linuxsuren/api-testing/pkg/render"
|
template "github.com/linuxsuren/api-testing/pkg/render"
|
||||||
"github.com/linuxsuren/api-testing/pkg/server"
|
"github.com/linuxsuren/api-testing/pkg/server"
|
||||||
"github.com/linuxsuren/api-testing/pkg/service"
|
"github.com/linuxsuren/api-testing/pkg/service"
|
||||||
|
@ -51,6 +50,8 @@ import (
|
||||||
"github.com/linuxsuren/api-testing/pkg/testing/remote"
|
"github.com/linuxsuren/api-testing/pkg/testing/remote"
|
||||||
"github.com/linuxsuren/api-testing/pkg/util"
|
"github.com/linuxsuren/api-testing/pkg/util"
|
||||||
fakeruntime "github.com/linuxsuren/go-fake-runtime"
|
fakeruntime "github.com/linuxsuren/go-fake-runtime"
|
||||||
|
atestoauth "github.com/linuxsuren/api-testing/pkg/oauth"
|
||||||
|
"github.com/linuxsuren/oauth-hub"
|
||||||
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
"github.com/prometheus/client_golang/prometheus"
|
||||||
"github.com/prometheus/client_golang/prometheus/collectors"
|
"github.com/prometheus/client_golang/prometheus/collectors"
|
||||||
|
@ -182,7 +183,7 @@ func (o *serverOption) preRunE(cmd *cobra.Command, args []string) (err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
grpcOpts = append(grpcOpts, oauth.NewAuthInterceptor(o.oauthGroup))
|
grpcOpts = append(grpcOpts, atestoauth.NewAuthInterceptor(o.oauthGroup))
|
||||||
}
|
}
|
||||||
if o.tls {
|
if o.tls {
|
||||||
if o.tlsCert != "" && o.tlsKey != "" {
|
if o.tlsCert != "" && o.tlsKey != "" {
|
||||||
|
|
5
go.mod
5
go.mod
|
@ -1,6 +1,6 @@
|
||||||
module github.com/linuxsuren/api-testing
|
module github.com/linuxsuren/api-testing
|
||||||
|
|
||||||
go 1.22.2
|
go 1.22.4
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/Masterminds/sprig/v3 v3.2.3
|
github.com/Masterminds/sprig/v3 v3.2.3
|
||||||
|
@ -33,7 +33,7 @@ require (
|
||||||
github.com/tidwall/gjson v1.14.4
|
github.com/tidwall/gjson v1.14.4
|
||||||
github.com/xeipuuv/gojsonschema v1.2.0
|
github.com/xeipuuv/gojsonschema v1.2.0
|
||||||
go.uber.org/zap v1.27.0
|
go.uber.org/zap v1.27.0
|
||||||
golang.org/x/oauth2 v0.18.0
|
golang.org/x/oauth2 v0.22.0
|
||||||
golang.org/x/sync v0.6.0
|
golang.org/x/sync v0.6.0
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80
|
google.golang.org/genproto/googleapis/api v0.0.0-20240123012728-ef4313101c80
|
||||||
google.golang.org/grpc v1.62.1
|
google.golang.org/grpc v1.62.1
|
||||||
|
@ -64,6 +64,7 @@ require (
|
||||||
github.com/imdario/mergo v0.3.16 // indirect
|
github.com/imdario/mergo v0.3.16 // indirect
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
github.com/josharian/intern v1.0.0 // indirect
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
|
github.com/linuxsuren/oauth-hub v0.0.0-20240809060240-e78c21b5d8d4 // indirect
|
||||||
github.com/mailru/easyjson v0.7.7 // indirect
|
github.com/mailru/easyjson v0.7.7 // indirect
|
||||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||||
|
|
6
go.sum
6
go.sum
|
@ -119,6 +119,10 @@ github.com/linuxsuren/go-fake-runtime v0.0.4 h1:y+tvBuw6MKTCav8Bo5HWwaXhBx1Z//VA
|
||||||
github.com/linuxsuren/go-fake-runtime v0.0.4/go.mod h1:zmh6J78hSnWZo68faMA2eKOdaEp8eFbERHi3ZB9xHCQ=
|
github.com/linuxsuren/go-fake-runtime v0.0.4/go.mod h1:zmh6J78hSnWZo68faMA2eKOdaEp8eFbERHi3ZB9xHCQ=
|
||||||
github.com/linuxsuren/go-service v0.0.0-20231225060426-efabcd3a5161 h1:dSL/ah6zaRGqH3FW0ogtMjP6xCFXX5NsgWJTaNIofI4=
|
github.com/linuxsuren/go-service v0.0.0-20231225060426-efabcd3a5161 h1:dSL/ah6zaRGqH3FW0ogtMjP6xCFXX5NsgWJTaNIofI4=
|
||||||
github.com/linuxsuren/go-service v0.0.0-20231225060426-efabcd3a5161/go.mod h1:QX22v61PxpOfJa4Xug8qzGTbPjclDZFx2j1PlGLknJw=
|
github.com/linuxsuren/go-service v0.0.0-20231225060426-efabcd3a5161/go.mod h1:QX22v61PxpOfJa4Xug8qzGTbPjclDZFx2j1PlGLknJw=
|
||||||
|
github.com/linuxsuren/oauth-hub v0.0.0-20240809035103-220d1f431cc3 h1:Nmh7TETH85skH7Wfw6M5J8DhdAyAGodGOwshNfzpM88=
|
||||||
|
github.com/linuxsuren/oauth-hub v0.0.0-20240809035103-220d1f431cc3/go.mod h1:NrsEbf2IUUmNUoNbTkeWMcswb+4nEMniZ/8xTUhk2zw=
|
||||||
|
github.com/linuxsuren/oauth-hub v0.0.0-20240809060240-e78c21b5d8d4 h1:muVmKxx+JneaVgUKHqLc+As5vpgKXZAfVu6h+iyb5LQ=
|
||||||
|
github.com/linuxsuren/oauth-hub v0.0.0-20240809060240-e78c21b5d8d4/go.mod h1:6K1L5ajpFTNO8iJSsNrxMWAigAqczI0UPfEV9NSE0nc=
|
||||||
github.com/linuxsuren/unstructured v0.0.1 h1:ilUA8MUYbR6l9ebo/YPV2bKqlf62bzQursDSE+j00iU=
|
github.com/linuxsuren/unstructured v0.0.1 h1:ilUA8MUYbR6l9ebo/YPV2bKqlf62bzQursDSE+j00iU=
|
||||||
github.com/linuxsuren/unstructured v0.0.1/go.mod h1:KH6aTj+FegzGBzc1vS6mzZx3/duhTUTEVyW5sO7p4as=
|
github.com/linuxsuren/unstructured v0.0.1/go.mod h1:KH6aTj+FegzGBzc1vS6mzZx3/duhTUTEVyW5sO7p4as=
|
||||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||||
|
@ -234,6 +238,8 @@ golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs=
|
||||||
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||||
golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI=
|
golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI=
|
||||||
golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8=
|
golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8=
|
||||||
|
golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA=
|
||||||
|
golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
||||||
|
|
|
@ -144,6 +144,7 @@ cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzc
|
||||||
cloud.google.com/go/compute v1.24.0/go.mod h1:kw1/T+h/+tK2LJK0wiPPx1intgdAM3j/g3hFDlscY40=
|
cloud.google.com/go/compute v1.24.0/go.mod h1:kw1/T+h/+tK2LJK0wiPPx1intgdAM3j/g3hFDlscY40=
|
||||||
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
|
||||||
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
|
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
|
||||||
|
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
|
||||||
cloud.google.com/go/contactcenterinsights v1.10.0 h1:YR2aPedGVQPpFBZXJnPkqRj8M//8veIZZH5ZvICoXnI=
|
cloud.google.com/go/contactcenterinsights v1.10.0 h1:YR2aPedGVQPpFBZXJnPkqRj8M//8veIZZH5ZvICoXnI=
|
||||||
cloud.google.com/go/contactcenterinsights v1.10.0/go.mod h1:bsg/R7zGLYMVxFFzfh9ooLTruLRCG9fnzhH9KznHhbM=
|
cloud.google.com/go/contactcenterinsights v1.10.0/go.mod h1:bsg/R7zGLYMVxFFzfh9ooLTruLRCG9fnzhH9KznHhbM=
|
||||||
cloud.google.com/go/contactcenterinsights v1.12.1 h1:EiGBeejtDDtr3JXt9W7xlhXyZ+REB5k2tBgVPVtmNb0=
|
cloud.google.com/go/contactcenterinsights v1.12.1 h1:EiGBeejtDDtr3JXt9W7xlhXyZ+REB5k2tBgVPVtmNb0=
|
||||||
|
@ -753,8 +754,6 @@ github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edY
|
||||||
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
|
||||||
github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||||
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
|
||||||
github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
|
|
||||||
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
|
|
||||||
github.com/bool64/httpmock v0.1.13 h1:3QpRXQ5kwHLW8xnVT8+Ug7VS6RerhdEFV+RWYC61aVo=
|
github.com/bool64/httpmock v0.1.13 h1:3QpRXQ5kwHLW8xnVT8+Ug7VS6RerhdEFV+RWYC61aVo=
|
||||||
github.com/bool64/httpmock v0.1.13/go.mod h1:YMTLaypQ3o5DAx78eA/kDRSLec0f+42sLMDmHdmeY+E=
|
github.com/bool64/httpmock v0.1.13/go.mod h1:YMTLaypQ3o5DAx78eA/kDRSLec0f+42sLMDmHdmeY+E=
|
||||||
github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs=
|
github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs=
|
||||||
|
|
|
@ -1,50 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2023 API Testing Authors.
|
|
||||||
|
|
||||||
Licensed 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 oauth
|
|
||||||
|
|
||||||
type dexOAuthProvider struct {
|
|
||||||
server string
|
|
||||||
}
|
|
||||||
|
|
||||||
// AllScopes returns all the supported scopes
|
|
||||||
func (p *dexOAuthProvider) AllScopes() []string {
|
|
||||||
return []string{"openid", "email", "groups", "profile", "offline_access"}
|
|
||||||
}
|
|
||||||
func (p *dexOAuthProvider) MinimalScopes() []string {
|
|
||||||
return p.AllScopes()
|
|
||||||
}
|
|
||||||
func (p *dexOAuthProvider) GetName() string {
|
|
||||||
return "dex"
|
|
||||||
}
|
|
||||||
func (p *dexOAuthProvider) GetServer() string {
|
|
||||||
return p.server
|
|
||||||
}
|
|
||||||
func (p *dexOAuthProvider) SetServer(server string) {
|
|
||||||
p.server = server
|
|
||||||
}
|
|
||||||
func (p *dexOAuthProvider) GetTokenURL() string {
|
|
||||||
return "/api/dex/token"
|
|
||||||
}
|
|
||||||
func (p *dexOAuthProvider) GetAuthURL() string {
|
|
||||||
return "/api/dex/auth"
|
|
||||||
}
|
|
||||||
func (p *dexOAuthProvider) GetUserInfoURL() string {
|
|
||||||
return "/api/dex/userinfo"
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
RegisterOAuthProvider(&dexOAuthProvider{})
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2023 API Testing Authors.
|
|
||||||
|
|
||||||
Licensed 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 oauth
|
|
||||||
|
|
||||||
import "github.com/linuxsuren/api-testing/pkg/logging"
|
|
||||||
|
|
||||||
var (
|
|
||||||
githubLogger = logging.DefaultLogger(logging.LogLevelInfo).WithName("github")
|
|
||||||
)
|
|
||||||
|
|
||||||
type githubOAuthProvider struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
// AllScopes returns all the supported scopes
|
|
||||||
// See also https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps
|
|
||||||
func (p *githubOAuthProvider) AllScopes() []string {
|
|
||||||
return []string{"repo", "public_repo", "read:org", "user", "read:user", "user:email"}
|
|
||||||
}
|
|
||||||
func (p *githubOAuthProvider) MinimalScopes() []string {
|
|
||||||
return []string{"read:user", "public_repo"}
|
|
||||||
}
|
|
||||||
func (p *githubOAuthProvider) GetName() string {
|
|
||||||
return "github"
|
|
||||||
}
|
|
||||||
func (p *githubOAuthProvider) GetServer() string {
|
|
||||||
return "https://github.com/login"
|
|
||||||
}
|
|
||||||
func (p *githubOAuthProvider) SetServer(_ string) {
|
|
||||||
githubLogger.Info("not support")
|
|
||||||
}
|
|
||||||
func (p *githubOAuthProvider) GetTokenURL() string {
|
|
||||||
return "/oauth/access_token"
|
|
||||||
}
|
|
||||||
func (p *githubOAuthProvider) GetAuthURL() string {
|
|
||||||
return "/oauth/authorize"
|
|
||||||
}
|
|
||||||
func (p *githubOAuthProvider) GetUserInfoURL() string {
|
|
||||||
return "https://api.github.com/user"
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
RegisterOAuthProvider(&githubOAuthProvider{})
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2023 API Testing Authors.
|
|
||||||
|
|
||||||
Licensed 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 oauth
|
|
||||||
|
|
||||||
type gitlabOAuthProvider struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
// AllScopes returns all the supported scopes
|
|
||||||
// See also https://docs.gitlab.com/ee/integration/oauth_provider.html
|
|
||||||
func (p *gitlabOAuthProvider) AllScopes() []string {
|
|
||||||
return []string{"api", "read_user", "read_api", "read_repository", "profile", "email"}
|
|
||||||
}
|
|
||||||
func (p *gitlabOAuthProvider) MinimalScopes() []string {
|
|
||||||
return []string{"read_user", "read_api", "read_repository", "profile"}
|
|
||||||
}
|
|
||||||
func (p *gitlabOAuthProvider) GetName() string {
|
|
||||||
return "gitlab"
|
|
||||||
}
|
|
||||||
func (p *gitlabOAuthProvider) GetServer() string {
|
|
||||||
return "https://gitlab.com"
|
|
||||||
}
|
|
||||||
func (p *gitlabOAuthProvider) SetServer(_ string) {
|
|
||||||
githubLogger.Info("not support")
|
|
||||||
}
|
|
||||||
func (p *gitlabOAuthProvider) GetTokenURL() string {
|
|
||||||
return "/oauth/token"
|
|
||||||
}
|
|
||||||
func (p *gitlabOAuthProvider) GetAuthURL() string {
|
|
||||||
return "/oauth/authorize"
|
|
||||||
}
|
|
||||||
func (p *gitlabOAuthProvider) GetUserInfoURL() string {
|
|
||||||
return "/oauth/userinfo"
|
|
||||||
}
|
|
||||||
|
|
||||||
type privateGitlabOAuthProvider struct {
|
|
||||||
*gitlabOAuthProvider
|
|
||||||
server string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *privateGitlabOAuthProvider) GetName() string {
|
|
||||||
return "private-gitlab"
|
|
||||||
}
|
|
||||||
func (p *privateGitlabOAuthProvider) GetServer() string {
|
|
||||||
return p.server
|
|
||||||
}
|
|
||||||
func (p *privateGitlabOAuthProvider) SetServer(server string) {
|
|
||||||
p.server = server
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
RegisterOAuthProvider(&gitlabOAuthProvider{})
|
|
||||||
RegisterOAuthProvider(&privateGitlabOAuthProvider{})
|
|
||||||
}
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
|
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
|
"github.com/linuxsuren/oauth-hub"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/metadata"
|
"google.golang.org/grpc/metadata"
|
||||||
|
@ -77,11 +78,11 @@ func (a *authInter) authInterceptor(ctx context.Context, req interface{}, info *
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetUserFromContext(ctx context.Context) (user *UserInfo) {
|
func GetUserFromContext(ctx context.Context) (user *oauth.UserInfo) {
|
||||||
if md, ok := metadata.FromIncomingContext(ctx); ok {
|
if md, ok := metadata.FromIncomingContext(ctx); ok {
|
||||||
data := md.Get("auth")
|
data := md.Get("auth")
|
||||||
if len(data) > 0 {
|
if len(data) > 0 {
|
||||||
user = GetUser(data[0])
|
user = oauth.GetUser(data[0])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|
|
@ -19,6 +19,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/linuxsuren/oauth-hub"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
"google.golang.org/grpc/metadata"
|
"google.golang.org/grpc/metadata"
|
||||||
|
@ -47,7 +48,7 @@ func TestAuthInterceptor(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("normal", func(t *testing.T) {
|
t.Run("normal", func(t *testing.T) {
|
||||||
accessToken["fake"] = &UserInfo{}
|
oauth.SetUser("fake", &oauth.UserInfo{})
|
||||||
ctx := metadata.NewIncomingContext(context.TODO(), metadata.Pairs("auth", "fake"))
|
ctx := metadata.NewIncomingContext(context.TODO(), metadata.Pairs("auth", "fake"))
|
||||||
|
|
||||||
inter := &authInter{}
|
inter := &authInter{}
|
||||||
|
|
|
@ -1,141 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2023 API Testing Authors.
|
|
||||||
|
|
||||||
Licensed 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 oauth
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/linuxsuren/api-testing/pkg/logging"
|
|
||||||
"github.com/linuxsuren/api-testing/pkg/util"
|
|
||||||
|
|
||||||
"golang.org/x/oauth2"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
accessToken = make(map[string]*UserInfo)
|
|
||||||
oauthLogger = logging.DefaultLogger(logging.LogLevelInfo).WithName("oauth")
|
|
||||||
)
|
|
||||||
|
|
||||||
func GetUser(token string) *UserInfo {
|
|
||||||
return accessToken[token]
|
|
||||||
}
|
|
||||||
|
|
||||||
type auth struct {
|
|
||||||
provider OAuthProvider
|
|
||||||
config oauth2.Config
|
|
||||||
verifier string
|
|
||||||
skipTlsVerify bool
|
|
||||||
state string
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewAuth creates a new auth handler
|
|
||||||
func NewAuth(provider OAuthProvider, config oauth2.Config, skipTlsVerify bool) *auth {
|
|
||||||
config.Scopes = provider.MinimalScopes()
|
|
||||||
config.Endpoint.TokenURL = fmt.Sprintf("%s%s", provider.GetServer(), provider.GetTokenURL())
|
|
||||||
config.Endpoint.AuthURL = fmt.Sprintf("%s%s", provider.GetServer(), provider.GetAuthURL())
|
|
||||||
config.Endpoint.DeviceAuthURL = "https://github.com/login/device/code"
|
|
||||||
return &auth{
|
|
||||||
provider: provider,
|
|
||||||
config: config,
|
|
||||||
verifier: oauth2.GenerateVerifier(),
|
|
||||||
skipTlsVerify: skipTlsVerify,
|
|
||||||
state: util.String(6),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *auth) Callback(w http.ResponseWriter, r *http.Request, pathParams map[string]string) {
|
|
||||||
r.ParseForm()
|
|
||||||
state := r.Form.Get("state")
|
|
||||||
if state != a.state {
|
|
||||||
http.Error(w, "State invalid", http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
code := r.Form.Get("code")
|
|
||||||
if code == "" {
|
|
||||||
http.Error(w, "Code not found", http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
oauthLogger.Info("get code", "code", code)
|
|
||||||
|
|
||||||
sslcli := util.TlsAwareHTTPClient(a.skipTlsVerify)
|
|
||||||
ctx := context.WithValue(r.Context(), oauth2.HTTPClient, sslcli)
|
|
||||||
|
|
||||||
token, err := a.config.Exchange(ctx, code, oauth2.VerifierOption(a.verifier))
|
|
||||||
a.getUserInfo(w, r, token, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *auth) getUserInfo(w http.ResponseWriter, r *http.Request, token *oauth2.Token, err error) {
|
|
||||||
if err != nil {
|
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
accessToken[token.AccessToken] = nil
|
|
||||||
// get userInfo, save it to session
|
|
||||||
if userInfo, err := GetUserInfo(a.provider, token.AccessToken, a.skipTlsVerify); err == nil {
|
|
||||||
accessToken[token.AccessToken] = userInfo
|
|
||||||
oauthLogger.Info("has login", "username", userInfo.Name)
|
|
||||||
} else {
|
|
||||||
oauthLogger.Info("failed to get userinfo", "error", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
http.Redirect(w, r, "/?access_token="+token.AccessToken, http.StatusFound)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *auth) RequestLocalToken(w http.ResponseWriter, r *http.Request, pathParams map[string]string) {
|
|
||||||
deviceCode := r.FormValue("device_code")
|
|
||||||
response, ok := deviceAuthResponseMap[deviceCode]
|
|
||||||
if !ok {
|
|
||||||
http.Error(w, "device code not found", http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
token, err := a.config.DeviceAccessToken(r.Context(), response)
|
|
||||||
a.getUserInfo(w, r, token, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var deviceAuthResponseMap = map[string]*oauth2.DeviceAuthResponse{}
|
|
||||||
|
|
||||||
func (a *auth) RequestLocalCode(w http.ResponseWriter, r *http.Request, pathParams map[string]string) {
|
|
||||||
response, err := a.config.DeviceAuth(context.Background())
|
|
||||||
if err != nil {
|
|
||||||
oauthLogger.Info("failed to get device auth", "error", err)
|
|
||||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
deviceAuthResponseMap[response.DeviceCode] = response
|
|
||||||
|
|
||||||
data, _ := json.Marshal(response)
|
|
||||||
w.Write(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *auth) RequestCode(w http.ResponseWriter, r *http.Request, pathParams map[string]string) {
|
|
||||||
ref := r.Header.Get("Referer")
|
|
||||||
oauthLogger.Info("callback host", "host", r.Host)
|
|
||||||
|
|
||||||
if ref == "" {
|
|
||||||
a.config.RedirectURL = fmt.Sprintf("https://%s/oauth2/callback", r.Host)
|
|
||||||
} else {
|
|
||||||
a.config.RedirectURL = fmt.Sprintf("%soauth2/callback", ref)
|
|
||||||
}
|
|
||||||
|
|
||||||
u := a.config.AuthCodeURL(a.state, oauth2.S256ChallengeOption(a.verifier))
|
|
||||||
http.Redirect(w, r, u, http.StatusFound)
|
|
||||||
}
|
|
|
@ -1,99 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2023 API Testing Authors.
|
|
||||||
|
|
||||||
Licensed 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 oauth
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/linuxsuren/api-testing/pkg/logging"
|
|
||||||
|
|
||||||
"github.com/linuxsuren/api-testing/pkg/util"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
userLogger = logging.DefaultLogger(logging.LogLevelInfo).WithName("user")
|
|
||||||
)
|
|
||||||
|
|
||||||
type OAuthProvider interface {
|
|
||||||
AllScopes() []string
|
|
||||||
MinimalScopes() []string
|
|
||||||
GetName() string
|
|
||||||
GetServer() string
|
|
||||||
SetServer(string)
|
|
||||||
GetTokenURL() string
|
|
||||||
GetAuthURL() string
|
|
||||||
GetUserInfoURL() string
|
|
||||||
}
|
|
||||||
|
|
||||||
var allOAuthProviders = make(map[string]OAuthProvider)
|
|
||||||
|
|
||||||
func RegisterOAuthProvider(provier OAuthProvider) {
|
|
||||||
name := provier.GetName()
|
|
||||||
_, ok := allOAuthProviders[name]
|
|
||||||
if !ok {
|
|
||||||
allOAuthProviders[name] = provier
|
|
||||||
} else {
|
|
||||||
panic(fmt.Sprintf("duplicated oauth provider: %q", name))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetOAuthProvider(name string) OAuthProvider {
|
|
||||||
return allOAuthProviders[name]
|
|
||||||
}
|
|
||||||
|
|
||||||
type UserInfo struct {
|
|
||||||
Sub string `json:"sub"`
|
|
||||||
Name string `json:"name"`
|
|
||||||
PreferredUsername string `json:"preferred_username"`
|
|
||||||
Email string `json:"email"`
|
|
||||||
Picture string `json:"picture"`
|
|
||||||
Groups []string `json:"groups"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetUserInfo(server OAuthProvider, token string, skipTlsVerify bool) (userInfo *UserInfo, err error) {
|
|
||||||
api := server.GetUserInfoURL()
|
|
||||||
if !strings.HasPrefix(api, "http://") && !strings.HasPrefix(api, "https://") {
|
|
||||||
api = fmt.Sprintf("%s%s", server.GetServer(), server.GetUserInfoURL())
|
|
||||||
}
|
|
||||||
req, err := http.NewRequest(http.MethodGet, api, nil)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
req.Header.Set("Authorization", "Bearer "+token)
|
|
||||||
|
|
||||||
client := util.TlsAwareHTTPClient(skipTlsVerify)
|
|
||||||
var resp *http.Response
|
|
||||||
if resp, err = client.Do(req); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
userLogger.Info("getting userinfo from", "name", server.GetName())
|
|
||||||
if resp.StatusCode == http.StatusOK {
|
|
||||||
var data []byte
|
|
||||||
if data, err = io.ReadAll(resp.Body); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
userInfo = &UserInfo{}
|
|
||||||
err = json.Unmarshal(data, userInfo)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
|
@ -1,6 +1,6 @@
|
||||||
module local
|
module local
|
||||||
|
|
||||||
go 1.22.2
|
go 1.22.4
|
||||||
|
|
||||||
require github.com/golangci/golangci-lint v1.57.2
|
require github.com/golangci/golangci-lint v1.57.2
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue