/ internal / gtsclient / client.go
client.go
 1  package gtsclient
 2  
 3  import (
 4  	"fmt"
 5  	"net/http"
 6  	"time"
 7  
 8  	"codeflow.dananglin.me.uk/apollo/enbas/internal/config"
 9  	"codeflow.dananglin.me.uk/apollo/enbas/internal/info"
10  	"codeflow.dananglin.me.uk/apollo/enbas/internal/utilities"
11  )
12  
13  const (
14  	applicationJSON   string = "application/json; charset=utf-8"
15  	redirectURI       string = "urn:ietf:wg:oauth:2.0:oob"
16  	authCodeURLFormat string = "%s/oauth/authorize?client_id=%s&redirect_uri=%s&response_type=code"
17  )
18  
19  type (
20  	NoRPCArgs    struct{}
21  	NoRPCResults struct{}
22  
23  	GTSClient struct {
24  		authentication config.Credentials
25  		httpClient     http.Client
26  		timeout        time.Duration
27  		mediaTimeout   time.Duration
28  		userAgent      string
29  	}
30  )
31  
32  // NewGTSClient creates GTSClient value for connecting with the GoToSocial instance. If the credentials
33  // file is present then the authentication details is retrieved for the current account in use.
34  // If the file is not present then a zero-valued authentication value is used which must be updated later.
35  func NewGTSClient(cfg *config.Config) (*GTSClient, error) {
36  	var auth config.Credentials
37  
38  	exists, err := utilities.FileExists(cfg.CredentialsFile)
39  	if err != nil {
40  		return nil, fmt.Errorf("error checking for the credentials file: %w", err)
41  	}
42  
43  	if exists {
44  		auth, err = authFromFile(cfg.CredentialsFile)
45  		if err != nil {
46  			return nil, fmt.Errorf("error getting the authentication details from the credentials file: %w", err)
47  		}
48  	} else {
49  		auth = config.Credentials{
50  			Instance:     "",
51  			ClientID:     "",
52  			ClientSecret: "",
53  			AccessToken:  "",
54  		}
55  	}
56  
57  	gtsClient := GTSClient{
58  		authentication: auth,
59  		httpClient:     http.Client{},
60  		timeout:        time.Duration(cfg.GTSClient.Timeout) * time.Second,
61  		mediaTimeout:   time.Duration(cfg.GTSClient.MediaTimeout) * time.Second,
62  		userAgent:      info.ApplicationTitledName + "/" + info.BinaryVersion,
63  	}
64  
65  	return &gtsClient, nil
66  }
67  
68  func authFromFile(path string) (config.Credentials, error) {
69  	creds, err := config.NewCredentialsConfigFromFile(path)
70  	if err != nil {
71  		return config.Credentials{}, fmt.Errorf("error getting the credentials from the credentials file: %w", err)
72  	}
73  
74  	auth, ok := creds.Credentials[creds.CurrentAccount]
75  	if !ok {
76  		return config.Credentials{}, Error{"the authentication details seems to be missing for the current account (" + creds.CurrentAccount + ")"}
77  	}
78  
79  	return auth, nil
80  }
81  
82  // UpdateAuthentication updates the authentication details for the GTSClient.
83  func (g *GTSClient) UpdateAuthentication(auth config.Credentials, _ *NoRPCResults) error {
84  	g.authentication = auth
85  
86  	return nil
87  }