Skip to content

Commit 7f6abe0

Browse files
adds method type, ApiSession interface JSON wrapper
- adds string alias type AuthMethod - adds AuthMethodEmpty as a sentinal type - adds ApiSessionJsonWrapper to allow direct (un)marshalling of ApiSession via interface
1 parent 655261c commit 7f6abe0

File tree

7 files changed

+107
-15
lines changed

7 files changed

+107
-15
lines changed

edge-apis/api_session.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,31 @@ import (
1616
"golang.org/x/oauth2"
1717
)
1818

19+
var _ json.Marshaler = (*ApiSessionJsonWrapper)(nil)
20+
var _ json.Unmarshaler = (*ApiSessionJsonWrapper)(nil)
21+
22+
// ApiSessionJsonWrapper provides JSON marshaling and unmarshaling capabilities for ApiSession
23+
// interface types. It allows polymorphic ApiSession implementations (ApiSessionLegacy and
24+
// ApiSessionOidc) to be correctly serialized and deserialized by delegating to the underlying
25+
// ApiSession's JSON methods.
26+
//
27+
// This wrapper enables ApiSession instances to be embedded in structs and marshaled to/from
28+
// JSON.
29+
type ApiSessionJsonWrapper struct {
30+
ApiSession ApiSession
31+
}
32+
33+
func (a *ApiSessionJsonWrapper) UnmarshalJSON(bytes []byte) error {
34+
var err error
35+
a.ApiSession, err = UnmarshalApiSession(bytes)
36+
37+
return err
38+
}
39+
40+
func (a *ApiSessionJsonWrapper) MarshalJSON() ([]byte, error) {
41+
return a.ApiSession.MarshalJSON()
42+
}
43+
1944
type ApiSession interface {
2045
//GetAccessHeader returns the HTTP header name and value that should be used to represent this ApiSession
2146
GetAccessHeader() (string, string)

edge-apis/api_session_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package edge_apis
2+
3+
import (
4+
"encoding/json"
5+
"testing"
6+
7+
"github.com/stretchr/testify/require"
8+
)
9+
10+
func Test_ApiSessionMarshalling(t *testing.T) {
11+
12+
t.Run("test marshalling", func(t *testing.T) {
13+
req := require.New(t)
14+
type testStruct struct {
15+
ApiSession ApiSessionJsonWrapper `json:"apiSession"`
16+
}
17+
18+
test := &testStruct{
19+
ApiSession: ApiSessionJsonWrapper{
20+
ApiSession: NewApiSessionOidc("access", "refresh"),
21+
},
22+
}
23+
24+
testJson, err := json.Marshal(test)
25+
req.NoError(err)
26+
27+
testUnmarhsal := &testStruct{}
28+
29+
err = json.Unmarshal(testJson, testUnmarhsal)
30+
req.NoError(err)
31+
req.Equal(test.ApiSession.ApiSession.GetToken(), testUnmarhsal.ApiSession.ApiSession.GetToken())
32+
})
33+
}

edge-apis/client_edge_client.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package edge_apis
33
import (
44
"crypto/x509"
55
"errors"
6+
"fmt"
67
"net/http"
78
"net/url"
89
"sync"
@@ -143,9 +144,13 @@ func (self *ZitiEdgeClient) Authenticate(credentials Credentials, configTypesOve
143144
func (self *ZitiEdgeClient) legacyAuth(credentials Credentials, configTypes []string, httpClient *http.Client) (ApiSession, error) {
144145
params := clientAuth.NewAuthenticateParams()
145146
params.Auth = credentials.Payload()
146-
params.Method = credentials.Method()
147+
params.Method = string(credentials.Method())
147148
params.Auth.ConfigTypes = append(params.Auth.ConfigTypes, configTypes...)
148149

150+
if credentials.Method() == AuthMethodEmpty {
151+
return nil, fmt.Errorf("auth method %s cannot be used for authentication, please provide alternate credentials", AuthMethodEmpty)
152+
}
153+
149154
certs := credentials.TlsCerts()
150155
if len(certs) != 0 {
151156
if transport, ok := httpClient.Transport.(*http.Transport); ok {

edge-apis/client_edge_management.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package edge_apis
33
import (
44
"crypto/x509"
55
"errors"
6+
"fmt"
67
"net/http"
78
"net/url"
89
"sync"
@@ -143,9 +144,13 @@ func (self *ZitiEdgeManagement) Authenticate(credentials Credentials, configType
143144
func (self *ZitiEdgeManagement) legacyAuth(credentials Credentials, configTypes []string, httpClient *http.Client) (ApiSession, error) {
144145
params := manAuth.NewAuthenticateParams()
145146
params.Auth = credentials.Payload()
146-
params.Method = credentials.Method()
147+
params.Method = string(credentials.Method())
147148
params.Auth.ConfigTypes = append(params.Auth.ConfigTypes, configTypes...)
148149

150+
if credentials.Method() == AuthMethodEmpty {
151+
return nil, fmt.Errorf("auth method %s cannot be used for authentication, please provide alternate credentials", AuthMethodEmpty)
152+
}
153+
149154
certs := credentials.TlsCerts()
150155
if len(certs) != 0 {
151156
if transport, ok := httpClient.Transport.(*http.Transport); ok {

edge-apis/clients_shared.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,10 @@ func oidcAuth(clientTransportPool ClientTransportPool, credentials Credentials,
217217
}
218218
method := credentials.Method()
219219

220+
if method == AuthMethodEmpty {
221+
return nil, fmt.Errorf("auth method %s cannot be used for authentication, please provide alternate credentials", AuthMethodEmpty)
222+
}
223+
220224
if configTypeOverrides != nil {
221225
payload.ConfigTypes = configTypeOverrides
222226
}
@@ -261,7 +265,7 @@ func oidcAuth(clientTransportPool ClientTransportPool, credentials Credentials,
261265
return nil, errors.New("could not find auth request id header")
262266
}
263267

264-
opLoginUri := "https://" + resp.RawResponse.Request.URL.Host + "/oidc/login/" + method
268+
opLoginUri := "https://" + resp.RawResponse.Request.URL.Host + "/oidc/login/" + string(method)
265269
totpUri := "https://" + resp.RawResponse.Request.URL.Host + "/oidc/login/totp"
266270

267271
formData := payload.toValues()

edge-apis/credentials.go

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,23 @@ import (
44
"crypto"
55
"crypto/tls"
66
"crypto/x509"
7+
"net/http"
8+
79
"github.com/go-openapi/runtime"
810
"github.com/go-openapi/strfmt"
911
"github.com/openziti/edge-api/rest_model"
1012
"github.com/openziti/identity"
1113
"github.com/openziti/sdk-golang/ziti/edge/network"
1214
"github.com/openziti/sdk-golang/ziti/sdkinfo"
13-
"net/http"
15+
)
16+
17+
type AuthMethod string
18+
19+
const (
20+
AuthMethodCert AuthMethod = "cert"
21+
AuthMethodUpdb AuthMethod = "password"
22+
AuthMethodEmpty AuthMethod = "empty"
23+
AuthMethodJwtExt AuthMethod = "ext-jwt"
1424
)
1525

1626
// Credentials represents the minimal information needed across all authentication mechanisms to authenticate an identity
@@ -26,7 +36,7 @@ type Credentials interface {
2636
GetCaPool() *x509.CertPool
2737

2838
// Method returns the authentication necessary to complete an authentication request.
29-
Method() string
39+
Method() AuthMethod
3040

3141
// AddAuthHeader adds a header for all authentication requests.
3242
AddAuthHeader(key, value string)
@@ -225,8 +235,8 @@ func NewCertCredentials(certs []*x509.Certificate, key crypto.PrivateKey) *CertC
225235
}
226236
}
227237

228-
func (c *CertCredentials) Method() string {
229-
return "cert"
238+
func (c *CertCredentials) Method() AuthMethod {
239+
return AuthMethodCert
230240
}
231241

232242
func (c *CertCredentials) TlsCerts() []tls.Certificate {
@@ -264,8 +274,8 @@ func (c *IdentityCredentials) GetIdentity() identity.Identity {
264274
return c.Identity
265275
}
266276

267-
func (c *IdentityCredentials) Method() string {
268-
return "cert"
277+
func (c *IdentityCredentials) Method() AuthMethod {
278+
return AuthMethodCert
269279
}
270280

271281
func (c *IdentityCredentials) GetCaPool() *x509.CertPool {
@@ -301,8 +311,8 @@ func NewJwtCredentials(jwt string) *JwtCredentials {
301311
}
302312
}
303313

304-
func (c *JwtCredentials) Method() string {
305-
return "ext-jwt"
314+
func (c *JwtCredentials) Method() AuthMethod {
315+
return AuthMethodJwtExt
306316
}
307317

308318
func (c *JwtCredentials) AuthenticateRequest(request runtime.ClientRequest, reg strfmt.Registry) error {
@@ -330,8 +340,8 @@ type UpdbCredentials struct {
330340
Password string
331341
}
332342

333-
func (c *UpdbCredentials) Method() string {
334-
return "password"
343+
func (c *UpdbCredentials) Method() AuthMethod {
344+
return AuthMethodUpdb
335345
}
336346

337347
// NewUpdbCredentials creates a Credentials instance based on a username/passwords combination.
@@ -354,3 +364,13 @@ func (c *UpdbCredentials) Payload() *rest_model.Authenticate {
354364
func (c *UpdbCredentials) AuthenticateRequest(request runtime.ClientRequest, reg strfmt.Registry) error {
355365
return c.BaseCredentials.AuthenticateRequest(request, reg)
356366
}
367+
368+
var _ Credentials = (*EmptyCredentials)(nil)
369+
370+
type EmptyCredentials struct {
371+
BaseCredentials
372+
}
373+
374+
func (e EmptyCredentials) Method() AuthMethod {
375+
return AuthMethodEmpty
376+
}

edge-apis/oidc.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ func (t *localRpServer) Start() {
131131

132132
// newLocalRpServer creates and configures a local HTTP server for handling OpenID Connect
133133
// authentication flows, including callback processing and token exchange.
134-
func newLocalRpServer(apiHost string, authMethod string) (*localRpServer, error) {
134+
func newLocalRpServer(apiHost string, authMethod AuthMethod) (*localRpServer, error) {
135135
tokenOutChan := make(chan *oidc.Tokens[*oidc.IDTokenClaims], 1)
136136
result := &localRpServer{
137137
CallbackPath: "/auth/callback",
@@ -198,7 +198,7 @@ func newLocalRpServer(apiHost string, authMethod string) (*localRpServer, error)
198198
}
199199
serverMux := http.NewServeMux()
200200

201-
authHandler := rp.AuthURLHandler(state, provider, rp.WithPromptURLParam("Welcome back!"), rp.WithURLParam("method", authMethod))
201+
authHandler := rp.AuthURLHandler(state, provider, rp.WithPromptURLParam("Welcome back!"), rp.WithURLParam("method", string(authMethod)))
202202
loginHandler := http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
203203
authHandler.ServeHTTP(writer, request)
204204
})

0 commit comments

Comments
 (0)