2022-04-03 12:44:52 +00:00
package configuration_test
2022-03-02 06:40:26 +00:00
import (
2022-10-02 02:07:40 +00:00
"bytes"
"crypto/ecdsa"
"crypto/rsa"
2023-05-31 10:50:22 +00:00
"crypto/tls"
2022-10-02 02:07:40 +00:00
"crypto/x509"
"encoding/pem"
2023-05-31 10:50:22 +00:00
"fmt"
2023-05-08 03:30:49 +00:00
"math"
2022-04-03 12:44:52 +00:00
"net/mail"
2022-03-16 05:16:46 +00:00
"net/url"
2022-03-02 06:40:26 +00:00
"reflect"
2022-04-01 11:38:49 +00:00
"regexp"
2022-03-02 06:40:26 +00:00
"testing"
"time"
"github.com/stretchr/testify/assert"
2022-04-01 11:38:49 +00:00
"github.com/stretchr/testify/require"
2022-03-16 05:16:46 +00:00
2022-04-03 12:44:52 +00:00
"github.com/authelia/authelia/v4/internal/configuration"
2022-07-05 04:43:12 +00:00
"github.com/authelia/authelia/v4/internal/configuration/schema"
2022-04-03 12:44:52 +00:00
)
2022-03-02 06:40:26 +00:00
2022-04-03 12:44:52 +00:00
func TestStringToMailAddressHookFunc ( t * testing . T ) {
testCases := [ ] struct {
desc string
2022-10-03 00:52:29 +00:00
have any
want any
2022-04-03 12:44:52 +00:00
err string
decode bool
} {
{
desc : "ShouldDecodeMailAddress" ,
have : "james@example.com" ,
want : mail . Address { Name : "" , Address : "james@example.com" } ,
decode : true ,
} ,
{
desc : "ShouldDecodeMailAddressWithName" ,
have : "James <james@example.com>" ,
want : mail . Address { Name : "James" , Address : "james@example.com" } ,
decode : true ,
} ,
{
desc : "ShouldDecodeMailAddressWithEmptyString" ,
have : "" ,
want : mail . Address { } ,
decode : true ,
} ,
{
desc : "ShouldNotDecodeInvalidMailAddress" ,
have : "fred" ,
want : mail . Address { } ,
err : "could not decode 'fred' to a mail.Address (RFC5322): mail: missing '@' or angle-addr" ,
decode : true ,
} ,
}
2022-03-02 06:40:26 +00:00
2022-04-03 12:44:52 +00:00
hook := configuration . StringToMailAddressHookFunc ( )
2022-03-02 06:40:26 +00:00
2022-04-03 12:44:52 +00:00
for _ , tc := range testCases {
t . Run ( tc . desc , func ( t * testing . T ) {
result , err := hook ( reflect . TypeOf ( tc . have ) , reflect . TypeOf ( tc . want ) , tc . have )
switch {
case ! tc . decode :
assert . NoError ( t , err )
assert . Equal ( t , tc . have , result )
case tc . err == "" :
assert . NoError ( t , err )
require . Equal ( t , tc . want , result )
default :
assert . EqualError ( t , err , tc . err )
assert . Nil ( t , result )
}
} )
}
2022-03-02 06:40:26 +00:00
}
2022-04-03 12:44:52 +00:00
func TestStringToMailAddressHookFuncPointer ( t * testing . T ) {
testCases := [ ] struct {
desc string
2022-10-03 00:52:29 +00:00
have any
want any
2022-04-03 12:44:52 +00:00
err string
decode bool
} {
{
desc : "ShouldDecodeMailAddress" ,
have : "james@example.com" ,
want : & mail . Address { Name : "" , Address : "james@example.com" } ,
decode : true ,
} ,
{
desc : "ShouldDecodeMailAddressWithName" ,
have : "James <james@example.com>" ,
want : & mail . Address { Name : "James" , Address : "james@example.com" } ,
decode : true ,
} ,
{
desc : "ShouldDecodeMailAddressWithEmptyString" ,
have : "" ,
want : ( * mail . Address ) ( nil ) ,
decode : true ,
} ,
{
desc : "ShouldNotDecodeInvalidMailAddress" ,
have : "fred" ,
want : & mail . Address { } ,
err : "could not decode 'fred' to a *mail.Address (RFC5322): mail: missing '@' or angle-addr" ,
decode : true ,
} ,
{
desc : "ShouldNotDecodeToInt" ,
have : "fred" ,
want : testInt32Ptr ( 4 ) ,
decode : false ,
} ,
}
2022-03-02 06:40:26 +00:00
2022-04-03 12:44:52 +00:00
hook := configuration . StringToMailAddressHookFunc ( )
2022-03-02 06:40:26 +00:00
2022-04-03 12:44:52 +00:00
for _ , tc := range testCases {
t . Run ( tc . desc , func ( t * testing . T ) {
result , err := hook ( reflect . TypeOf ( tc . have ) , reflect . TypeOf ( tc . want ) , tc . have )
switch {
case ! tc . decode :
assert . NoError ( t , err )
assert . Equal ( t , tc . have , result )
case tc . err == "" :
assert . NoError ( t , err )
require . Equal ( t , tc . want , result )
default :
assert . EqualError ( t , err , tc . err )
assert . Nil ( t , result )
}
} )
}
2022-03-02 06:40:26 +00:00
}
2022-04-03 12:44:52 +00:00
func TestStringToURLHookFunc ( t * testing . T ) {
testCases := [ ] struct {
desc string
2022-10-03 00:52:29 +00:00
have any
want any
2022-04-03 12:44:52 +00:00
err string
decode bool
} {
{
desc : "ShouldDecodeURL" ,
have : "https://www.example.com:9090/abc?test=true" ,
want : url . URL { Scheme : "https" , Host : "www.example.com:9090" , Path : "/abc" , RawQuery : "test=true" } ,
decode : true ,
} ,
{
desc : "ShouldDecodeURLEmptyString" ,
have : "" ,
want : url . URL { } ,
decode : true ,
} ,
{
desc : "ShouldNotDecodeToString" ,
have : "abc" ,
want : "" ,
decode : false ,
} ,
{
desc : "ShouldDecodeURLWithUserAndPassword" ,
have : "https://john:abc123@www.example.com:9090/abc?test=true" ,
want : url . URL { Scheme : "https" , Host : "www.example.com:9090" , Path : "/abc" , RawQuery : "test=true" , User : url . UserPassword ( "john" , "abc123" ) } ,
decode : true ,
} ,
{
desc : "ShouldNotDecodeInt" ,
have : 5 ,
want : url . URL { } ,
decode : false ,
} ,
{
desc : "ShouldNotDecodeBool" ,
have : true ,
want : url . URL { } ,
decode : false ,
} ,
{
desc : "ShouldNotDecodeBadURL" ,
have : "*(!&@#(!*^$%" ,
want : url . URL { } ,
err : "could not decode '*(!&@#(!*^$%' to a url.URL: parse \"*(!&@#(!*^$%\": invalid URL escape \"%\"" ,
decode : true ,
} ,
}
2022-03-02 06:40:26 +00:00
2022-04-03 12:44:52 +00:00
hook := configuration . StringToURLHookFunc ( )
2022-03-02 06:40:26 +00:00
2022-04-03 12:44:52 +00:00
for _ , tc := range testCases {
t . Run ( tc . desc , func ( t * testing . T ) {
result , err := hook ( reflect . TypeOf ( tc . have ) , reflect . TypeOf ( tc . want ) , tc . have )
switch {
case ! tc . decode :
assert . NoError ( t , err )
assert . Equal ( t , tc . have , result )
case tc . err == "" :
assert . NoError ( t , err )
require . Equal ( t , tc . want , result )
default :
assert . EqualError ( t , err , tc . err )
assert . Nil ( t , result )
}
} )
}
2022-03-02 06:40:26 +00:00
}
2022-04-03 12:44:52 +00:00
func TestStringToURLHookFuncPointer ( t * testing . T ) {
testCases := [ ] struct {
desc string
2022-10-03 00:52:29 +00:00
have any
want any
2022-04-03 12:44:52 +00:00
err string
decode bool
} {
{
desc : "ShouldDecodeURL" ,
have : "https://www.example.com:9090/abc?test=true" ,
want : & url . URL { Scheme : "https" , Host : "www.example.com:9090" , Path : "/abc" , RawQuery : "test=true" } ,
decode : true ,
} ,
{
desc : "ShouldDecodeURLEmptyString" ,
have : "" ,
want : ( * url . URL ) ( nil ) ,
decode : true ,
} ,
{
desc : "ShouldDecodeURLWithUserAndPassword" ,
have : "https://john:abc123@www.example.com:9090/abc?test=true" ,
want : & url . URL { Scheme : "https" , Host : "www.example.com:9090" , Path : "/abc" , RawQuery : "test=true" , User : url . UserPassword ( "john" , "abc123" ) } ,
decode : true ,
} ,
{
desc : "ShouldNotDecodeInt" ,
have : 5 ,
want : & url . URL { } ,
decode : false ,
} ,
{
desc : "ShouldNotDecodeBool" ,
have : true ,
want : & url . URL { } ,
decode : false ,
} ,
{
desc : "ShouldNotDecodeBadURL" ,
have : "*(!&@#(!*^$%" ,
want : & url . URL { } ,
err : "could not decode '*(!&@#(!*^$%' to a *url.URL: parse \"*(!&@#(!*^$%\": invalid URL escape \"%\"" ,
decode : true ,
} ,
{
desc : "ShouldNotDecodeToInt" ,
have : "fred" ,
want : testInt32Ptr ( 4 ) ,
decode : false ,
} ,
}
2022-03-02 06:40:26 +00:00
2022-04-03 12:44:52 +00:00
hook := configuration . StringToURLHookFunc ( )
2022-03-02 06:40:26 +00:00
2022-04-03 12:44:52 +00:00
for _ , tc := range testCases {
t . Run ( tc . desc , func ( t * testing . T ) {
result , err := hook ( reflect . TypeOf ( tc . have ) , reflect . TypeOf ( tc . want ) , tc . have )
switch {
case ! tc . decode :
assert . NoError ( t , err )
assert . Equal ( t , tc . have , result )
case tc . err == "" :
assert . NoError ( t , err )
require . Equal ( t , tc . want , result )
default :
assert . EqualError ( t , err , tc . err )
assert . Nil ( t , result )
}
} )
}
2022-03-02 06:40:26 +00:00
}
2022-04-03 12:44:52 +00:00
func TestToTimeDurationHookFunc ( t * testing . T ) {
testCases := [ ] struct {
desc string
2022-10-03 00:52:29 +00:00
have any
want any
2022-04-03 12:44:52 +00:00
err string
decode bool
} {
{
desc : "ShouldDecodeFourtyFiveSeconds" ,
have : "45s" ,
want : time . Second * 45 ,
decode : true ,
} ,
{
desc : "ShouldDecodeOneMinute" ,
have : "1m" ,
want : time . Minute ,
decode : true ,
} ,
{
desc : "ShouldDecodeTwoHours" ,
have : "2h" ,
want : time . Hour * 2 ,
decode : true ,
} ,
{
desc : "ShouldDecodeThreeDays" ,
have : "3d" ,
want : time . Hour * 24 * 3 ,
decode : true ,
} ,
{
desc : "ShouldDecodeFourWeeks" ,
have : "4w" ,
want : time . Hour * 24 * 7 * 4 ,
decode : true ,
} ,
{
desc : "ShouldDecodeFiveMonths" ,
have : "5M" ,
want : time . Hour * 24 * 30 * 5 ,
decode : true ,
} ,
{
desc : "ShouldDecodeSixYears" ,
have : "6y" ,
want : time . Hour * 24 * 365 * 6 ,
decode : true ,
} ,
{
desc : "ShouldNotDecodeInvalidString" ,
have : "abc" ,
want : time . Duration ( 0 ) ,
err : "could not decode 'abc' to a time.Duration: could not parse 'abc' as a duration" ,
decode : true ,
} ,
{
desc : "ShouldDecodeIntToSeconds" ,
have : 60 ,
want : time . Second * 60 ,
decode : true ,
} ,
2023-05-08 03:30:49 +00:00
{
desc : "ShouldDecodeInt8ToSeconds" ,
have : int8 ( 90 ) ,
want : time . Second * 90 ,
decode : true ,
} ,
{
desc : "ShouldDecodeInt16ToSeconds" ,
have : int16 ( 90 ) ,
want : time . Second * 90 ,
decode : true ,
} ,
2022-04-03 12:44:52 +00:00
{
desc : "ShouldDecodeInt32ToSeconds" ,
have : int32 ( 90 ) ,
want : time . Second * 90 ,
decode : true ,
} ,
2023-05-08 03:30:49 +00:00
{
desc : "ShouldDecodeFloat64ToSeconds" ,
have : float64 ( 90 ) ,
want : time . Second * 90 ,
decode : true ,
} ,
{
desc : "ShouldDecodeFloat64ToSeconds" ,
have : math . MaxFloat64 ,
want : time . Duration ( math . MaxInt64 ) ,
decode : true ,
} ,
2022-04-03 12:44:52 +00:00
{
desc : "ShouldDecodeInt64ToSeconds" ,
have : int64 ( 120 ) ,
want : time . Second * 120 ,
decode : true ,
} ,
{
desc : "ShouldDecodeTimeDuration" ,
have : time . Second * 30 ,
want : time . Second * 30 ,
decode : true ,
} ,
{
desc : "ShouldNotDecodeToString" ,
have : int64 ( 30 ) ,
want : "" ,
decode : false ,
} ,
{
desc : "ShouldDecodeFromIntZero" ,
have : 0 ,
want : time . Duration ( 0 ) ,
decode : true ,
} ,
2023-05-08 03:30:49 +00:00
{
desc : "ShouldSkipParsingBoolean" ,
have : true ,
want : time . Duration ( 0 ) ,
decode : false ,
} ,
2022-04-03 12:44:52 +00:00
{
desc : "ShouldNotDecodeFromBool" ,
have : true ,
want : true ,
} ,
}
2022-03-02 06:40:26 +00:00
2022-04-03 12:44:52 +00:00
hook := configuration . ToTimeDurationHookFunc ( )
2022-03-02 06:40:26 +00:00
2022-04-03 12:44:52 +00:00
for _ , tc := range testCases {
t . Run ( tc . desc , func ( t * testing . T ) {
result , err := hook ( reflect . TypeOf ( tc . have ) , reflect . TypeOf ( tc . want ) , tc . have )
switch {
case ! tc . decode :
assert . NoError ( t , err )
assert . Equal ( t , tc . have , result )
case tc . err == "" :
assert . NoError ( t , err )
require . Equal ( t , tc . want , result )
default :
assert . EqualError ( t , err , tc . err )
assert . Nil ( t , result )
}
} )
}
2022-03-02 06:40:26 +00:00
}
2022-04-03 12:44:52 +00:00
func TestToTimeDurationHookFuncPointer ( t * testing . T ) {
testCases := [ ] struct {
desc string
2022-10-03 00:52:29 +00:00
have any
want any
2022-04-03 12:44:52 +00:00
err string
decode bool
} {
{
desc : "ShouldDecodeFourtyFiveSeconds" ,
have : "45s" ,
want : testTimeDurationPtr ( time . Second * 45 ) ,
decode : true ,
} ,
{
desc : "ShouldDecodeOneMinute" ,
have : "1m" ,
want : testTimeDurationPtr ( time . Minute ) ,
decode : true ,
} ,
{
desc : "ShouldDecodeTwoHours" ,
have : "2h" ,
want : testTimeDurationPtr ( time . Hour * 2 ) ,
decode : true ,
} ,
{
desc : "ShouldDecodeThreeDays" ,
have : "3d" ,
want : testTimeDurationPtr ( time . Hour * 24 * 3 ) ,
decode : true ,
} ,
{
desc : "ShouldDecodeFourWeeks" ,
have : "4w" ,
want : testTimeDurationPtr ( time . Hour * 24 * 7 * 4 ) ,
decode : true ,
} ,
{
desc : "ShouldDecodeFiveMonths" ,
have : "5M" ,
want : testTimeDurationPtr ( time . Hour * 24 * 30 * 5 ) ,
decode : true ,
} ,
{
desc : "ShouldDecodeSixYears" ,
have : "6y" ,
want : testTimeDurationPtr ( time . Hour * 24 * 365 * 6 ) ,
decode : true ,
} ,
{
desc : "ShouldNotDecodeInvalidString" ,
have : "abc" ,
want : testTimeDurationPtr ( time . Duration ( 0 ) ) ,
err : "could not decode 'abc' to a *time.Duration: could not parse 'abc' as a duration" ,
decode : true ,
} ,
{
desc : "ShouldDecodeIntToSeconds" ,
have : 60 ,
want : testTimeDurationPtr ( time . Second * 60 ) ,
decode : true ,
} ,
{
desc : "ShouldDecodeInt32ToSeconds" ,
have : int32 ( 90 ) ,
want : testTimeDurationPtr ( time . Second * 90 ) ,
decode : true ,
} ,
{
desc : "ShouldDecodeInt64ToSeconds" ,
have : int64 ( 120 ) ,
want : testTimeDurationPtr ( time . Second * 120 ) ,
decode : true ,
} ,
{
desc : "ShouldDecodeTimeDuration" ,
have : time . Second * 30 ,
want : testTimeDurationPtr ( time . Second * 30 ) ,
decode : true ,
} ,
{
desc : "ShouldNotDecodeToString" ,
have : int64 ( 30 ) ,
want : & testString ,
decode : false ,
} ,
{
desc : "ShouldDecodeFromIntZero" ,
have : 0 ,
want : testTimeDurationPtr ( time . Duration ( 0 ) ) ,
decode : true ,
} ,
{
desc : "ShouldNotDecodeFromBool" ,
have : true ,
want : & testTrue ,
decode : false ,
} ,
}
2022-03-02 06:40:26 +00:00
2022-04-03 12:44:52 +00:00
hook := configuration . ToTimeDurationHookFunc ( )
2022-03-02 06:40:26 +00:00
2022-04-03 12:44:52 +00:00
for _ , tc := range testCases {
t . Run ( tc . desc , func ( t * testing . T ) {
result , err := hook ( reflect . TypeOf ( tc . have ) , reflect . TypeOf ( tc . want ) , tc . have )
switch {
case ! tc . decode :
assert . NoError ( t , err )
assert . Equal ( t , tc . have , result )
case tc . err == "" :
assert . NoError ( t , err )
require . Equal ( t , tc . want , result )
default :
assert . EqualError ( t , err , tc . err )
assert . Nil ( t , result )
}
} )
}
2022-03-02 06:40:26 +00:00
}
2022-03-05 05:51:41 +00:00
2022-04-03 12:44:52 +00:00
func TestStringToRegexpFunc ( t * testing . T ) {
testCases := [ ] struct {
desc string
2022-10-03 00:52:29 +00:00
have any
want any
2022-04-03 12:44:52 +00:00
err string
decode bool
wantGrps [ ] string
} {
{
desc : "ShouldNotDecodeRegexpWithOpenParenthesis" ,
have : "hello(test one two" ,
want : regexp . Regexp { } ,
err : "could not decode 'hello(test one two' to a regexp.Regexp: error parsing regexp: missing closing ): `hello(test one two`" ,
decode : true ,
} ,
{
desc : "ShouldDecodeValidRegex" ,
have : "^(api|admin)$" ,
want : * regexp . MustCompile ( ` ^(api|admin)$ ` ) ,
decode : true ,
} ,
{
desc : "ShouldDecodeValidRegexWithGroupNames" ,
have : "^(?P<area>api|admin)(one|two)$" ,
want : * regexp . MustCompile ( ` ^(?P<area>api|admin)(one|two)$ ` ) ,
decode : true ,
wantGrps : [ ] string { "area" } ,
} ,
{
desc : "ShouldNotDecodeFromInt32" ,
have : int32 ( 20 ) ,
want : regexp . Regexp { } ,
decode : false ,
} ,
{
desc : "ShouldNotDecodeFromBool" ,
have : false ,
want : regexp . Regexp { } ,
decode : false ,
} ,
{
desc : "ShouldNotDecodeToBool" ,
have : "^(?P<area>api|admin)(one|two)$" ,
want : testTrue ,
decode : false ,
} ,
{
desc : "ShouldNotDecodeToInt32" ,
have : "^(?P<area>api|admin)(one|two)$" ,
want : testInt32Ptr ( 0 ) ,
decode : false ,
} ,
{
desc : "ShouldNotDecodeToMailAddress" ,
have : "^(?P<area>api|admin)(one|two)$" ,
want : mail . Address { } ,
decode : false ,
} ,
{
desc : "ShouldErrOnDecodeEmptyString" ,
have : "" ,
want : regexp . Regexp { } ,
err : "could not decode an empty value to a regexp.Regexp: must have a non-empty value" ,
decode : true ,
} ,
}
2022-03-05 05:51:41 +00:00
2022-06-01 23:18:45 +00:00
hook := configuration . StringToRegexpHookFunc ( )
2022-04-01 11:38:49 +00:00
2022-04-03 12:44:52 +00:00
for _ , tc := range testCases {
t . Run ( tc . desc , func ( t * testing . T ) {
result , err := hook ( reflect . TypeOf ( tc . have ) , reflect . TypeOf ( tc . want ) , tc . have )
switch {
case ! tc . decode :
assert . NoError ( t , err )
assert . Equal ( t , tc . have , result )
case tc . err == "" :
assert . NoError ( t , err )
require . Equal ( t , tc . want , result )
pattern := result . ( regexp . Regexp )
var names [ ] string
for _ , name := range pattern . SubexpNames ( ) {
if name != "" {
names = append ( names , name )
}
}
2022-04-01 11:38:49 +00:00
2022-04-03 12:44:52 +00:00
if len ( tc . wantGrps ) != 0 {
t . Run ( "MustHaveAllExpectedSubexpGroupNames" , func ( t * testing . T ) {
for _ , name := range tc . wantGrps {
assert . Contains ( t , names , name )
}
} )
t . Run ( "MustNotHaveUnexpectedSubexpGroupNames" , func ( t * testing . T ) {
for _ , name := range names {
assert . Contains ( t , tc . wantGrps , name )
}
} )
} else {
t . Run ( "MustHaveNoSubexpGroupNames" , func ( t * testing . T ) {
assert . Len ( t , names , 0 )
} )
}
default :
assert . EqualError ( t , err , tc . err )
assert . Nil ( t , result )
}
} )
2022-04-01 11:38:49 +00:00
}
2022-04-03 12:44:52 +00:00
}
2022-04-01 11:38:49 +00:00
2022-04-03 12:44:52 +00:00
func TestStringToRegexpFuncPointers ( t * testing . T ) {
2022-04-01 11:38:49 +00:00
testCases := [ ] struct {
2022-04-03 12:44:52 +00:00
desc string
2022-10-03 00:52:29 +00:00
have any
want any
2022-04-03 12:44:52 +00:00
err string
decode bool
wantGrps [ ] string
2022-04-01 11:38:49 +00:00
} {
{
2022-04-03 12:44:52 +00:00
desc : "ShouldNotDecodeRegexpWithOpenParenthesis" ,
have : "hello(test one two" ,
want : & regexp . Regexp { } ,
err : "could not decode 'hello(test one two' to a *regexp.Regexp: error parsing regexp: missing closing ): `hello(test one two`" ,
decode : true ,
2022-04-01 11:38:49 +00:00
} ,
{
2022-04-03 12:44:52 +00:00
desc : "ShouldDecodeValidRegex" ,
have : "^(api|admin)$" ,
want : regexp . MustCompile ( ` ^(api|admin)$ ` ) ,
decode : true ,
2022-04-01 11:38:49 +00:00
} ,
{
2022-04-03 12:44:52 +00:00
desc : "ShouldDecodeValidRegexWithGroupNames" ,
have : "^(?P<area>api|admin)(one|two)$" ,
want : regexp . MustCompile ( ` ^(?P<area>api|admin)(one|two)$ ` ) ,
decode : true ,
wantGrps : [ ] string { "area" } ,
} ,
{
desc : "ShouldNotDecodeFromInt32" ,
have : int32 ( 20 ) ,
want : & regexp . Regexp { } ,
decode : false ,
} ,
{
desc : "ShouldNotDecodeFromBool" ,
have : false ,
want : & regexp . Regexp { } ,
decode : false ,
} ,
{
desc : "ShouldNotDecodeToBool" ,
have : "^(?P<area>api|admin)(one|two)$" ,
want : & testTrue ,
decode : false ,
} ,
{
desc : "ShouldNotDecodeToInt32" ,
have : "^(?P<area>api|admin)(one|two)$" ,
want : & testZero ,
decode : false ,
} ,
{
desc : "ShouldNotDecodeToMailAddress" ,
have : "^(?P<area>api|admin)(one|two)$" ,
want : & mail . Address { } ,
decode : false ,
} ,
{
desc : "ShouldDecodeEmptyStringToNil" ,
have : "" ,
want : ( * regexp . Regexp ) ( nil ) ,
decode : true ,
2022-04-01 11:38:49 +00:00
} ,
}
2022-06-01 23:18:45 +00:00
hook := configuration . StringToRegexpHookFunc ( )
2022-04-01 11:38:49 +00:00
for _ , tc := range testCases {
t . Run ( tc . desc , func ( t * testing . T ) {
2022-04-03 12:44:52 +00:00
result , err := hook ( reflect . TypeOf ( tc . have ) , reflect . TypeOf ( tc . want ) , tc . have )
switch {
case ! tc . decode :
assert . NoError ( t , err )
assert . Equal ( t , tc . have , result )
case tc . err == "" :
assert . NoError ( t , err )
require . Equal ( t , tc . want , result )
pattern := result . ( * regexp . Regexp )
if tc . want == ( * regexp . Regexp ) ( nil ) {
assert . Nil ( t , pattern )
2022-04-01 11:38:49 +00:00
} else {
var names [ ] string
2022-04-03 12:44:52 +00:00
for _ , name := range pattern . SubexpNames ( ) {
2022-04-01 11:38:49 +00:00
if name != "" {
names = append ( names , name )
}
}
2022-04-03 12:44:52 +00:00
if len ( tc . wantGrps ) != 0 {
t . Run ( "MustHaveAllExpectedSubexpGroupNames" , func ( t * testing . T ) {
for _ , name := range tc . wantGrps {
2022-04-01 11:38:49 +00:00
assert . Contains ( t , names , name )
}
} )
2022-04-03 12:44:52 +00:00
t . Run ( "MustNotHaveUnexpectedSubexpGroupNames" , func ( t * testing . T ) {
2022-04-01 11:38:49 +00:00
for _ , name := range names {
2022-04-03 12:44:52 +00:00
assert . Contains ( t , tc . wantGrps , name )
2022-04-01 11:38:49 +00:00
}
} )
} else {
2022-04-03 12:44:52 +00:00
t . Run ( "MustHaveNoSubexpGroupNames" , func ( t * testing . T ) {
2022-04-01 11:38:49 +00:00
assert . Len ( t , names , 0 )
} )
}
}
2022-04-03 12:44:52 +00:00
default :
assert . EqualError ( t , err , tc . err )
assert . Nil ( t , result )
}
2022-04-01 11:38:49 +00:00
} )
}
}
2022-04-03 12:44:52 +00:00
2022-07-05 04:43:12 +00:00
func TestStringToAddressHookFunc ( t * testing . T ) {
testCases := [ ] struct {
name string
2022-10-03 00:52:29 +00:00
have any
expected any
2022-07-05 04:43:12 +00:00
err string
decode bool
} {
{
name : "ShouldDecodeNonPtr" ,
have : "tcp://0.0.0.0:2020" ,
2023-05-31 10:50:22 +00:00
expected : MustParseAddress ( "tcp://0.0.0.0:2020" ) ,
2022-07-05 04:43:12 +00:00
decode : true ,
} ,
{
name : "ShouldDecodePtr" ,
have : "tcp://0.0.0.0:2020" ,
2023-05-31 10:50:22 +00:00
expected : MustParseAddressPtr ( "tcp://0.0.0.0:2020" ) ,
2022-07-05 04:43:12 +00:00
decode : true ,
} ,
{
name : "ShouldNotDecodeIntegerToCorrectType" ,
have : 1 ,
expected : schema . Address { } ,
decode : false ,
} ,
{
name : "ShouldNotDecodeIntegerToCorrectTypePtr" ,
have : 1 ,
expected : & schema . Address { } ,
decode : false ,
} ,
{
name : "ShouldNotDecodeIntegerPtrToCorrectType" ,
have : testInt32Ptr ( 1 ) ,
expected : schema . Address { } ,
decode : false ,
} ,
{
name : "ShouldNotDecodeIntegerPtrToCorrectTypePtr" ,
have : testInt32Ptr ( 1 ) ,
expected : & schema . Address { } ,
decode : false ,
} ,
{
name : "ShouldNotDecodeToString" ,
have : "tcp://0.0.0.0:2020" ,
expected : "" ,
decode : false ,
} ,
{
name : "ShouldNotDecodeToIntPtr" ,
have : "tcp://0.0.0.0:2020" ,
expected : testInt32Ptr ( 1 ) ,
decode : false ,
} ,
{
name : "ShouldNotDecodeToIntPtr" ,
have : "tcp://0.0.0.0:2020" ,
expected : testInt32Ptr ( 1 ) ,
decode : false ,
} ,
{
name : "ShouldFailDecode" ,
have : "tcp://&!@^#*&!@#&*@!:2020" ,
expected : schema . Address { } ,
2023-05-07 06:39:17 +00:00
err : "could not decode 'tcp://&!@^#*&!@#&*@!:2020' to a schema.Address: could not parse string 'tcp://&!@^#*&!@#&*@!:2020' as address: expected format is [<scheme>://]<hostname>[:<port>]: parse \"tcp://&!@^\": invalid character \"^\" in host name" ,
2022-07-05 04:43:12 +00:00
decode : false ,
} ,
2023-05-31 10:50:22 +00:00
{
name : "ShouldDecodeTCP" ,
have : "tcp://127.0.0.1" ,
expected : schema . AddressTCP { Address : MustParseAddress ( "tcp://127.0.0.1" ) } ,
err : "" ,
decode : true ,
} ,
{
name : "ShouldDecodeTCPPtr" ,
have : "tcp://127.0.0.1" ,
expected : & schema . AddressTCP { Address : MustParseAddress ( "tcp://127.0.0.1" ) } ,
err : "" ,
decode : true ,
} ,
{
name : "ShouldDecodeUDP" ,
have : "udp://127.0.0.1" ,
expected : schema . AddressUDP { Address : MustParseAddress ( "udp://127.0.0.1" ) } ,
err : "" ,
decode : true ,
} ,
{
name : "ShouldDecodeUDPPtr" ,
have : "udp://127.0.0.1" ,
expected : & schema . AddressUDP { Address : MustParseAddress ( "udp://127.0.0.1" ) } ,
err : "" ,
decode : true ,
} ,
{
name : "ShouldDecodeLDAP" ,
have : "ldap://127.0.0.1" ,
expected : schema . AddressLDAP { Address : MustParseAddress ( "ldap://127.0.0.1" ) } ,
err : "" ,
decode : true ,
} ,
{
name : "ShouldDecodeLDAPPtr" ,
have : "ldap://127.0.0.1" ,
expected : & schema . AddressLDAP { Address : MustParseAddress ( "ldap://127.0.0.1" ) } ,
err : "" ,
decode : true ,
} ,
{
name : "ShouldDecodeSMTP" ,
have : "smtp://127.0.0.1" ,
expected : schema . AddressSMTP { Address : MustParseAddress ( "smtp://127.0.0.1" ) } ,
err : "" ,
decode : true ,
} ,
{
name : "ShouldDecodeSMTPPtr" ,
have : "smtp://127.0.0.1" ,
expected : & schema . AddressSMTP { Address : MustParseAddress ( "smtp://127.0.0.1" ) } ,
err : "" ,
decode : true ,
} ,
{
name : "ShouldFailDecodeTCP" ,
have : "@@@@@@@" ,
expected : schema . AddressTCP { Address : MustParseAddress ( "tcp://127.0.0.1" ) } ,
err : "could not decode '@@@@@@@' to a schema.AddressTCP: error validating the address: the url 'tcp://%40%40%40%40%40%40@' appears to have user info but this is not valid for addresses" ,
decode : false ,
} ,
{
name : "ShouldFailDecodeUDP" ,
have : "@@@@@@@" ,
expected : schema . AddressUDP { Address : MustParseAddress ( "udp://127.0.0.1" ) } ,
err : "could not decode '@@@@@@@' to a schema.AddressUDP: error validating the address: the url 'udp://%40%40%40%40%40%40@' appears to have user info but this is not valid for addresses" ,
decode : false ,
} ,
{
name : "ShouldFailDecodeLDAP" ,
have : "@@@@@@@" ,
expected : schema . AddressLDAP { Address : MustParseAddress ( "ldap://127.0.0.1" ) } ,
err : "could not decode '@@@@@@@' to a schema.AddressLDAP: error validating the address: the url 'ldaps://%40%40%40%40%40%40@' appears to have user info but this is not valid for addresses" ,
decode : false ,
} ,
{
name : "ShouldFailDecodeSMTP" ,
have : "@@@@@@@" ,
expected : schema . AddressSMTP { Address : MustParseAddress ( "smtp://127.0.0.1" ) } ,
err : "could not decode '@@@@@@@' to a schema.AddressSMTP: error validating the address: the url 'smtp://%40%40%40%40%40%40@' appears to have user info but this is not valid for addresses" ,
decode : false ,
} ,
2022-07-05 04:43:12 +00:00
}
hook := configuration . StringToAddressHookFunc ( )
for _ , tc := range testCases {
t . Run ( tc . name , func ( t * testing . T ) {
actual , err := hook ( reflect . TypeOf ( tc . have ) , reflect . TypeOf ( tc . expected ) , tc . have )
if tc . err != "" {
assert . EqualError ( t , err , tc . err )
if ! tc . decode {
assert . Nil ( t , actual )
}
} else {
assert . NoError ( t , err )
if tc . decode {
assert . Equal ( t , tc . expected , actual )
} else {
assert . Equal ( t , tc . have , actual )
}
}
} )
}
}
2022-10-03 00:52:29 +00:00
func TestStringToPrivateKeyHookFunc ( t * testing . T ) {
var (
nilRSA * rsa . PrivateKey
nilECDSA * ecdsa . PrivateKey
nilCert * x509 . Certificate
)
2022-10-02 02:07:40 +00:00
testCases := [ ] struct {
desc string
2022-10-03 00:52:29 +00:00
have any
want any
2022-10-02 02:07:40 +00:00
err string
decode bool
} {
{
desc : "ShouldDecodeRSAPrivateKey" ,
have : x509PrivateKeyRSA1 ,
2022-10-03 00:52:29 +00:00
want : MustParseRSAPrivateKey ( x509PrivateKeyRSA1 ) ,
decode : true ,
} ,
{
desc : "ShouldDecodeECDSAPrivateKey" ,
have : x509PrivateKeyEC1 ,
want : MustParseECDSAPrivateKey ( x509PrivateKeyEC1 ) ,
2022-10-02 02:07:40 +00:00
decode : true ,
} ,
{
desc : "ShouldNotDecodeToECDSAPrivateKey" ,
have : x509PrivateKeyRSA1 ,
want : & ecdsa . PrivateKey { } ,
2022-10-03 00:52:29 +00:00
decode : true ,
err : "could not decode to a *ecdsa.PrivateKey: the data is for a *rsa.PrivateKey not a *ecdsa.PrivateKey" ,
2022-10-02 02:07:40 +00:00
} ,
{
2022-10-03 00:52:29 +00:00
desc : "ShouldNotDecodeEmptyRSAKey" ,
2022-10-02 02:07:40 +00:00
have : "" ,
2022-10-03 00:52:29 +00:00
want : nilRSA ,
decode : true ,
} ,
{
desc : "ShouldNotDecodeEmptyECDSAKey" ,
have : "" ,
want : nilECDSA ,
2022-10-02 02:07:40 +00:00
decode : true ,
} ,
{
desc : "ShouldNotDecodeECDSAKeyToRSAKey" ,
have : x509PrivateKeyEC1 ,
2022-10-03 00:52:29 +00:00
want : nilRSA ,
2022-10-02 02:07:40 +00:00
decode : true ,
err : "could not decode to a *rsa.PrivateKey: the data is for a *ecdsa.PrivateKey not a *rsa.PrivateKey" ,
} ,
2022-10-03 00:52:29 +00:00
{
desc : "ShouldNotDecodeRSAKeyToECDSAKey" ,
have : x509PrivateKeyRSA1 ,
want : nilECDSA ,
decode : true ,
err : "could not decode to a *ecdsa.PrivateKey: the data is for a *rsa.PrivateKey not a *ecdsa.PrivateKey" ,
} ,
2022-10-02 02:07:40 +00:00
{
desc : "ShouldNotDecodeBadRSAPrivateKey" ,
have : x509PrivateKeyRSA2 ,
2022-10-03 00:52:29 +00:00
want : nilRSA ,
2022-10-02 02:07:40 +00:00
decode : true ,
err : "could not decode to a *rsa.PrivateKey: failed to parse PEM block containing the key" ,
} ,
2022-10-03 00:52:29 +00:00
{
desc : "ShouldNotDecodeBadECDSAPrivateKey" ,
have : x509PrivateKeyEC2 ,
want : nilECDSA ,
decode : true ,
err : "could not decode to a *ecdsa.PrivateKey: failed to parse PEM block containing the key" ,
} ,
{
desc : "ShouldNotDecodeCertificateToRSAPrivateKey" ,
have : x509CertificateRSA1 ,
want : nilRSA ,
decode : true ,
err : "could not decode to a *rsa.PrivateKey: the data is for a *x509.Certificate not a *rsa.PrivateKey" ,
} ,
{
desc : "ShouldNotDecodeCertificateToECDSAPrivateKey" ,
have : x509CertificateRSA1 ,
want : nilECDSA ,
decode : true ,
err : "could not decode to a *ecdsa.PrivateKey: the data is for a *x509.Certificate not a *ecdsa.PrivateKey" ,
} ,
{
desc : "ShouldNotDecodeRSAKeyToCertificate" ,
have : x509PrivateKeyRSA1 ,
want : nilCert ,
decode : false ,
} ,
{
desc : "ShouldNotDecodeECDSAKeyToCertificate" ,
have : x509PrivateKeyEC1 ,
want : nilCert ,
decode : false ,
} ,
2022-10-02 02:07:40 +00:00
}
2022-10-03 00:52:29 +00:00
hook := configuration . StringToPrivateKeyHookFunc ( )
2022-10-02 02:07:40 +00:00
for _ , tc := range testCases {
t . Run ( tc . desc , func ( t * testing . T ) {
result , err := hook ( reflect . TypeOf ( tc . have ) , reflect . TypeOf ( tc . want ) , tc . have )
switch {
case ! tc . decode :
assert . NoError ( t , err )
assert . Equal ( t , tc . have , result )
case tc . err == "" :
assert . NoError ( t , err )
require . Equal ( t , tc . want , result )
default :
assert . EqualError ( t , err , tc . err )
assert . Nil ( t , result )
}
} )
}
}
func TestStringToX509CertificateHookFunc ( t * testing . T ) {
var nilkey * x509 . Certificate
testCases := [ ] struct {
desc string
2022-10-05 05:05:23 +00:00
have any
want any
2022-10-02 02:07:40 +00:00
err string
decode bool
} {
{
desc : "ShouldDecodeRSACertificate" ,
have : x509CertificateRSA1 ,
2022-10-03 00:52:29 +00:00
want : MustParseX509Certificate ( x509CertificateRSA1 ) ,
2022-10-02 02:07:40 +00:00
decode : true ,
} ,
{
desc : "ShouldDecodeECDSACertificate" ,
have : x509CACertificateECDSA ,
2022-10-03 00:52:29 +00:00
want : MustParseX509Certificate ( x509CACertificateECDSA ) ,
2022-10-02 02:07:40 +00:00
decode : true ,
} ,
{
desc : "ShouldDecodeRSACACertificate" ,
have : x509CACertificateRSA ,
2022-10-03 00:52:29 +00:00
want : MustParseX509Certificate ( x509CACertificateRSA ) ,
2022-10-02 02:07:40 +00:00
decode : true ,
} ,
{
desc : "ShouldDecodeECDSACACertificate" ,
have : x509CACertificateECDSA ,
2022-10-03 00:52:29 +00:00
want : MustParseX509Certificate ( x509CACertificateECDSA ) ,
2022-10-02 02:07:40 +00:00
decode : true ,
} ,
{
desc : "ShouldDecodeEmptyCertificateToNil" ,
have : "" ,
want : nilkey ,
decode : true ,
} ,
{
desc : "ShouldNotDecodeECDSAKeyToCertificate" ,
have : x509PrivateKeyEC1 ,
want : nilkey ,
decode : true ,
err : "could not decode to a *x509.Certificate: the data is for a *ecdsa.PrivateKey not a *x509.Certificate" ,
} ,
{
desc : "ShouldNotDecodeBadRSAPrivateKeyToCertificate" ,
have : x509PrivateKeyRSA2 ,
want : nilkey ,
decode : true ,
err : "could not decode to a *x509.Certificate: failed to parse PEM block containing the key" ,
} ,
}
hook := configuration . StringToX509CertificateHookFunc ( )
for _ , tc := range testCases {
t . Run ( tc . desc , func ( t * testing . T ) {
result , err := hook ( reflect . TypeOf ( tc . have ) , reflect . TypeOf ( tc . want ) , tc . have )
switch {
case ! tc . decode :
assert . NoError ( t , err )
assert . Equal ( t , tc . have , result )
case tc . err == "" :
assert . NoError ( t , err )
require . Equal ( t , tc . want , result )
default :
assert . EqualError ( t , err , tc . err )
assert . Nil ( t , result )
}
} )
}
}
2023-05-31 10:50:22 +00:00
func TestStringToPasswordDigestHookFunc ( t * testing . T ) {
var nilvalue * schema . PasswordDigest
testCases := [ ] struct {
name string
have any
expected any
err string
decode bool
} {
{
"ShouldParse" ,
"$plaintext$example" ,
MustParsePasswordDigest ( "$plaintext$example" ) ,
"" ,
true ,
} ,
{
"ShouldParsePtr" ,
"$plaintext$example" ,
MustParsePasswordDigestPtr ( "$plaintext$example" ) ,
"" ,
true ,
} ,
{
"ShouldNotParseUnknown" ,
"$abc$example" ,
schema . PasswordDigest { } ,
"could not decode '$abc$example' to a schema.PasswordDigest: provided encoded hash has an invalid identifier: the identifier 'abc' is unknown to the decoder" ,
false ,
} ,
{
"ShouldNotParseWrongType" ,
"$abc$example" ,
schema . TLSVersion { } ,
"" ,
false ,
} ,
{
"ShouldNotParseWrongTypePtr" ,
"$abc$example" ,
& schema . TLSVersion { } ,
"" ,
false ,
} ,
{
"ShouldNotParseEmptyString" ,
"" ,
schema . PasswordDigest { } ,
"could not decode an empty value to a schema.PasswordDigest: must have a non-empty value" ,
false ,
} ,
{
"ShouldParseEmptyStringPtr" ,
"" ,
nilvalue ,
"" ,
true ,
} ,
}
hook := configuration . StringToPasswordDigestHookFunc ( )
for _ , tc := range testCases {
t . Run ( tc . name , func ( t * testing . T ) {
actual , err := hook ( reflect . TypeOf ( tc . have ) , reflect . TypeOf ( tc . expected ) , tc . have )
if tc . err != "" {
assert . EqualError ( t , err , tc . err )
if ! tc . decode {
assert . Nil ( t , actual )
}
} else {
assert . NoError ( t , err )
if tc . decode {
assert . Equal ( t , tc . expected , actual )
} else {
assert . Equal ( t , tc . have , actual )
}
}
} )
}
}
func TestStringToTLSVersionHookFunc ( t * testing . T ) {
testCases := [ ] struct {
name string
have any
expected any
err string
decode bool
} {
{
"ShouldParseTLS1.3" ,
"TLS1.3" ,
schema . TLSVersion { Value : tls . VersionTLS13 } ,
"" ,
true ,
} ,
{
"ShouldParseTLS1.3PTR" ,
"TLS1.3" ,
& schema . TLSVersion { Value : tls . VersionTLS13 } ,
"" ,
true ,
} ,
{
"ShouldParseTLS1.2" ,
"TLS1.2" ,
schema . TLSVersion { Value : tls . VersionTLS12 } ,
"" ,
true ,
} ,
{
"ShouldNotParseInt" ,
1 ,
& schema . TLSVersion { } ,
"" ,
false ,
} ,
{
"ShouldNotParseNonVersion" ,
"1" ,
& schema . TLSVersion { } ,
"could not decode '1' to a *schema.TLSVersion: supplied tls version isn't supported" ,
false ,
} ,
}
hook := configuration . StringToTLSVersionHookFunc ( )
for _ , tc := range testCases {
t . Run ( tc . name , func ( t * testing . T ) {
actual , err := hook ( reflect . TypeOf ( tc . have ) , reflect . TypeOf ( tc . expected ) , tc . have )
if tc . err != "" {
assert . EqualError ( t , err , tc . err )
if ! tc . decode {
assert . Nil ( t , actual )
}
} else {
assert . NoError ( t , err )
if tc . decode {
assert . Equal ( t , tc . expected , actual )
} else {
assert . Equal ( t , tc . have , actual )
}
}
} )
}
}
2022-10-02 02:07:40 +00:00
func TestStringToX509CertificateChainHookFunc ( t * testing . T ) {
var nilkey * schema . X509CertificateChain
testCases := [ ] struct {
desc string
2022-10-05 05:05:23 +00:00
have any
expected any
2022-10-02 02:07:40 +00:00
err , verr string
decode bool
} {
{
desc : "ShouldDecodeRSACertificate" ,
have : x509CertificateRSA1 ,
2022-10-03 00:52:29 +00:00
expected : MustParseX509CertificateChain ( x509CertificateRSA1 ) ,
2022-10-02 02:07:40 +00:00
decode : true ,
} ,
{
desc : "ShouldDecodeRSACertificateNoPtr" ,
have : x509CertificateRSA1 ,
2022-10-03 00:52:29 +00:00
expected : * MustParseX509CertificateChain ( x509CertificateRSA1 ) ,
2022-10-02 02:07:40 +00:00
decode : true ,
} ,
{
desc : "ShouldDecodeRSACertificateChain" ,
2022-10-03 00:52:29 +00:00
have : BuildChain ( x509CertificateRSA1 , x509CACertificateRSA ) ,
expected : MustParseX509CertificateChain ( x509CertificateRSA1 , x509CACertificateRSA ) ,
2022-10-02 02:07:40 +00:00
decode : true ,
} ,
{
desc : "ShouldDecodeRSACertificateChainNoPtr" ,
2022-10-03 00:52:29 +00:00
have : BuildChain ( x509CertificateRSA1 , x509CACertificateRSA ) ,
expected : * MustParseX509CertificateChain ( x509CertificateRSA1 , x509CACertificateRSA ) ,
2022-10-02 02:07:40 +00:00
decode : true ,
} ,
{
desc : "ShouldNotDecodeBadRSACertificateChain" ,
2022-10-03 00:52:29 +00:00
have : BuildChain ( x509CertificateRSA1 , x509CACertificateECDSA ) ,
expected : MustParseX509CertificateChain ( x509CertificateRSA1 , x509CACertificateECDSA ) ,
2022-10-02 02:07:40 +00:00
verr : "certificate #1 in chain is not signed properly by certificate #2 in chain: x509: signature algorithm specifies an RSA public key, but have public key of type *ecdsa.PublicKey" ,
decode : true ,
} ,
{
desc : "ShouldDecodeECDSACertificate" ,
have : x509CACertificateECDSA ,
2022-10-03 00:52:29 +00:00
expected : MustParseX509CertificateChain ( x509CACertificateECDSA ) ,
2022-10-02 02:07:40 +00:00
decode : true ,
} ,
{
desc : "ShouldDecodeRSACACertificate" ,
have : x509CACertificateRSA ,
2022-10-03 00:52:29 +00:00
expected : MustParseX509CertificateChain ( x509CACertificateRSA ) ,
2022-10-02 02:07:40 +00:00
decode : true ,
} ,
{
desc : "ShouldDecodeECDSACACertificate" ,
have : x509CACertificateECDSA ,
2022-10-03 00:52:29 +00:00
expected : MustParseX509CertificateChain ( x509CACertificateECDSA ) ,
2022-10-02 02:07:40 +00:00
decode : true ,
} ,
{
desc : "ShouldDecodeEmptyCertificateToNil" ,
have : "" ,
expected : nilkey ,
decode : true ,
} ,
{
desc : "ShouldDecodeEmptyCertificateToEmptyStruct" ,
have : "" ,
expected : schema . X509CertificateChain { } ,
decode : true ,
} ,
{
desc : "ShouldNotDecodeECDSAKeyToCertificate" ,
have : x509PrivateKeyEC1 ,
expected : nilkey ,
decode : true ,
err : "could not decode to a *schema.X509CertificateChain: the PEM data chain contains a EC PRIVATE KEY but only certificates are expected" ,
} ,
{
desc : "ShouldNotDecodeBadRSAPrivateKeyToCertificate" ,
have : x509PrivateKeyRSA2 ,
expected : nilkey ,
decode : true ,
err : "could not decode to a *schema.X509CertificateChain: invalid PEM block" ,
} ,
}
hook := configuration . StringToX509CertificateChainHookFunc ( )
for _ , tc := range testCases {
t . Run ( tc . desc , func ( t * testing . T ) {
actual , err := hook ( reflect . TypeOf ( tc . have ) , reflect . TypeOf ( tc . expected ) , tc . have )
switch {
case ! tc . decode :
assert . NoError ( t , err )
assert . Equal ( t , tc . have , actual )
case tc . err == "" :
assert . NoError ( t , err )
require . Equal ( t , tc . expected , actual )
if tc . expected == nilkey {
break
}
switch chain := actual . ( type ) {
case * schema . X509CertificateChain :
require . NotNil ( t , chain )
if tc . verr == "" {
assert . NoError ( t , chain . Validate ( ) )
} else {
assert . EqualError ( t , chain . Validate ( ) , tc . verr )
}
case schema . X509CertificateChain :
require . NotNil ( t , chain )
if tc . verr == "" {
assert . NoError ( t , chain . Validate ( ) )
} else {
assert . EqualError ( t , chain . Validate ( ) , tc . verr )
}
}
default :
assert . EqualError ( t , err , tc . err )
assert . Nil ( t , actual )
}
} )
}
}
var (
x509PrivateKeyRSA1 = `
-- -- - BEGIN RSA PRIVATE KEY -- -- -
MIIEpAIBAAKCAQEA6z1LOg1ZCqb0lytXWZ + MRBpMHEXOoTOLYgfZXt1IYyE3Z758
cyalk0NYQhY5cZDsXPYWPvAHiPMUxutWkoxFwby56S + AbIMa3 / Is + ILrHRJs8Exn
ZkpyrYFxPX12app2kErdmAkHSx0Z5 / kuXiz96PHs8S8 / ZbyZolLHzdfLtSzjvRm5
Zue5iFzsf19NJz5CIBfv8g5lRwtE8wNJoRSpn1xq7fqfuA0weDNFPzjlNWRLy6aa
rK7qJexRkmkCs4sLgyl + 9 NODYJpvmN8E1yhyC27E0joI6rBFVW7Ihv + cSPCdDzGp
EWe81x3AeqAa3mjVqkiq4u4Z2i8JDgBaPboqJwIDAQABAoIBAAFdLZ58jVOefDSU
L8F5R1rtvBs93GDa56f926jNJ6pLewLC + / 2 + 757 W + SAI + PRLntM7Kg3bXm / Q2QH +
Q1Y + MflZmspbWCdI61L5GIGoYKyeers59i + FpvySj5GHtLQRiTZ0 + Kv1AXHSDWBm
9 XneUOqU3IbZe0ifu1RRno72 / VtjkGXbW8Mkkw + ohyGbIeTx / 0 / JQ6sSNZTT3Vk7
8i 4 IXptq3HSF0 / vqZuah8rShoeNq72pD1YLM9YPdL5by1QkDLnqATDiCpLBTCaNV
I8sqYEun + HYbQzBj8ZACG2JVZpEEidONWQHw5BPWO95DSZYrVnEkuCqeH + u5vYt7
CHuJ3AECgYEA + W3v5z + j91w1VPHS0VB3SCDMouycAMIUnJPAbt + 0 LPP0scUFsBGE
hPAKddC54pmMZRQ2KIwBKiyWfCrJ8Xz8Yogn7fJgmwTHidJBr2WQpIEkNGlK3Dzi
jXL2sh0yC7sHvn0DqiQ79l / e7yRbSnv2wrTJEczOOH2haD7 / tBRyCYECgYEA8W + q
E9YyGvEltnPFaOxofNZ8LHVcZSsQI5b6fc0iE7fjxFqeXPXEwGSOTwqQLQRiHn9b
CfPmIG4Vhyq0otVmlPvUnfBZ2OK + tl5X2 / mQFO3ROMdvpi0KYa994uqfJdSTaqLn
jjoKFB906UFHnDQDLZUNiV1WwnkTglgLc + xrd6cCgYEAqqthyv6NyBTM3Tm2gcio
Ra9Dtntl51LlXZnvwy3IkDXBCd6BHM9vuLKyxZiziGx + Vy90O1xI872cnot8sINQ
Am + dur / tAEVN72zxyv0Y8qb2yfH96iKy9gxi5s75TnOEQgAygLnYWaWR2lorKRUX
bHTdXBOiS58S0UzCFEslGIECgYBqkO4SKWYeTDhoKvuEj2yjRYyzlu28XeCWxOo1
otiauX0YSyNBRt2cSgYiTzhKFng0m + QUJYp63 / wymB / 5 C5Zmxi0XtWIDADpLhqLj
HmmBQ2Mo26alQ5YkffBju0mZyhVzaQop1eZi8WuKFV1FThPlB7hc3E0SM5zv2Grd
tQnOWwKBgQC40yZY0PcjuILhy + sIc0Wvh7LUA7taSdTye149kRvbvsCDN7Jh75lM
USjhLXY0Nld2zBm9r8wMb81mXH29uvD + tDqqsICvyuKlA / tyzXR + QTr7dCVKVwu0
1 YjCJ36UpTsLre2f8nOSLtNmRfDPtbOE2mkOoO9dD9UU0XZwnvn9xw ==
-- -- - END RSA PRIVATE KEY -- -- - `
x509PrivateKeyRSA2 = `
-- -- - BEGIN RSA PRIVATE KEY -- -- -
bad key
-- -- - END RSA PRIVATE KEY -- -- - `
x509PrivateKeyEC1 = `
-- -- - BEGIN EC PRIVATE KEY -- -- -
MHcCAQEEIMn970LSn8aKVhBM4vyUmpZyEdCT4riN + Lp4QU04zUhYoAoGCCqGSM49
AwEHoUQDQgAEMD69n22nd78GmaRDzy / s7muqhbc / OEnFS2mNtiRAA5FaX + kbkCB5
8 pu / k2jkaSVNZtBYKPVAibHkhvakjVb66A ==
2022-10-03 00:52:29 +00:00
-- -- - END EC PRIVATE KEY -- -- - `
x509PrivateKeyEC2 = `
-- -- - BEGIN EC PRIVATE KEY -- -- -
bad key
2022-10-02 02:07:40 +00:00
-- -- - END EC PRIVATE KEY -- -- - `
x509CertificateRSA1 = `
-- -- - BEGIN CERTIFICATE -- -- -
MIIC5TCCAc2gAwIBAgIQfBUmKLmEvMqS6S9auKCY2DANBgkqhkiG9w0BAQsFADAT
MREwDwYDVQQKEwhBdXRoZWxpYTAeFw0yMjA5MDgxMDA5MThaFw0yMzA5MDgxMDA5
MThaMBMxETAPBgNVBAoTCEF1dGhlbGlhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
MIIBCgKCAQEApqno1cOpDcgKmOJqeDQGIGH5 / ZnqcJ4xud6eOUfbDqel3b0RkAQX
mFYWEDO / PDOAOjYk / xSwZGo3jDofOHGhrKstQqLdweHGfme5NXYHJda7nGv / OY5q
zUuEG4xBVgUsvbshWZ18H + bIQpwiP6tDAabxc0B7J15F1pArK8QN4pDTfsqZDwMi
Qyo638XfUbDzEVZRbdDKxHz5g0w2vFdXon8uOxRRb0 + zlHF9nM4PiESNgiUIYeua
8 Q5yP10SY2k9zlQ / OFJ4XhQmioCJvNjJE / TSc5 / ECub2n7hTZhN5TGKagukZ5NAy
KgbvNYW + CN + H4pFJt / 9 WptiDfBqhlUvjnwIDAQABozUwMzAOBgNVHQ8BAf8EBAMC
BaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH / BAIwADANBgkqhkiG9w0B
AQsFAAOCAQEAH9veGzfWqXxsa5s2KHV2Jzed9V8KSs1Qy9QKRez1i2OMvMPh2DRM
RLzAAp / XigjxLQF / LFXuoFW0Qg8BRb44iRgZrCiqVOUnd3xTrS / CcFExnpQI4F12
/ U70o97rkTonCOHmUUW6vQfWSXR / GU3 / faRLJjiqcpWLZhTQNrnsip1ym3B2NMdk
gMKkT8Acx1DX48MvTE4 + DyqCS8TlJbacBJ2RFFELKu3jYnVNyrb0ywLxoCtWqBBE
veVj + VMn9hNY1u5uydLsUDOlT5QyQcEuUzjjdhsJKEgDE5daNtB2OJJnd9IOMzUA
hasPZETCCKabTpWiEPw1Cn / ZRqya0SZqFg ==
-- -- - END CERTIFICATE -- -- -
`
x509CACertificateRSA = `
-- -- - BEGIN CERTIFICATE -- -- -
MIIDBDCCAeygAwIBAgIRAJfz0dHS9UkDngE55lUPdu4wDQYJKoZIhvcNAQELBQAw
EzERMA8GA1UEChMIQXV0aGVsaWEwHhcNMjIwOTA4MDk1OTI1WhcNMjMwOTA4MDk1
OTI1WjATMREwDwYDVQQKEwhBdXRoZWxpYTCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBALfivbwq9r5X8N + NSbNHVuKbCb9f9vD5Xw2pOjSVvVjFkWQ1YKJu
JGx9yskhHBZTBt76cInipA + 0 PqCBrBrjij1lh2StvzRVuQwgFG6H01LxBPi0JyYv
Is94F6PHr6fSBgFWB5GNQ797KQIOdIr057uEFbp0eBMxxqiQ9gdyD0HPretrx1Uy
kHuF6jck958combn9luHW0i53mt8706j7UAhxFqu9YUeklTM1VqUiRm5 + nJKIdNA
LiDMGVAuoxjhF6aIgY0yh5mL5mKtYYzhtA8WryrMzBgFRUGzHCSI1TNisA8wSf2T
Z2JhbFHrFPR5fiSqAEHok3UXu ++ wsfl / lisCAwEAAaNTMFEwDgYDVR0PAQH / BAQD
AgKkMA8GA1UdJQQIMAYGBFUdJQAwDwYDVR0TAQH / BAUwAwEB / zAdBgNVHQ4EFgQU
OSXG42bCPNuWeP0ahScUMVjxe / wwDQYJKoZIhvcNAQELBQADggEBAFRnubHiYy1H
PGODKA ++ UY9eAmmaCJxzuWpY8FY9fBz8 / VBzcp8vaURPmmQ / 34 QcqfaSHDM2jIaL
dQ2o9Ae5NjbRzLB6a5DcVO50oHG4BHP1ix4Bt3POr8J80KgA9pOIyAQqbAlFBSzQ
l9yrzVULyf + qpUmByRf5qy2kQJOBfMJbn5j + BprWKwbcI8OAZWWSLItTXqJDrFTk
OMZK4wZ6KiZM07KWMlwW / CE0QRzDk5MXfbwRt4D8pyx6rGKqI7QRusjm5osIpHZV
26 FdBdBvEhq4i8UsmDsQqH3iMY1AKmojZToZb5rStOZWHO / BZZ7nT2bscNjwm0E8
6E2 l6czk8ss =
-- -- - END CERTIFICATE -- -- - `
x509CACertificateECDSA = `
-- -- - BEGIN CERTIFICATE -- -- -
MIIBdzCCAR2gAwIBAgIQUzb62irYb / 7 B2H0c1AbriDAKBggqhkjOPQQDAjATMREw
DwYDVQQKEwhBdXRoZWxpYTAeFw0yMjA5MDgxMDEzNDZaFw0yMzA5MDgxMDEzNDZa
MBMxETAPBgNVBAoTCEF1dGhlbGlhMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE
b / EiIBpmifCI34JdI7luetygue2rTtoNH0QXhtrjMuZNugT29LUz + DobZQxvGsOY
4 TXzAQXq4gnTb7enNWFgsaNTMFEwDgYDVR0PAQH / BAQDAgKkMA8GA1UdJQQIMAYG
BFUdJQAwDwYDVR0TAQH / BAUwAwEB / zAdBgNVHQ4EFgQUxlDPBKHKawuvhtQTN874
TeCEKjkwCgYIKoZIzj0EAwIDSAAwRQIgAQeV01FZ / VkSERwaRKTeXAXxmKyc / 05 O
uDv6M2spMi0CIQC8uOSMcv11vp1ylsGg38N6XYA + GQa1BHRd79 + 91 hC + 7 w ==
-- -- - END CERTIFICATE -- -- - `
)
2022-10-03 00:52:29 +00:00
func MustParseRSAPrivateKey ( data string ) * rsa . PrivateKey {
2022-10-02 02:07:40 +00:00
block , _ := pem . Decode ( [ ] byte ( data ) )
if block == nil || block . Bytes == nil || len ( block . Bytes ) == 0 {
panic ( "not pem encoded" )
}
if block . Type != "RSA PRIVATE KEY" {
2022-10-03 00:52:29 +00:00
panic ( "not rsa private key" )
2022-10-02 02:07:40 +00:00
}
key , err := x509 . ParsePKCS1PrivateKey ( block . Bytes )
if err != nil {
panic ( err )
}
return key
}
2022-10-03 00:52:29 +00:00
func MustParseECDSAPrivateKey ( data string ) * ecdsa . PrivateKey {
block , _ := pem . Decode ( [ ] byte ( data ) )
if block == nil || block . Bytes == nil || len ( block . Bytes ) == 0 {
panic ( "not pem encoded" )
}
if block . Type != "EC PRIVATE KEY" {
panic ( "not ecdsa private key" )
}
key , err := x509 . ParseECPrivateKey ( block . Bytes )
if err != nil {
panic ( err )
}
return key
}
func MustParseX509Certificate ( data string ) * x509 . Certificate {
2022-10-02 02:07:40 +00:00
block , _ := pem . Decode ( [ ] byte ( data ) )
if block == nil || len ( block . Bytes ) == 0 {
panic ( "not a PEM" )
}
cert , err := x509 . ParseCertificate ( block . Bytes )
if err != nil {
panic ( err )
}
return cert
}
2022-10-03 00:52:29 +00:00
func BuildChain ( pems ... string ) string {
2022-10-02 02:07:40 +00:00
buf := bytes . Buffer { }
for i , data := range pems {
if i != 0 {
buf . WriteString ( "\n" )
}
buf . WriteString ( data )
}
return buf . String ( )
}
2022-10-03 00:52:29 +00:00
func MustParseX509CertificateChain ( datas ... string ) * schema . X509CertificateChain {
chain , err := schema . NewX509CertificateChain ( BuildChain ( datas ... ) )
2022-10-02 02:07:40 +00:00
if err != nil {
panic ( err )
}
return chain
}
2022-04-03 12:44:52 +00:00
func testInt32Ptr ( i int32 ) * int32 {
return & i
}
func testTimeDurationPtr ( t time . Duration ) * time . Duration {
return & t
}
var (
testTrue = true
testZero int32
testString = ""
)
2023-05-31 10:50:22 +00:00
func MustParseAddress ( input string ) schema . Address {
address , err := schema . NewAddress ( input )
if err != nil {
panic ( err )
}
fmt . Println ( address . String ( ) )
addr := * address
return addr
}
func MustParseAddressPtr ( input string ) * schema . Address {
address , err := schema . NewAddress ( input )
if err != nil {
panic ( err )
}
return address
}
func MustParsePasswordDigest ( input string ) schema . PasswordDigest {
digest , err := schema . DecodePasswordDigest ( input )
if err != nil {
panic ( err )
}
return * digest
}
func MustParsePasswordDigestPtr ( input string ) * schema . PasswordDigest {
digest , err := schema . DecodePasswordDigest ( input )
if err != nil {
panic ( err )
}
return digest
}