From 082dfc09d70b117ad9d1164853a82a7a43f37e20 Mon Sep 17 00:00:00 2001 From: kompotkot Date: Wed, 5 Mar 2025 09:48:15 +0000 Subject: [PATCH] Auth user endpoint --- cmd/bugout/brood/user.go | 30 +++++++++++++++++++++++++++++- dev.sh | 10 ++++++++++ pkg/brood/client.go | 3 +++ pkg/brood/data.go | 24 ++++++++++++++++++++++++ pkg/brood/user.go | 32 ++++++++++++++++++++++++++++++++ pkg/version.go | 2 +- 6 files changed, 99 insertions(+), 2 deletions(-) create mode 100755 dev.sh diff --git a/cmd/bugout/brood/user.go b/cmd/bugout/brood/user.go index 127dbcc..cb85196 100644 --- a/cmd/bugout/brood/user.go +++ b/cmd/bugout/brood/user.go @@ -17,6 +17,7 @@ func CreateUserCommand() *cobra.Command { Short: "Bugout user operations", } + userAuthCmd := CreateUserAuthCommand() userCreateCmd := CreateUserCreateCommand() userLoginCmd := CreateUserLoginCommand() userTokensCmd := CreateUserTokensCommand() @@ -25,11 +26,38 @@ func CreateUserCommand() *cobra.Command { userVerifyCmd := CreateUserVerifyCommand() userChangePasswordCmd := CreateUserChangePasswordCommand() - userCmd.AddCommand(userCreateCmd, userLoginCmd, userTokensCmd, userGetCmd, userFindCmd, userVerifyCmd, userChangePasswordCmd) + userCmd.AddCommand(userAuthCmd, userCreateCmd, userLoginCmd, userTokensCmd, userGetCmd, userFindCmd, userVerifyCmd, userChangePasswordCmd) return userCmd } +func CreateUserAuthCommand() *cobra.Command { + var token string + userGetCmd := &cobra.Command{ + Use: "auth", + Short: "Get the user with groups represented by a token", + PreRunE: cmdutils.TokenArgPopulator, + RunE: func(cmd *cobra.Command, args []string) error { + client, err := bugout.ClientFromEnv() + if err != nil { + return err + } + + userAuth, err := client.Brood.Auth(token) + if err != nil { + return err + } + + encodeErr := json.NewEncoder(cmd.OutOrStdout()).Encode(&userAuth) + return encodeErr + }, + } + + userGetCmd.Flags().StringVarP(&token, "token", "t", "", "Bugout access token to use for the request") + + return userGetCmd +} + func CreateUserCreateCommand() *cobra.Command { var username, email, password string userCreateCmd := &cobra.Command{ diff --git a/dev.sh b/dev.sh new file mode 100755 index 0000000..0a6a4c3 --- /dev/null +++ b/dev.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env sh + +# Compile application and run with provided arguments +set -e + +PROGRAM_NAME="bugout" + +go build -o "$PROGRAM_NAME" ./cmd/bugout + +./"$PROGRAM_NAME" "$@" diff --git a/pkg/brood/client.go b/pkg/brood/client.go index c3eae3f..3bec960 100644 --- a/pkg/brood/client.go +++ b/pkg/brood/client.go @@ -18,6 +18,7 @@ const BugoutBroodURL string = "https://auth.bugout.dev" type BroodCaller interface { Ping() (string, error) Version() (string, error) + Auth(token string) (AuthUser, error) CreateUser(string, string, string) (User, error) GenerateToken(string, string) (string, error) AnnotateToken(token, tokenType, note string) (string, error) @@ -49,6 +50,7 @@ type BroodCaller interface { type BroodRoutes struct { Ping string Version string + Auth string User string FindUser string Groups string @@ -69,6 +71,7 @@ func RoutesFromURL(broodURL string) BroodRoutes { return BroodRoutes{ Ping: fmt.Sprintf("%s/ping", cleanURL), Version: fmt.Sprintf("%s/version", cleanURL), + Auth: fmt.Sprintf("%s/auth", cleanURL), User: fmt.Sprintf("%s/user", cleanURL), FindUser: fmt.Sprintf("%s/user/find", cleanURL), Groups: fmt.Sprintf("%s/groups", cleanURL), diff --git a/pkg/brood/data.go b/pkg/brood/data.go index 11c482e..3f73e1c 100644 --- a/pkg/brood/data.go +++ b/pkg/brood/data.go @@ -4,12 +4,36 @@ import ( "encoding/json" ) +type AuthUserGroup struct { + GroupId string `json:"group_id"` + UserId string `json:"user_id"` + UserType string `json:"user_type"` + Autogenerated bool `json:"autogenerated"` + GroupName string `json:"group_name"` +} + +type AuthUser struct { + UserId string `json:"user_id"` + Username string `json:"username"` + Email string `json:"email"` + NormalizedEmail string `json:"normalized_email"` + Verified bool `json:"verified"` + Autogenerated bool `json:"autogenerated"` + ApplicationId string `json:"application_id"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` + + Groups []AuthUserGroup `json:"groups"` +} + type User struct { Id string `json:"id"` Username string `json:"username"` Email string `json:"email"` NormalizedEmail string `json:"normalized_email"` Verified bool `json:"verified"` + ApplicationId string `json:"application_id"` + Autogenerated bool `json:"autogenerated"` CreatedAt string `json:"created_at"` UpdatedAt string `json:"updated_at"` } diff --git a/pkg/brood/user.go b/pkg/brood/user.go index 28e37b5..f8bf69d 100644 --- a/pkg/brood/user.go +++ b/pkg/brood/user.go @@ -22,6 +22,38 @@ func getUserID(decoder *json.Decoder) (string, error) { return userIDWrapper.UserID, decodeErr } +func (client BroodClient) Auth(token string) (AuthUser, error) { + authRoute := client.Routes.Auth + request, requestErr := http.NewRequest("GET", authRoute, nil) + if requestErr != nil { + return AuthUser{}, requestErr + } + request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token)) + request.Header.Add("Accept", "application/json") + + response, err := client.HTTPClient.Do(request) + if err != nil { + return AuthUser{}, err + } + defer response.Body.Close() + + var buf bytes.Buffer + bodyReader := io.TeeReader(response.Body, &buf) + + statusErr := utils.HTTPStatusCheck(response) + if statusErr != nil { + return AuthUser{}, statusErr + } + + var authUser AuthUser + decodeErr := json.NewDecoder(bodyReader).Decode(&authUser) + if decodeErr != nil { + return authUser, decodeErr + } + + return authUser, nil +} + func (client BroodClient) CreateUser(username, email, password string) (User, error) { userRoute := client.Routes.User data := url.Values{} diff --git a/pkg/version.go b/pkg/version.go index 0053fd2..f7e2004 100644 --- a/pkg/version.go +++ b/pkg/version.go @@ -1,3 +1,3 @@ package bugout -const Version string = "0.4.6" +const Version string = "0.4.7"