Skip to content

Commit

Permalink
Use lowercase usernames in SelectBroker
Browse files Browse the repository at this point in the history
  • Loading branch information
adombeck committed Jan 15, 2025
1 parent 41e992b commit b218326
Show file tree
Hide file tree
Showing 19 changed files with 132 additions and 128 deletions.
82 changes: 41 additions & 41 deletions internal/brokers/broker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,13 @@ func TestGetAuthenticationModes(t *testing.T) {
"Get authentication modes and generate validators": {sessionID: "success", supportedUILayouts: []string{"required-entry", "optional-entry"}},
"Get authentication modes and generate validator ignoring whitespaces in supported values": {sessionID: "success", supportedUILayouts: []string{"layout-with-spaces"}},
"Get authentication modes and ignores invalid UI layout": {sessionID: "success", supportedUILayouts: []string{"required-entry", "missing-type"}},
"Get multiple authentication modes and generate validators": {sessionID: "GAM_multiple_modes", supportedUILayouts: []string{"required-entry", "optional-entry"}},
"Get multiple authentication modes and generate validators": {sessionID: "gam_multiple_modes", supportedUILayouts: []string{"required-entry", "optional-entry"}},

"Does not error out when no authentication modes are returned": {sessionID: "GAM_empty"},
"Does not error out when no authentication modes are returned": {sessionID: "gam_empty"},

// broker errors
"Error when getting authentication modes": {sessionID: "GAM_error", wantErr: true},
"Error when broker returns invalid modes": {sessionID: "GAM_invalid", wantErr: true},
"Error when getting authentication modes": {sessionID: "gam_error", wantErr: true},
"Error when broker returns invalid modes": {sessionID: "gam_invalid", wantErr: true},
}
for name, tc := range tests {
t.Run(name, func(t *testing.T) {
Expand Down Expand Up @@ -153,23 +153,23 @@ func TestSelectAuthenticationMode(t *testing.T) {

wantErr bool
}{
"Successfully select mode with required value": {sessionID: "SAM_success_required_entry"},
"Successfully select mode with optional value": {sessionID: "SAM_success_optional_entry", supportedUILayouts: []string{"optional-entry"}},
"Successfully select mode with missing optional value": {sessionID: "SAM_missing_optional_entry", supportedUILayouts: []string{"optional-entry"}},
"Successfully select mode with required value": {sessionID: "sam_success_required_entry"},
"Successfully select mode with optional value": {sessionID: "sam_success_optional_entry", supportedUILayouts: []string{"optional-entry"}},
"Successfully select mode with missing optional value": {sessionID: "sam_missing_optional_entry", supportedUILayouts: []string{"optional-entry"}},

// broker errors
"Error when selecting invalid auth mode": {sessionID: "SAM_error", wantErr: true},
"Error when selecting invalid auth mode": {sessionID: "sam_error", wantErr: true},
"Error when no validators were generated for session": {sessionID: "no-validators", wantErr: true},

/* Layout errors */
"Error when returns no layout": {sessionID: "SAM_no_layout", wantErr: true},
"Error when returns empty layout": {sessionID: "SAM_empty_layout", wantErr: true},
"Error when returns layout with no type": {sessionID: "SAM_no_layout_type", wantErr: true},
"Error when returns layout with invalid type": {sessionID: "SAM_invalid_layout_type", wantErr: true},
"Error when returns layout without required value": {sessionID: "SAM_missing_required_entry", wantErr: true},
"Error when returns layout with unknown field": {sessionID: "SAM_unknown_field", wantErr: true},
"Error when returns layout with invalid required value": {sessionID: "SAM_invalid_required_entry", wantErr: true},
"Error when returns layout with invalid optional value": {sessionID: "SAM_invalid_optional_entry", wantErr: true},
"Error when returns no layout": {sessionID: "sam_no_layout", wantErr: true},
"Error when returns empty layout": {sessionID: "sam_empty_layout", wantErr: true},
"Error when returns layout with no type": {sessionID: "sam_no_layout_type", wantErr: true},
"Error when returns layout with invalid type": {sessionID: "sam_invalid_layout_type", wantErr: true},
"Error when returns layout without required value": {sessionID: "sam_missing_required_entry", wantErr: true},
"Error when returns layout with unknown field": {sessionID: "sam_unknown_field", wantErr: true},
"Error when returns layout with invalid required value": {sessionID: "sam_invalid_required_entry", wantErr: true},
"Error when returns layout with invalid optional value": {sessionID: "sam_invalid_optional_entry", wantErr: true},
}
for name, tc := range tests {
t.Run(name, func(t *testing.T) {
Expand Down Expand Up @@ -213,30 +213,30 @@ func TestIsAuthenticated(t *testing.T) {
cancelFirstCall bool
}{
"Successfully authenticate": {sessionID: "success"},
"Successfully authenticate after cancelling first call": {sessionID: "IA_second_call", secondCall: true},
"Denies authentication when broker times out": {sessionID: "IA_timeout"},
"Adds default groups even if broker did not set them": {sessionID: "IA_info_empty_groups"},
"No error when auth.Next and no data": {sessionID: "IA_next"},
"No error when broker returns userinfo with empty gecos": {sessionID: "IA_info_empty_gecos"},
"No error when broker returns userinfo with group with empty UGID": {sessionID: "IA_info_empty_ugid"},
"No error when broker returns userinfo with mismatching username": {sessionID: "IA_info_mismatching_user_name"},
"Successfully authenticate after cancelling first call": {sessionID: "ia_second_call", secondCall: true},
"Denies authentication when broker times out": {sessionID: "ia_timeout"},
"Adds default groups even if broker did not set them": {sessionID: "ia_info_empty_groups"},
"No error when auth.Next and no data": {sessionID: "ia_next"},
"No error when broker returns userinfo with empty gecos": {sessionID: "ia_info_empty_gecos"},
"No error when broker returns userinfo with group with empty UGID": {sessionID: "ia_info_empty_ugid"},
"No error when broker returns userinfo with mismatching username": {sessionID: "ia_info_mismatching_user_name"},

// broker errors
"Error when authenticating": {sessionID: "IA_error"},
"Error on empty data even if granted": {sessionID: "IA_empty_data"},
"Error when broker returns invalid data": {sessionID: "IA_invalid_data"},
"Error when broker returns invalid access": {sessionID: "IA_invalid_access"},
"Error when broker returns invalid userinfo": {sessionID: "IA_invalid_userinfo"},
"Error when broker returns userinfo with empty username": {sessionID: "IA_info_empty_user_name"},
"Error when broker returns userinfo with empty group name": {sessionID: "IA_info_empty_group_name"},
"Error when broker returns userinfo with empty UUID": {sessionID: "IA_info_empty_uuid"},
"Error when broker returns userinfo with invalid homedir": {sessionID: "IA_info_invalid_home"},
"Error when broker returns userinfo with invalid shell": {sessionID: "IA_info_invalid_shell"},
"Error when broker returns data on auth.Next": {sessionID: "IA_next_with_data"},
"Error when broker returns data on auth.Cancelled": {sessionID: "IA_cancelled_with_data"},
"Error when broker returns no data on auth.Denied": {sessionID: "IA_denied_without_data"},
"Error when broker returns no data on auth.Retry": {sessionID: "IA_retry_without_data"},
"Error when calling IsAuthenticated a second time without cancelling": {sessionID: "IA_second_call", secondCall: true, cancelFirstCall: true},
"Error when authenticating": {sessionID: "ia_error"},
"Error on empty data even if granted": {sessionID: "ia_empty_data"},
"Error when broker returns invalid data": {sessionID: "ia_invalid_data"},
"Error when broker returns invalid access": {sessionID: "ia_invalid_access"},
"Error when broker returns invalid userinfo": {sessionID: "ia_invalid_userinfo"},
"Error when broker returns userinfo with empty username": {sessionID: "ia_info_empty_user_name"},
"Error when broker returns userinfo with empty group name": {sessionID: "ia_info_empty_group_name"},
"Error when broker returns userinfo with empty UUID": {sessionID: "ia_info_empty_uuid"},
"Error when broker returns userinfo with invalid homedir": {sessionID: "ia_info_invalid_home"},
"Error when broker returns userinfo with invalid shell": {sessionID: "ia_info_invalid_shell"},
"Error when broker returns data on auth.Next": {sessionID: "ia_next_with_data"},
"Error when broker returns data on auth.Cancelled": {sessionID: "ia_cancelled_with_data"},
"Error when broker returns no data on auth.Denied": {sessionID: "ia_denied_without_data"},
"Error when broker returns no data on auth.Retry": {sessionID: "ia_retry_without_data"},
"Error when calling IsAuthenticated a second time without cancelling": {sessionID: "ia_second_call", secondCall: true, cancelFirstCall: true},
}
for name, tc := range tests {
t.Run(name, func(t *testing.T) {
Expand Down Expand Up @@ -289,8 +289,8 @@ func TestCancelIsAuthenticated(t *testing.T) {

wantAnswer string
}{
"Successfully cancels IsAuthenticated": {sessionID: "IA_wait", wantAnswer: auth.Cancelled},
"Call returns denied if not cancelled": {sessionID: "IA_timeout", wantAnswer: auth.Denied},
"Successfully cancels IsAuthenticated": {sessionID: "ia_wait", wantAnswer: auth.Cancelled},
"Call returns denied if not cancelled": {sessionID: "ia_timeout", wantAnswer: auth.Denied},
}
for name, tc := range tests {
t.Run(name, func(t *testing.T) {
Expand All @@ -305,7 +305,7 @@ func TestCancelIsAuthenticated(t *testing.T) {
}()
defer cancel()

if tc.sessionID == "IA_wait" {
if tc.sessionID == "ia_wait" {
// Give some time for the IsAuthenticated routine to start.
time.Sleep(time.Second)
cancel()
Expand Down
4 changes: 2 additions & 2 deletions internal/brokers/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,8 @@ func TestNewSession(t *testing.T) {
"Successfully start a new session with the correct broker": {username: "success", configuredBrokers: []string{t.Name() + "_Broker1.conf", t.Name() + "_Broker2.conf"}},

"Error when broker does not exist": {brokerID: "does_not_exist", wantErr: true},
"Error when broker does not provide an ID": {username: "NS_no_id", wantErr: true},
"Error when starting a new session": {username: "NS_error", wantErr: true},
"Error when broker does not provide an ID": {username: "ns_no_id", wantErr: true},
"Error when starting a new session": {username: "ns_error", wantErr: true},
"Error when broker is not available on dbus": {unavailableBroker: true, wantErr: true},
}
for name, tc := range tests {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FIRST CALL:
access: granted
data: {"Name":"TestIsAuthenticated/Adds_default_groups_even_if_broker_did_not_set_them_separator_IA_info_empty_groups","UID":0,"Gecos":"gecos for IA_info_empty_groups","Dir":"/home/IA_info_empty_groups","Shell":"/bin/sh/IA_info_empty_groups","Groups":[]}
data: {"Name":"TestIsAuthenticated/Adds_default_groups_even_if_broker_did_not_set_them_separator_ia_info_empty_groups","UID":0,"Gecos":"gecos for ia_info_empty_groups","Dir":"/home/ia_info_empty_groups","Shell":"/bin/sh/ia_info_empty_groups","Groups":[]}
err: <nil>
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
FIRST CALL:
access: granted
data: {"Name":"TestIsAuthenticated/Error_when_calling_IsAuthenticated_a_second_time_without_cancelling_separator_IA_second_call","UID":0,"Gecos":"gecos for IA_second_call","Dir":"/home/IA_second_call","Shell":"/bin/sh/IA_second_call","Groups":[{"Name":"group-IA_second_call","GID":null,"UGID":"ugid-IA_second_call"}]}
data: {"Name":"TestIsAuthenticated/Error_when_calling_IsAuthenticated_a_second_time_without_cancelling_separator_ia_second_call","UID":0,"Gecos":"gecos for ia_second_call","Dir":"/home/ia_second_call","Shell":"/bin/sh/ia_second_call","Groups":[{"Name":"group-ia_second_call","GID":null,"UGID":"ugid-ia_second_call"}]}
err: <nil>
SECOND CALL:
access:
data:
err: broker "TestIsAuthenticated": IsAuthenticated already running for session "TestIsAuthenticated/Error_when_calling_IsAuthenticated_a_second_time_without_cancelling_separator_IA_second_call"
err: broker "TestIsAuthenticated": IsAuthenticated already running for session "TestIsAuthenticated/Error_when_calling_IsAuthenticated_a_second_time_without_cancelling_separator_ia_second_call"
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FIRST CALL:
access: granted
data: {"Name":"TestIsAuthenticated/No_error_when_broker_returns_userinfo_with_empty_gecos_separator_IA_info_empty_gecos","UID":0,"Gecos":"","Dir":"/home/IA_info_empty_gecos","Shell":"/bin/sh/IA_info_empty_gecos","Groups":[{"Name":"group-IA_info_empty_gecos","GID":null,"UGID":"ugid-IA_info_empty_gecos"}]}
data: {"Name":"TestIsAuthenticated/No_error_when_broker_returns_userinfo_with_empty_gecos_separator_ia_info_empty_gecos","UID":0,"Gecos":"","Dir":"/home/ia_info_empty_gecos","Shell":"/bin/sh/ia_info_empty_gecos","Groups":[{"Name":"group-ia_info_empty_gecos","GID":null,"UGID":"ugid-ia_info_empty_gecos"}]}
err: <nil>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FIRST CALL:
access: granted
data: {"Name":"TestIsAuthenticated/No_error_when_broker_returns_userinfo_with_group_with_empty_UGID_separator_IA_info_empty_ugid","UID":0,"Gecos":"gecos for IA_info_empty_ugid","Dir":"/home/IA_info_empty_ugid","Shell":"/bin/sh/IA_info_empty_ugid","Groups":[{"Name":"group-IA_info_empty_ugid","GID":null,"UGID":""}]}
data: {"Name":"TestIsAuthenticated/No_error_when_broker_returns_userinfo_with_group_with_empty_UGID_separator_ia_info_empty_ugid","UID":0,"Gecos":"gecos for ia_info_empty_ugid","Dir":"/home/ia_info_empty_ugid","Shell":"/bin/sh/ia_info_empty_ugid","Groups":[{"Name":"group-ia_info_empty_ugid","GID":null,"UGID":""}]}
err: <nil>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FIRST CALL:
access: granted
data: {"Name":"different_username","UID":0,"Gecos":"gecos for IA_info_mismatching_user_name","Dir":"/home/IA_info_mismatching_user_name","Shell":"/bin/sh/IA_info_mismatching_user_name","Groups":[{"Name":"group-IA_info_mismatching_user_name","GID":null,"UGID":"ugid-IA_info_mismatching_user_name"}]}
data: {"Name":"different_username","UID":0,"Gecos":"gecos for ia_info_mismatching_user_name","Dir":"/home/ia_info_mismatching_user_name","Shell":"/bin/sh/ia_info_mismatching_user_name","Groups":[{"Name":"group-ia_info_mismatching_user_name","GID":null,"UGID":"ugid-ia_info_mismatching_user_name"}]}
err: <nil>
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ FIRST CALL:
err: <nil>
SECOND CALL:
access: granted
data: {"Name":"TestIsAuthenticated/Successfully_authenticate_after_cancelling_first_call_separator_IA_second_call","UID":0,"Gecos":"gecos for IA_second_call","Dir":"/home/IA_second_call","Shell":"/bin/sh/IA_second_call","Groups":[{"Name":"group-IA_second_call","GID":null,"UGID":"ugid-IA_second_call"}]}
data: {"Name":"TestIsAuthenticated/Successfully_authenticate_after_cancelling_first_call_separator_ia_second_call","UID":0,"Gecos":"gecos for ia_second_call","Dir":"/home/ia_second_call","Shell":"/bin/sh/ia_second_call","Groups":[{"Name":"group-ia_second_call","GID":null,"UGID":"ugid-ia_second_call"}]}
err: <nil>
4 changes: 4 additions & 0 deletions internal/services/pam/pam.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"errors"
"fmt"
"os/user"
"strings"

"github.com/ubuntu/authd/internal/brokers"
"github.com/ubuntu/authd/internal/brokers/auth"
Expand Down Expand Up @@ -127,6 +128,9 @@ func (s Service) SelectBroker(ctx context.Context, req *authd.SBRequest) (resp *
brokerID := req.GetBrokerId()
lang := req.GetLang()

// authd usernames are lowercase
username = strings.ToLower(username)

if username == "" {
return nil, status.Error(codes.InvalidArgument, "no user name provided")
}
Expand Down
Loading

0 comments on commit b218326

Please sign in to comment.