-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 5a46114
Showing
11 changed files
with
1,307 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
/.idea | ||
/shopware-cli |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package account_api | ||
|
||
import ( | ||
"io" | ||
"net/http" | ||
) | ||
|
||
type Client struct { | ||
token token | ||
} | ||
|
||
func (c Client) NewAuthenticatedRequest(method, path string, body io.Reader) (*http.Request, error) { | ||
r, err := http.NewRequest(method, path, body) | ||
|
||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
r.Header.Set("content-type", "application/json") | ||
r.Header.Set("accept", "application/json") | ||
r.Header.Set("x-shopware-token", c.token.Token) | ||
|
||
return r, nil | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
package account_api | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"io/ioutil" | ||
"net/http" | ||
) | ||
|
||
type clientCompanies struct { | ||
c Client | ||
} | ||
|
||
func (c Client) Companies() *clientCompanies { | ||
return &clientCompanies{c: c} | ||
} | ||
|
||
func (cc clientCompanies) MyCompanies() (*[]membershipCompany, error) { | ||
r, err := cc.c.NewAuthenticatedRequest("GET", fmt.Sprintf("%s/account/%d/memberships", ApiUrl, cc.c.token.UserAccountID), nil) | ||
|
||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
resp, err := http.DefaultClient.Do(r) | ||
|
||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
defer resp.Body.Close() | ||
|
||
data, err := ioutil.ReadAll(resp.Body) | ||
if err != nil { | ||
return nil, fmt.Errorf("MyCompanies: %v", err) | ||
} | ||
|
||
if resp.StatusCode != 200 { | ||
return nil, fmt.Errorf(string(data)) | ||
} | ||
|
||
var companies []membershipCompany | ||
if err := json.Unmarshal(data, &companies); err != nil { | ||
return nil, fmt.Errorf("my_profile: %v", err) | ||
} | ||
|
||
return &companies, nil | ||
} | ||
|
||
type membershipCompany []struct { | ||
Id int `json:"id"` | ||
CreationDate string `json:"creationDate"` | ||
Active bool `json:"active"` | ||
Member struct { | ||
Id int `json:"id"` | ||
Email string `json:"email"` | ||
AvatarUrl interface{} `json:"avatarUrl"` | ||
PersonalData struct { | ||
Id int `json:"id"` | ||
Salutation struct { | ||
Id int `json:"id"` | ||
Name string `json:"name"` | ||
Description string `json:"description"` | ||
} `json:"salutation"` | ||
FirstName string `json:"firstName"` | ||
LastName string `json:"lastName"` | ||
Locale struct { | ||
Id int `json:"id"` | ||
Name string `json:"name"` | ||
Description string `json:"description"` | ||
} `json:"locale"` | ||
} `json:"personalData"` | ||
} `json:"member"` | ||
Company struct { | ||
Id int `json:"id"` | ||
Name string `json:"name"` | ||
CustomerNumber int `json:"customerNumber"` | ||
} `json:"company"` | ||
Roles []struct { | ||
Id int `json:"id"` | ||
Name string `json:"name"` | ||
CreationDate string `json:"creationDate"` | ||
Company interface{} `json:"company"` | ||
Permissions []struct { | ||
Id int `json:"id"` | ||
Context string `json:"context"` | ||
Name string `json:"name"` | ||
} `json:"permissions"` | ||
} `json:"roles"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
package account_api | ||
|
||
import ( | ||
"bytes" | ||
"encoding/json" | ||
"fmt" | ||
"io/ioutil" | ||
"net/http" | ||
) | ||
|
||
const ApiUrl = "https://api.shopware.com" | ||
|
||
func NewApi(request LoginRequest) (*Client, error) { | ||
s, err := json.Marshal(request) | ||
if err != nil { | ||
return nil, fmt.Errorf("login: %v", err) | ||
} | ||
|
||
resp, err := http.Post(ApiUrl+"/accesstokens", "application/json", bytes.NewBuffer(s)) | ||
if err != nil { | ||
return nil, fmt.Errorf("login: %v", err) | ||
} | ||
|
||
defer resp.Body.Close() | ||
|
||
data, err := ioutil.ReadAll(resp.Body) | ||
if err != nil { | ||
return nil, fmt.Errorf("login: %v", err) | ||
} | ||
|
||
if resp.StatusCode != 200 { | ||
return nil, fmt.Errorf(string(data)) | ||
} | ||
|
||
var token token | ||
if err := json.Unmarshal(data, &token); err != nil { | ||
return nil, fmt.Errorf("login: %v", err) | ||
} | ||
|
||
client := Client{ | ||
token: token, | ||
} | ||
|
||
return &client, nil | ||
} | ||
|
||
type token struct { | ||
Token string `json:"token"` | ||
Expire tokenExpire `json:"expire"` | ||
UserAccountID int `json:"userAccountId"` | ||
UserID int `json:"userId"` | ||
LegacyLogin bool `json:"legacyLogin"` | ||
} | ||
|
||
type tokenExpire struct { | ||
Date string `json:"date"` | ||
TimezoneType int `json:"timezone_type"` | ||
Timezone string `json:"timezone"` | ||
} | ||
|
||
type LoginRequest struct { | ||
Email string `json:"shopwareId"` | ||
Password string `json:"password"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package account_api | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"io/ioutil" | ||
"net/http" | ||
) | ||
|
||
func (c Client) GetMyProfile() (*myProfile, error) { | ||
request, err := c.NewAuthenticatedRequest("GET", fmt.Sprintf("%s/account/%d", ApiUrl, c.token.UserAccountID), nil) | ||
|
||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
resp, err := http.DefaultClient.Do(request) | ||
|
||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
defer resp.Body.Close() | ||
|
||
data, err := ioutil.ReadAll(resp.Body) | ||
if err != nil { | ||
return nil, fmt.Errorf("login: %v", err) | ||
} | ||
|
||
if resp.StatusCode != 200 { | ||
return nil, fmt.Errorf(string(data)) | ||
} | ||
|
||
var profile myProfile | ||
if err := json.Unmarshal(data, &profile); err != nil { | ||
return nil, fmt.Errorf("my_profile: %v", err) | ||
} | ||
|
||
return &profile, nil | ||
} | ||
|
||
type myProfile struct { | ||
Id int `json:"id"` | ||
Email string `json:"email"` | ||
CreationDate string `json:"creationDate"` | ||
Banned bool `json:"banned"` | ||
Verified bool `json:"verified"` | ||
PersonalData struct { | ||
Id int `json:"id"` | ||
Salutation struct { | ||
Id int `json:"id"` | ||
Name string `json:"name"` | ||
Description string `json:"description"` | ||
} `json:"salutation"` | ||
FirstName string `json:"firstName"` | ||
LastName string `json:"lastName"` | ||
Locale struct { | ||
Id int `json:"id"` | ||
Name string `json:"name"` | ||
Description string `json:"description"` | ||
} `json:"locale"` | ||
} `json:"personalData"` | ||
PartnerMarketingOptIn bool `json:"partnerMarketingOptIn"` | ||
SelectedMembership struct { | ||
Id int `json:"id"` | ||
CreationDate string `json:"creationDate"` | ||
Active bool `json:"active"` | ||
Member struct { | ||
Id int `json:"id"` | ||
Email string `json:"email"` | ||
AvatarUrl interface{} `json:"avatarUrl"` | ||
PersonalData struct { | ||
Id int `json:"id"` | ||
Salutation struct { | ||
Id int `json:"id"` | ||
Name string `json:"name"` | ||
Description string `json:"description"` | ||
} `json:"salutation"` | ||
FirstName string `json:"firstName"` | ||
LastName string `json:"lastName"` | ||
Locale struct { | ||
Id int `json:"id"` | ||
Name string `json:"name"` | ||
Description string `json:"description"` | ||
} `json:"locale"` | ||
} `json:"personalData"` | ||
} `json:"member"` | ||
Company struct { | ||
Id int `json:"id"` | ||
Name string `json:"name"` | ||
CustomerNumber int `json:"customerNumber"` | ||
} `json:"company"` | ||
Roles []struct { | ||
Id int `json:"id"` | ||
Name string `json:"name"` | ||
CreationDate string `json:"creationDate"` | ||
Company interface{} `json:"company"` | ||
Permissions []struct { | ||
Id int `json:"id"` | ||
Context string `json:"context"` | ||
Name string `json:"name"` | ||
} `json:"permissions"` | ||
} `json:"roles"` | ||
} `json:"selectedMembership"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
package cmd | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
termColor "github.com/fatih/color" | ||
"github.com/manifoldco/promptui" | ||
"github.com/spf13/cobra" | ||
"github.com/spf13/viper" | ||
"log" | ||
"os" | ||
shopware_account_api "shopware-cli/account-api" | ||
) | ||
|
||
var loginCmd = &cobra.Command{ | ||
Use: "account:login", | ||
Short: "Login into your Shopware Account", | ||
Long: "", | ||
Run: func(cmd *cobra.Command, args []string) { | ||
email := viper.GetString("account_email") | ||
password := viper.GetString("account_password") | ||
newCredentials := false | ||
|
||
if len(email) == 0 || len(password) == 0 { | ||
email, password = askUserForEmailAndPassword() | ||
newCredentials = true | ||
|
||
viper.Set("account_email", email) | ||
viper.Set("account_password", password) | ||
} else { | ||
termColor.Blue("Using existing credentials. Use account:logout to logout") | ||
} | ||
|
||
client, err := shopware_account_api.NewApi(shopware_account_api.LoginRequest{Email: email, Password: password}) | ||
|
||
if err != nil { | ||
termColor.Red("Login failed with error: %s", err.Error()) | ||
os.Exit(1) | ||
} | ||
|
||
if newCredentials { | ||
|
||
err := viper.WriteConfig() | ||
|
||
if err != nil { | ||
log.Fatalln(err) | ||
} | ||
} | ||
|
||
profile, err := client.GetMyProfile() | ||
|
||
if err != nil { | ||
log.Fatalln(err) | ||
} | ||
|
||
companies, err := client.Companies().MyCompanies() | ||
if err != nil { | ||
log.Fatalln(err) | ||
} | ||
|
||
fmt.Println(companies) | ||
|
||
termColor.Green("Hey %s %s. You are now authenticated and can use all account commands", profile.PersonalData.FirstName, profile.PersonalData.LastName) | ||
}, | ||
} | ||
|
||
func init() { | ||
rootCmd.AddCommand(loginCmd) | ||
} | ||
|
||
func askUserForEmailAndPassword() (string, string) { | ||
emailPrompt := promptui.Prompt{ | ||
Label: "Email", | ||
Validate: emptyValidator, | ||
} | ||
|
||
email, err := emailPrompt.Run() | ||
|
||
if err != nil { | ||
fmt.Printf("Prompt failed %v\n", err) | ||
os.Exit(1) | ||
} | ||
|
||
passwordPrompt := promptui.Prompt{ | ||
Label: "Password", | ||
Validate: emptyValidator, | ||
Mask: '*', | ||
} | ||
|
||
password, err := passwordPrompt.Run() | ||
|
||
if err != nil { | ||
fmt.Printf("Prompt failed %v\n", err) | ||
os.Exit(1) | ||
} | ||
|
||
return email, password | ||
} | ||
|
||
func emptyValidator(s string) error { | ||
if len(s) == 0 { | ||
return errors.New("this cannot be empty") | ||
} | ||
|
||
return nil | ||
} |
Oops, something went wrong.