Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 20 additions & 9 deletions api/gen/proto/go/teleport/userloginstate/v1/userloginstate.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions api/proto/teleport/userloginstate/v1/userloginstate.proto
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,7 @@ message Spec {

// traits are the traits attached to the user.
repeated teleport.trait.v1.Trait traits = 2;

// user_type is the type of user this state represents.
string user_type = 3;
}
15 changes: 15 additions & 0 deletions api/types/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ type User interface {
GetTrustedDeviceIDs() []string
// SetTrustedDeviceIDs assigns the IDs of the user's trusted devices.
SetTrustedDeviceIDs(ids []string)
// IsBot returns true if the user is a bot.
IsBot() bool
// BotGenerationLabel returns the bot generation label.
BotGenerationLabel() string
}

// NewUser creates new empty user
Expand Down Expand Up @@ -460,6 +464,17 @@ func (u UserV2) GetUserType() UserType {
return UserTypeSSO
}

// IsBot returns true if the user is a bot.
func (u UserV2) IsBot() bool {
_, ok := u.GetMetadata().Labels[BotGenerationLabel]
return ok
}

// BotGenerationLabel returns the bot generation label.
func (u UserV2) BotGenerationLabel() string {
return u.GetMetadata().Labels[BotGenerationLabel]
}

func (u *UserV2) String() string {
return fmt.Sprintf("User(name=%v, roles=%v, identities=%v)", u.Metadata.Name, u.Spec.Roles, u.Spec.OIDCIdentities)
}
Expand Down
11 changes: 7 additions & 4 deletions api/types/userloginstate/convert/v1/user_login_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/gravitational/trace"

userloginstatev1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/userloginstate/v1"
"github.com/gravitational/teleport/api/types"
headerv1 "github.com/gravitational/teleport/api/types/header/convert/v1"
traitv1 "github.com/gravitational/teleport/api/types/trait/convert/v1"
"github.com/gravitational/teleport/api/types/userloginstate"
Expand All @@ -32,8 +33,9 @@ func FromProto(msg *userloginstatev1.UserLoginState) (*userloginstate.UserLoginS
}

uls, err := userloginstate.New(headerv1.FromMetadataProto(msg.Header.Metadata), userloginstate.Spec{
Roles: msg.Spec.Roles,
Traits: traitv1.FromProto(msg.Spec.Traits),
Roles: msg.Spec.Roles,
Traits: traitv1.FromProto(msg.Spec.Traits),
UserType: types.UserType(msg.Spec.UserType),
})

return uls, trace.Wrap(err)
Expand All @@ -44,8 +46,9 @@ func ToProto(uls *userloginstate.UserLoginState) *userloginstatev1.UserLoginStat
return &userloginstatev1.UserLoginState{
Header: headerv1.ToResourceHeaderProto(uls.ResourceHeader),
Spec: &userloginstatev1.Spec{
Roles: uls.GetRoles(),
Traits: traitv1.ToProto(uls.GetTraits()),
Roles: uls.GetRoles(),
Traits: traitv1.ToProto(uls.GetTraits()),
UserType: string(uls.Spec.UserType),
},
}
}
10 changes: 10 additions & 0 deletions api/types/userloginstate/convert/v1/user_login_state_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/require"

"github.com/gravitational/teleport/api/types"
"github.com/gravitational/teleport/api/types/header"
"github.com/gravitational/teleport/api/types/trait"
"github.com/gravitational/teleport/api/types/userloginstate"
Expand Down Expand Up @@ -58,6 +59,14 @@ func TestFromProtoNils(t *testing.T) {

_, err = FromProto(uls)
require.NoError(t, err)

// UserType is empty
uls = ToProto(newUserLoginState(t, "user-login-state"))
uls.Spec.UserType = ""

fromProto, err := FromProto(uls)
require.NoError(t, err)
require.Equal(t, fromProto.GetUserType(), types.UserTypeLocal)
}

func newUserLoginState(t *testing.T, name string) *userloginstate.UserLoginState {
Expand All @@ -73,6 +82,7 @@ func newUserLoginState(t *testing.T, name string) *userloginstate.UserLoginState
"key1": []string{"value1"},
"key2": []string{"value2"},
},
UserType: types.UserTypeSSO,
},
)
require.NoError(t, err)
Expand Down
31 changes: 29 additions & 2 deletions api/types/userloginstate/user_login_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ type Spec struct {

// Traits are the traits attached to the user login state.
Traits trait.Traits `json:"traits" yaml:"traits"`

// UserType is the type of user that this state represents.
UserType types.UserType `json:"user_type" yaml:"user_type"`
}

// New creates a new user login state.
Expand All @@ -67,7 +70,15 @@ func (u *UserLoginState) CheckAndSetDefaults() error {
u.SetKind(types.KindUserLoginState)
u.SetVersion(types.V1)

return trace.Wrap(u.ResourceHeader.CheckAndSetDefaults())
if err := trace.Wrap(u.ResourceHeader.CheckAndSetDefaults()); err != nil {
return trace.Wrap(err)
}

if u.Spec.UserType == "" {
u.Spec.UserType = types.UserTypeLocal
}

return nil
}

// GetRoles returns the roles attached to the user login state.
Expand All @@ -76,10 +87,26 @@ func (u *UserLoginState) GetRoles() []string {
}

// GetTraits returns the traits attached to the user login state.
func (u *UserLoginState) GetTraits() trait.Traits {
func (u *UserLoginState) GetTraits() map[string][]string {
return u.Spec.Traits
}

// GetUserType returns the user type for the user login state.
func (u *UserLoginState) GetUserType() types.UserType {
return u.Spec.UserType
}

// IsBot returns true if the user is a bot.
func (u *UserLoginState) IsBot() bool {
_, ok := u.GetMetadata().Labels[types.BotGenerationLabel]
return ok
}

// BotGenerationLabel returns the bot generation label.
func (u *UserLoginState) BotGenerationLabel() string {
return u.GetMetadata().Labels[types.BotGenerationLabel]
}

// GetMetadata returns metadata. This is specifically for conforming to the Resource interface,
// and should be removed when possible.
func (u *UserLoginState) GetMetadata() types.Metadata {
Expand Down
Loading