@@ -37,6 +37,7 @@ import (
37
37
"github.com/coder/coder/coderd/database/postgres"
38
38
"github.com/coder/coder/coderd/telemetry"
39
39
"github.com/coder/coder/codersdk"
40
+ "github.com/coder/coder/cryptorand"
40
41
"github.com/coder/coder/pty/ptytest"
41
42
"github.com/coder/coder/testutil"
42
43
)
@@ -1016,6 +1017,166 @@ func TestServer(t *testing.T) {
1016
1017
require .True (t , strings .HasPrefix (fakeURL .String (), fakeRedirect ), fakeURL .String ())
1017
1018
})
1018
1019
1020
+ t .Run ("OIDC" , func (t * testing.T ) {
1021
+ t .Parallel ()
1022
+
1023
+ t .Run ("Defaults" , func (t * testing.T ) {
1024
+ t .Parallel ()
1025
+ ctx , cancel := context .WithTimeout (context .Background (), testutil .WaitMedium )
1026
+ defer cancel ()
1027
+
1028
+ // Startup a fake server that just responds to .well-known/openid-configuration
1029
+ // This is just needed to get Coder to start up.
1030
+ oidcServer := httptest .NewServer (nil )
1031
+ fakeWellKnownHandler := func (w http.ResponseWriter , r * http.Request ) {
1032
+ w .Header ().Set ("Content-Type" , "application/json" )
1033
+ payload := fmt .Sprintf ("{\" issuer\" : %q}" , oidcServer .URL )
1034
+ _ , _ = w .Write ([]byte (payload ))
1035
+ }
1036
+ oidcServer .Config .Handler = http .HandlerFunc (fakeWellKnownHandler )
1037
+ t .Cleanup (oidcServer .Close )
1038
+
1039
+ inv , cfg := clitest .New (t ,
1040
+ "server" ,
1041
+ "--in-memory" ,
1042
+ "--http-address" , ":0" ,
1043
+ "--access-url" , "http://example.com" ,
1044
+ "--oidc-client-id" , "fake" ,
1045
+ "--oidc-client-secret" , "fake" ,
1046
+ "--oidc-issuer-url" , oidcServer .URL ,
1047
+ // Leaving the rest of the flags as defaults.
1048
+ )
1049
+
1050
+ // Ensure that the server starts up without error.
1051
+ clitest .Start (t , inv )
1052
+ accessURL := waitAccessURL (t , cfg )
1053
+ client := codersdk .New (accessURL )
1054
+
1055
+ randPassword , err := cryptorand .String (24 )
1056
+ require .NoError (t , err )
1057
+
1058
+ _ , err = client .CreateFirstUser (ctx , codersdk.CreateFirstUserRequest {
1059
+ Email : "admin@coder.com" ,
1060
+ Password : randPassword ,
1061
+ Username : "admin" ,
1062
+ Trial : true ,
1063
+ })
1064
+ require .NoError (t , err )
1065
+
1066
+ loginResp , err := client .LoginWithPassword (ctx , codersdk.LoginWithPasswordRequest {
1067
+ Email : "admin@coder.com" ,
1068
+ Password : randPassword ,
1069
+ })
1070
+ require .NoError (t , err )
1071
+ client .SetSessionToken (loginResp .SessionToken )
1072
+
1073
+ deploymentConfig , err := client .DeploymentConfig (ctx )
1074
+ require .NoError (t , err )
1075
+
1076
+ // Ensure that the OIDC provider is configured correctly.
1077
+ require .Equal (t , "fake" , deploymentConfig .Values .OIDC .ClientID .Value ())
1078
+ // The client secret is not returned from the API.
1079
+ require .Empty (t , deploymentConfig .Values .OIDC .ClientSecret .Value ())
1080
+ require .Equal (t , oidcServer .URL , deploymentConfig .Values .OIDC .IssuerURL .Value ())
1081
+ // These are the default values returned from the API. See codersdk/deployment.go for the default values.
1082
+ require .True (t , deploymentConfig .Values .OIDC .AllowSignups .Value ())
1083
+ require .Empty (t , deploymentConfig .Values .OIDC .EmailDomain .Value ())
1084
+ require .Equal (t , []string {"openid" , "profile" , "email" }, deploymentConfig .Values .OIDC .Scopes .Value ())
1085
+ require .False (t , deploymentConfig .Values .OIDC .IgnoreEmailVerified .Value ())
1086
+ require .Equal (t , "preferred_username" , deploymentConfig .Values .OIDC .UsernameField .Value ())
1087
+ require .Equal (t , "email" , deploymentConfig .Values .OIDC .EmailField .Value ())
1088
+ require .Equal (t , map [string ]string {"access_type" : "offline" }, deploymentConfig .Values .OIDC .AuthURLParams .Value )
1089
+ require .Empty (t , deploymentConfig .Values .OIDC .GroupField .Value ())
1090
+ require .Empty (t , deploymentConfig .Values .OIDC .GroupMapping .Value )
1091
+ require .Equal (t , "OpenID Connect" , deploymentConfig .Values .OIDC .SignInText .Value ())
1092
+ require .Empty (t , deploymentConfig .Values .OIDC .IconURL .Value ())
1093
+ })
1094
+
1095
+ t .Run ("Overrides" , func (t * testing.T ) {
1096
+ t .Parallel ()
1097
+
1098
+ ctx , cancel := context .WithTimeout (context .Background (), testutil .WaitMedium )
1099
+ defer cancel ()
1100
+
1101
+ // Startup a fake server that just responds to .well-known/openid-configuration
1102
+ // This is just needed to get Coder to start up.
1103
+ oidcServer := httptest .NewServer (nil )
1104
+ fakeWellKnownHandler := func (w http.ResponseWriter , r * http.Request ) {
1105
+ w .Header ().Set ("Content-Type" , "application/json" )
1106
+ payload := fmt .Sprintf ("{\" issuer\" : %q}" , oidcServer .URL )
1107
+ _ , _ = w .Write ([]byte (payload ))
1108
+ }
1109
+ oidcServer .Config .Handler = http .HandlerFunc (fakeWellKnownHandler )
1110
+ t .Cleanup (oidcServer .Close )
1111
+
1112
+ inv , cfg := clitest .New (t ,
1113
+ "server" ,
1114
+ "--in-memory" ,
1115
+ "--http-address" , ":0" ,
1116
+ "--access-url" , "http://example.com" ,
1117
+ "--oidc-client-id" , "fake" ,
1118
+ "--oidc-client-secret" , "fake" ,
1119
+ "--oidc-issuer-url" , oidcServer .URL ,
1120
+ // The following values have defaults that we want to override.
1121
+ "--oidc-allow-signups=false" ,
1122
+ "--oidc-email-domain" , "example.com" ,
1123
+ "--oidc-scopes" , "360noscope" ,
1124
+ "--oidc-ignore-email-verified" ,
1125
+ "--oidc-username-field" , "not_preferred_username" ,
1126
+ "--oidc-email-field" , "not_email" ,
1127
+ "--oidc-auth-url-params" , `{"prompt":"consent"}` ,
1128
+ "--oidc-group-field" , "serious_business_unit" ,
1129
+ "--oidc-group-mapping" , `{"serious_business_unit": "serious_business_unit"}` ,
1130
+ "--oidc-sign-in-text" , "Sign In With Coder" ,
1131
+ "--oidc-icon-url" , "https://example.com/icon.png" ,
1132
+ )
1133
+
1134
+ // Ensure that the server starts up without error.
1135
+ clitest .Start (t , inv )
1136
+ accessURL := waitAccessURL (t , cfg )
1137
+ client := codersdk .New (accessURL )
1138
+
1139
+ randPassword , err := cryptorand .String (24 )
1140
+ require .NoError (t , err )
1141
+
1142
+ _ , err = client .CreateFirstUser (ctx , codersdk.CreateFirstUserRequest {
1143
+ Email : "admin@coder.com" ,
1144
+ Password : randPassword ,
1145
+ Username : "admin" ,
1146
+ Trial : true ,
1147
+ })
1148
+ require .NoError (t , err )
1149
+
1150
+ loginResp , err := client .LoginWithPassword (ctx , codersdk.LoginWithPasswordRequest {
1151
+ Email : "admin@coder.com" ,
1152
+ Password : randPassword ,
1153
+ })
1154
+ require .NoError (t , err )
1155
+ client .SetSessionToken (loginResp .SessionToken )
1156
+
1157
+ deploymentConfig , err := client .DeploymentConfig (ctx )
1158
+ require .NoError (t , err )
1159
+
1160
+ // Ensure that the OIDC provider is configured correctly.
1161
+ require .Equal (t , "fake" , deploymentConfig .Values .OIDC .ClientID .Value ())
1162
+ // The client secret is not returned from the API.
1163
+ require .Empty (t , deploymentConfig .Values .OIDC .ClientSecret .Value ())
1164
+ require .Equal (t , oidcServer .URL , deploymentConfig .Values .OIDC .IssuerURL .Value ())
1165
+ // These are values that we want to make sure were overridden.
1166
+ require .False (t , deploymentConfig .Values .OIDC .AllowSignups .Value ())
1167
+ require .Equal (t , []string {"example.com" }, deploymentConfig .Values .OIDC .EmailDomain .Value ())
1168
+ require .Equal (t , []string {"360noscope" }, deploymentConfig .Values .OIDC .Scopes .Value ())
1169
+ require .True (t , deploymentConfig .Values .OIDC .IgnoreEmailVerified .Value ())
1170
+ require .Equal (t , "not_preferred_username" , deploymentConfig .Values .OIDC .UsernameField .Value ())
1171
+ require .Equal (t , "not_email" , deploymentConfig .Values .OIDC .EmailField .Value ())
1172
+ require .Equal (t , map [string ]string {"access_type" : "offline" , "prompt" : "consent" }, deploymentConfig .Values .OIDC .AuthURLParams .Value )
1173
+ require .Equal (t , "serious_business_unit" , deploymentConfig .Values .OIDC .GroupField .Value ())
1174
+ require .Equal (t , map [string ]string {"serious_business_unit" : "serious_business_unit" }, deploymentConfig .Values .OIDC .GroupMapping .Value )
1175
+ require .Equal (t , "Sign In With Coder" , deploymentConfig .Values .OIDC .SignInText .Value ())
1176
+ require .Equal (t , "https://example.com/icon.png" , deploymentConfig .Values .OIDC .IconURL .Value ().String ())
1177
+ })
1178
+ })
1179
+
1019
1180
t .Run ("RateLimit" , func (t * testing.T ) {
1020
1181
t .Parallel ()
1021
1182
0 commit comments