Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
shyim committed Jan 9, 2022
0 parents commit 5a46114
Show file tree
Hide file tree
Showing 11 changed files with 1,307 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/.idea
/shopware-cli
25 changes: 25 additions & 0 deletions account-api/client.go
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

}
90 changes: 90 additions & 0 deletions account-api/companies.go
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"`
}
64 changes: 64 additions & 0 deletions account-api/login.go
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"`
}
105 changes: 105 additions & 0 deletions account-api/profile.go
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"`
}
106 changes: 106 additions & 0 deletions cmd/account_login.go
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
}
Loading

0 comments on commit 5a46114

Please sign in to comment.