Skip to content

Commit

Permalink
account login stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
dotvezz committed Jun 14, 2024
1 parent 34a9f8b commit 487287e
Show file tree
Hide file tree
Showing 12 changed files with 388 additions and 61 deletions.
96 changes: 42 additions & 54 deletions cloud/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,72 +12,60 @@ import (
"github.com/google/uuid"
)

type httpBeginLoginFunc func(
ctx context.Context,
params *oapi.BeginLoginParams,
body oapi.BeginLoginJSONRequestBody,
reqEditors ...oapi.RequestEditorFn,
) (*oapi.BeginLoginResponse, error)

func BeginLogin(
requestBeginLogin httpBeginLoginFunc,
) func(email string) (challengeID uuid.UUID, err error) {
return func(email string) (challengeID uuid.UUID, err error) {
body := oapi.BeginLoginJSONRequestBody{
func BeginLogin(email string) (challengeID uuid.UUID, err error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()

{
body := oapi.GetUserStatusJSONRequestBody{
Email: types.Email(email),
}
resp, err := client.GetUserStatusWithResponse(ctx, nil, body)
if err != nil {
return uuid.Nil, fmt.Errorf("couldn't get user status: %w", err)
}

ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()
if resp == nil || resp.JSON200 == nil {
return uuid.Nil, fmt.Errorf("couldn't get user status: nil response")
}
}

resp, err := requestBeginLogin(ctx, nil, body)
body := oapi.BeginLoginJSONRequestBody{
Email: types.Email(email),
}
resp, err := client.BeginLoginWithResponse(ctx, nil, body)

if err != nil || resp.JSON200 == nil {
return uuid.Nil, fmt.Errorf("couldn't perform login: error %w, http status %s", err, resp.Status())
}
if err != nil {
return uuid.Nil, fmt.Errorf("couldn't begin login: %w", err)
}

return uuid.UUID(resp.JSON200.ChallengeId), nil
if resp == nil || resp.JSON200 == nil {
return uuid.Nil, fmt.Errorf("couldn't begin login: nil response")
}

return resp.JSON200.ChallengeId, nil
}

type httpCompleteLoginFunc func(
ctx context.Context,
params *oapi.CompleteLoginParams,
body oapi.CompleteLoginJSONRequestBody,
reqEditors ...oapi.RequestEditorFn,
) (*oapi.CompleteLoginResponse, error)

func CompleteLogin(
requestCompleteLogin httpCompleteLoginFunc,
) func(
email string,
otpCode string,
challengeID uuid.UUID,
password string,
) (token string, err error) {
return func(
email string,
otpCode string,
challengeID uuid.UUID,
password string,
) (token string, err error) {
body := oapi.CompleteLoginJSONRequestBody{
Email: types.Email(email),
OtpCode: otpCode,
ChallengeId: challengeID,
Password: password,
}
func CompleteLogin(email, otpCode, password string, challengeID uuid.UUID) (token string, err error) {
body := oapi.CompleteLoginJSONRequestBody{
Email: types.Email(email),
OtpCode: otpCode,
ChallengeId: challengeID,
Password: password,
}

ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()

resp, err := requestCompleteLogin(ctx, nil, body)
resp, err := client.CompleteLoginWithResponse(ctx, nil, body)

if err != nil || resp.JSON200 == nil {
return "", fmt.Errorf("couldn't perform login: error %w, http status %s", err, resp.Status())
}

return resp.JSON200.Tokeng, nil
if err != nil {
return "", fmt.Errorf("couldn't complete login: %w", err)
}

if resp == nil || resp.JSON200 == nil {
return "", fmt.Errorf("couldn't complete login: nil response")
}

return resp.JSON200.Token, nil
}
71 changes: 71 additions & 0 deletions cloud/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package cloud

import (
"context"
"fmt"
"github.com/libdyson-wg/libdyson-go/internal/generated/oapi"
"net/http"
)

type ServerRegion int

const (
RegionGlobal ServerRegion = iota
RegionChina
)

var (
region ServerRegion = RegionGlobal
client oapi.ClientWithResponsesInterface

provisioned bool

token string

servers = []string{
"https://appapi.cp.dyson.com",
"https://appapi.cp.dyson.cn",
}
)

func init() {
setServer()
}

func addAuthToken(_ context.Context, r *http.Request) error {
if token != "" {
r.Header.Set("Authorization", "Bearer "+token)
}
return nil
}

func addUserAgent(_ context.Context, r *http.Request) error {
r.Header.Set("User-Agent", "android client")
return nil
}

func setServer() {
var err error
client, err = oapi.NewClientWithResponses(
servers[region],
oapi.WithRequestEditorFn(addAuthToken),
oapi.WithRequestEditorFn(addUserAgent),
)
if err != nil {
panic(fmt.Errorf("unable to initialize client: %w", err))
}

_, err = client.ProvisionWithResponse(context.Background())
if err != nil {
panic(fmt.Errorf("unable to provision api client: %w", err))
}
}

func SetToken(t string) {
token = t
}

func SetServerRegion(r ServerRegion) {
region = r
setServer()
}
14 changes: 12 additions & 2 deletions cmd/dson/cmd/devices.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
package cmd

import (
"fmt"
"github.com/libdyson-wg/libdyson-go/config"

"github.com/spf13/cobra"
)

var devicesCmd = &cobra.Command{
Use: "devices",
Short: "Lists the devices on your account",
PreRunE: func(cmd *cobra.Command, args []string) error {
tok, err := config.GetToken()
if err != nil {
return err
}
if tok == "" {
err = funcs.Login()
}
return err
},
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("devices called")
//ds, err := funcs.GetDevices
},
}

Expand Down
29 changes: 29 additions & 0 deletions cmd/dson/cmd/funcs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package cmd

import (
"github.com/libdyson-wg/libdyson-go/cloud"
"github.com/libdyson-wg/libdyson-go/config"
"github.com/libdyson-wg/libdyson-go/internal/account"
"github.com/libdyson-wg/libdyson-go/internal/shell"
)

type functions struct {
Login func() error
GetDevices func() error
}

var funcs functions

func init() {
funcs = functions{
Login: account.Login(
shell.PromptForInput,
shell.PromptForPassword,
cloud.BeginLogin,
cloud.CompleteLogin,
config.SetToken,
cloud.SetToken,
cloud.SetServerRegion,
),
}
}
20 changes: 18 additions & 2 deletions cmd/dson/cmd/login.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,30 @@
package cmd

import (
"fmt"
"github.com/libdyson-wg/libdyson-go/config"

"github.com/spf13/cobra"
)

var loginCmd = &cobra.Command{
Use: "login",
RunE: func(cmd *cobra.Command, args []string) error {
return funcs.Login()
},
PostRun: func(cmd *cobra.Command, args []string) {
fmt.Println(
fmt.Sprintf(
"You are logged in. Please note that your API Token has been saved to %s.\n\n"+
"This API Token is sensitive and should not be shared with anyone you don't trust. "+
"It could possibly be used to control your Dyson devices or learn sensitive private "+
"information about you through your Dyson account.",
config.GetFilePath(),
),
)
},
}

func init() {
loginCmd.Run =
rootCmd.AddCommand(loginCmd)
rootCmd.AddCommand(loginCmd)
}
11 changes: 10 additions & 1 deletion cmd/dson/main.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
package main

import "libdyson-go/cmd/dson/cmd"
import (
"github.com/libdyson-wg/libdyson-go/cloud"
"github.com/libdyson-wg/libdyson-go/cmd/dson/cmd"
"github.com/libdyson-wg/libdyson-go/config"
)

func main() {
tok, err := config.GetToken()
if err != nil {
panic(err)
}
cloud.SetToken(tok)
cmd.Execute()
}
26 changes: 26 additions & 0 deletions config/account.go
Original file line number Diff line number Diff line change
@@ -1 +1,27 @@
package config

import "fmt"

func SetToken(t string) error {
conf, err := readConfig()
if err != nil {
return fmt.Errorf("could not read config: %v", err)
}

conf.Token = t
err = writeConfig(conf)
if err != nil {
err = fmt.Errorf("could not save config: %v", err)
}

return err
}

func GetToken() (string, error) {
conf, err := readConfig()
if err != nil {
return "", fmt.Errorf("could not read token from config: %v", err)
}

return conf.Token, nil
}
Loading

0 comments on commit 487287e

Please sign in to comment.