Skip to content

Commit

Permalink
Merge pull request #55 from muzzammilshahid/auth-tests
Browse files Browse the repository at this point in the history
Add tests for Authentications
  • Loading branch information
muzzammilshahid authored Jul 10, 2024
2 parents 2aa1545 + 7743182 commit 4329ecd
Show file tree
Hide file tree
Showing 6 changed files with 327 additions and 0 deletions.
27 changes: 27 additions & 0 deletions auth/anonymous_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package auth_test

import (
"testing"

"github.com/stretchr/testify/require"

"github.com/xconnio/wampproto-go/auth"
"github.com/xconnio/wampproto-go/messages"
)

func TestNewAnonymousAuthenticator(t *testing.T) {
authenticator := auth.NewAnonymousAuthenticator(testAuthID, nil)

require.Equal(t, testAuthID, authenticator.AuthID())
require.Equal(t, auth.MethodAnonymous, authenticator.AuthMethod())
require.NotNil(t, authenticator.AuthExtra())
require.Empty(t, authenticator.AuthExtra()) // AuthExtra should be an empty map

t.Run("Authenticate", func(t *testing.T) {
challenge := messages.NewChallenge(auth.MethodAnonymous, nil)

authenticate, err := authenticator.Authenticate(*challenge)
require.EqualError(t, err, "func Authenticate() must not be called for anonymous authentication")
require.Nil(t, authenticate)
})
}
115 changes: 115 additions & 0 deletions auth/cra_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package auth_test

import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"testing"

"github.com/stretchr/testify/require"

"github.com/xconnio/wampproto-go/auth"
"github.com/xconnio/wampproto-go/messages"
)

const (
testSecret = "secret"
testCRAChallenge = `{
"authid": "authid",
"authmethod": "wampcra",
"authprovider": "provider",
"authrole": "authrole",
"nonce": "VJ/iO7bpl5rCiRGJ7IGuQg==",
"session": 12345,
"timestamp": "2024-07-09T14:32:29+0500"
}`
)

func TestNewCRAAuthenticator(t *testing.T) {
authenticator := auth.NewCRAAuthenticator(testAuthID, nil, testSecret)

require.Equal(t, testAuthID, authenticator.AuthID())
require.Equal(t, auth.MethodCRA, authenticator.AuthMethod())
require.Nil(t, authenticator.AuthExtra())

t.Run("Authenticate", func(t *testing.T) {
challengeData := map[string]any{"challenge": testCRAChallenge}
challenge := messages.NewChallenge(auth.MethodCRA, challengeData)

authenticate, err := authenticator.Authenticate(*challenge)
require.NoError(t, err)

expectedSig := auth.SignCRAChallenge(testCRAChallenge, []byte(testSecret))
require.Equal(t, expectedSig, authenticate.Signature())
})
}

func signCRAChallenge() []byte {
key := []byte(testSecret)

sig := hmac.New(sha256.New, key)
sig.Write([]byte(testCRAChallenge))
sigBytes := sig.Sum(nil)

return sigBytes
}

func TestSignCRAChallengeBytes(t *testing.T) {
expectedBytes := signCRAChallenge()

signedBytes := auth.SignCRAChallengeBytes(testCRAChallenge, []byte(testSecret))
require.Equal(t, expectedBytes, signedBytes)
}

func TestSignCRAChallenge(t *testing.T) {
expectedBytes := signCRAChallenge()

expectedSig := base64.StdEncoding.EncodeToString(expectedBytes)
signed := auth.SignCRAChallenge(testCRAChallenge, []byte(testSecret))
require.Equal(t, expectedSig, signed)
}

func TestDeriveCRAKey(t *testing.T) {
salt := "somesalt"
secret := testSecret
iterations := 1000
keyLength := 32

derivedKey := auth.DeriveCRAKey(salt, secret, iterations, keyLength)
require.NotNil(t, derivedKey)
require.Equal(t, base64.StdEncoding.EncodedLen(keyLength), len(derivedKey))
}

func TestVerifyCRASignature(t *testing.T) {
key := []byte(testSecret)
sig := auth.SignCRAChallenge(testCRAChallenge, key)

valid := auth.VerifyCRASignature(sig, testCRAChallenge, key)
require.True(t, valid)

invalid := auth.VerifyCRASignature("invalidsig", testCRAChallenge, key)
require.False(t, invalid)
}

func TestGenerateCRAChallenge(t *testing.T) {
session := int64(12345)
authid := "authid"
authrole := "authrole"
provider := "provider"

challenge, err := auth.GenerateCRAChallenge(session, authid, authrole, provider)
require.NoError(t, err)

var data map[string]any
err = json.Unmarshal([]byte(challenge), &data)
require.NoError(t, err)

require.Equal(t, session, int64(data["session"].(float64)))
require.Equal(t, authid, data["authid"])
require.Equal(t, authrole, data["authrole"])
require.Equal(t, provider, data["authprovider"])
require.Equal(t, auth.MethodCRA, data["authmethod"])
require.NotEmpty(t, data["nonce"])
require.NotEmpty(t, data["timestamp"])
}
97 changes: 97 additions & 0 deletions auth/cryptosign_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package auth_test

import (
"crypto/ed25519"
"encoding/hex"
"testing"

"github.com/stretchr/testify/require"

"github.com/xconnio/wampproto-go/auth"
"github.com/xconnio/wampproto-go/messages"
)

const (
testAuthID = "foo"
testPublicKey = "2b7ec216daa877c7f4c9439db8a722ea2340eacad506988db2564e258284f895"
testPrivateKey = "022b089bed5ab78808365e82dd12c796c835aeb98b4a5a9e099d3e72cb719516"
testChallenge = "5c7b195948a15a9f94bdc31cf6d88294e380985e2c40f5f912fd707e080cb5ff"
)

func TestNewCryptoSignAuthenticator(t *testing.T) {
authenticator, err := auth.NewCryptoSignAuthenticator(testAuthID, nil, testPrivateKey)
require.NoError(t, err)

require.Equal(t, testAuthID, authenticator.AuthID())
require.Equal(t, auth.MethodCryptoSign, authenticator.AuthMethod())
require.Equal(t, testPublicKey, authenticator.AuthExtra()["pubkey"])

t.Run("InvalidPrivateKey", func(t *testing.T) {
_, err = auth.NewCryptoSignAuthenticator(testAuthID, nil, "invalidkey")
require.Error(t, err)
})

t.Run("MismatchedPublicKey", func(t *testing.T) {
authExtra := map[string]any{"pubkey": "d057db19aa21f20419dfd385c3dae0cc39ecfc94f8acc921d5f9fc76443098f0"}
_, err = auth.NewCryptoSignAuthenticator("authID", authExtra, testPrivateKey)
require.Error(t, err)
})

t.Run("Authenticate", func(t *testing.T) {
challenge := messages.NewChallenge(auth.MethodCryptoSign, map[string]any{"challenge": testChallenge})

authenticate, err := authenticator.Authenticate(*challenge)
require.NoError(t, err)

signed, err := hex.DecodeString(authenticate.Signature())
require.NoError(t, err)
require.Equal(t, 96, len(signed))
})
}

func TestSignCryptoSignChallenge(t *testing.T) {
privateKey, err := hex.DecodeString(testPrivateKey + testPublicKey)
require.NoError(t, err)

signature, err := auth.SignCryptoSignChallenge(testChallenge, privateKey)
require.NoError(t, err)

signatureBytes, err := hex.DecodeString(signature)
require.NoError(t, err)

require.Equal(t, 96, len(signatureBytes))
}

func TestVerifyCryptoSignSignature(t *testing.T) {
privateKey, err := hex.DecodeString(testPrivateKey + testPublicKey)
require.NoError(t, err)

signature, err := auth.SignCryptoSignChallenge(testChallenge, privateKey)
require.NoError(t, err)

publicKeyBytes, err := hex.DecodeString(testPublicKey)
require.NoError(t, err)

isVerified, err := auth.VerifyCryptoSignSignature(signature, publicKeyBytes)
require.NoError(t, err)
require.True(t, isVerified)
}

func TestGenerateCryptoSignChallenge(t *testing.T) {
challenge, err := auth.GenerateCryptoSignChallenge()
require.NoError(t, err)
require.Equal(t, 64, len(challenge))
}

func TestGenerateCryptoSignKeyPair(t *testing.T) {
publicKey, privateKey, err := auth.GenerateCryptoSignKeyPair()
require.NoError(t, err)

pubKeyBytes, err := hex.DecodeString(publicKey)
require.NoError(t, err)
require.Equal(t, ed25519.PublicKeySize, len(pubKeyBytes))

priKeyBytes, err := hex.DecodeString(privateKey)
require.NoError(t, err)
require.Equal(t, ed25519.SeedSize, len(priKeyBytes))
}
35 changes: 35 additions & 0 deletions auth/helpers_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package auth_test

import (
"testing"

"github.com/stretchr/testify/require"

"github.com/xconnio/wampproto-go/auth"
)

func TestSelectAuthMethod(t *testing.T) {
// case where proposed methods include allowed methods
allowedMethods := []auth.Method{"ticket", "anonymous"}
proposedMethods := []string{"ticket", "challenge", "anonymous"}

method, err := auth.SelectAuthMethod(allowedMethods, proposedMethods)
require.NoError(t, err)
require.Equal(t, auth.Method("ticket"), method)

// case where no proposed methods match allowed methods
allowedMethods = []auth.Method{"ticket", "anonymous"}
proposedMethods = []string{"challenge"}

method, err = auth.SelectAuthMethod(allowedMethods, proposedMethods)
require.EqualError(t, err, "server does not have [challenge] auth enabled")
require.Equal(t, auth.Method(""), method)

// case where proposed methods is empty
allowedMethods = []auth.Method{"ticket", "anonymous"}
proposedMethods = []string{}

method, err = auth.SelectAuthMethod(allowedMethods, proposedMethods)
require.NoError(t, err)
require.Equal(t, auth.Method("anonymous"), method)
}
27 changes: 27 additions & 0 deletions auth/iso8601_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package auth_test

import (
"testing"
"time"

"github.com/stretchr/testify/require"

"github.com/xconnio/wampproto-go/auth"
)

func TestISO8601(t *testing.T) {
// UTC time
t1 := time.Date(2024, 7, 10, 12, 30, 0, 0, time.UTC)
expected1 := "2024-07-10T12:30:00Z"
require.Equal(t, expected1, auth.ISO8601(t1))

// Time with negative timezone offset
t2 := time.Date(2024, 7, 10, 12, 30, 0, 0, time.FixedZone("CET", -1*60*60))
expected2 := "2024-07-10T12:30:00-0100"
require.Equal(t, expected2, auth.ISO8601(t2))

// Time with positive timezone offset
t3 := time.Date(2024, 7, 10, 12, 30, 0, 0, time.FixedZone("JST", 9*60*60))
expected3 := "2024-07-10T12:30:00+0900"
require.Equal(t, expected3, auth.ISO8601(t3))
}
26 changes: 26 additions & 0 deletions auth/ticket_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package auth_test

import (
"testing"

"github.com/stretchr/testify/require"

"github.com/xconnio/wampproto-go/auth"
"github.com/xconnio/wampproto-go/messages"
)

func TestNewTicketAuthenticator(t *testing.T) {
authenticator := auth.NewTicketAuthenticator(testAuthID, nil, "ticket")

require.Equal(t, testAuthID, authenticator.AuthID())
require.Equal(t, auth.MethodTicket, authenticator.AuthMethod())
require.Nil(t, authenticator.AuthExtra())

t.Run("Authenticate", func(t *testing.T) {
challenge := messages.NewChallenge(auth.MethodTicket, nil)

authenticate, err := authenticator.Authenticate(*challenge)
require.NoError(t, err)
require.Equal(t, "ticket", authenticate.Signature())
})
}

0 comments on commit 4329ecd

Please sign in to comment.