Files
Matheus Sampaio Queiroga 45ceeea236 Add Readlink, Lstat and refactor
Signed-off-by: Matheus Sampaio Queiroga <srherobrine20@gmail.com>
2025-03-17 00:57:53 -03:00

144 lines
4.3 KiB
Go

package main
import (
"context"
"encoding/json"
"flag"
"fmt"
"net"
"net/http"
"net/netip"
"os"
"golang.org/x/oauth2"
"google.golang.org/api/drive/v2"
"sirherobrine23.com.br/Sirherobrine23/drivefs"
)
var (
configPath = flag.String("config", "./config.json", "Config file path")
serverPort = flag.Uint("port", 8081, "server to listen")
setupAuth = flag.Bool("auth", false, "Listen server and Auth")
client = flag.String("client", "", "installed.client_id")
secret = flag.String("secret", "", "installed.client_secret")
project = flag.String("project", "", "installed.project_id")
auth_uri = flag.String("auth_uri", "", "installed.auth_uri")
token_uri = flag.String("token_uri", "", "installed.token_uri")
redirect = flag.String("redirect", "", "installed.redirect_uris[]")
access_token = flag.String("access_token", "", "token.access_token")
refresh_token = flag.String("refresh_token", "", "token.refresh_token")
token_type = flag.String("token_type", "", "token.token_type")
root_folder = flag.String("root_folder", "", "Google drive folder id (gdrive:<ID>) or path to folder")
gdriveConfig drivefs.GoogleOauthConfig
)
func main() {
flag.Parse()
gdriveConfig.Client = *client
gdriveConfig.Secret = *secret
gdriveConfig.Project = *project
gdriveConfig.AuthURI = *auth_uri
gdriveConfig.TokenURI = *token_uri
gdriveConfig.Redirect = *redirect
gdriveConfig.AccessToken = *access_token
gdriveConfig.RefreshToken = *refresh_token
gdriveConfig.TokenType = *token_type
gdriveConfig.RootFolder = *root_folder
fileConfig, err := os.ReadFile(*configPath)
if err == nil {
if err = json.Unmarshal(fileConfig, &gdriveConfig); err != nil {
fmt.Fprintf(os.Stderr, "Cannot unmarshall config: %s\n", err)
os.Exit(1)
return
}
} else if os.IsNotExist(err) {
} else {
fmt.Fprintf(os.Stderr, "Cannot open %q: %s\n", *configPath, err)
os.Exit(1)
return
}
if *setupAuth {
ln, err := net.Listen("tcp", ":0")
if err != nil {
panic(err)
}
P, _ := netip.ParseAddrPort(ln.Addr().String())
ln.Close()
config := &oauth2.Config{
ClientID: gdriveConfig.Client,
ClientSecret: gdriveConfig.Secret,
RedirectURL: fmt.Sprintf("http://localhost:%d/callback", P.Port()),
Scopes: []string{drive.DriveScope, drive.DriveFileScope},
Endpoint: oauth2.Endpoint{
AuthURL: gdriveConfig.AuthURI,
TokenURL: gdriveConfig.TokenURI,
},
}
var (
server *http.Server
GoogleToken *oauth2.Token
)
mux := http.NewServeMux()
mux.HandleFunc("/token", func(w http.ResponseWriter, r *http.Request) {
authURL := config.AuthCodeURL("state-token", oauth2.AccessTypeOffline)
http.Redirect(w, r, authURL, http.StatusTemporaryRedirect)
})
mux.HandleFunc("/callback", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
if code := r.URL.Query().Get("code"); code != "" {
if GoogleToken, err = config.Exchange(context.TODO(), code); err != nil {
panic(fmt.Errorf("unable to retrieve token from web %v", err))
}
defer server.Close()
w.WriteHeader(200)
fmt.Fprintf(w, "<html><body>Code: %q</body></html>", code)
fmt.Printf("Code: %q\n", code)
return
}
w.WriteHeader(400)
w.Write([]byte("Wait to code\n"))
})
fmt.Printf("Go to the following link in your browser then type the authorization code: \nhttp://%s/token\n", P.String())
server = &http.Server{Addr: P.String(), Handler: mux}
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
panic(err)
}
gdriveConfig.AccessToken = GoogleToken.AccessToken
gdriveConfig.RefreshToken = GoogleToken.RefreshToken
gdriveConfig.TokenType = GoogleToken.TokenType
gdriveConfig.Expire = GoogleToken.Expiry
data, err := json.MarshalIndent(gdriveConfig, "", " ")
if err != nil {
panic(err)
} else if err = os.WriteFile(*configPath, data, 0666); err != nil {
panic(err)
}
}
gdrive, err := drivefs.NewGoogleDrive(gdriveConfig)
if err != nil {
fmt.Fprintf(os.Stderr, "Cannot open gdrive client: %s\n", err)
os.Exit(1)
return
}
fmt.Printf("server listening on :%d\n", *serverPort)
if err := http.ListenAndServe(fmt.Sprintf(":%d", *serverPort), http.FileServerFS(gdrive)); err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(1)
}
}