Initial commit
This commit is contained in:
137
cmd/lsf/main.go
Normal file
137
cmd/lsf/main.go
Normal file
@@ -0,0 +1,137 @@
|
||||
// Command lsf provides functions to use the lsf with the commandline.
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
||||
"git.marceltransier.de/lsf"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/crypto/ssh/terminal"
|
||||
)
|
||||
|
||||
var (
|
||||
sessionCache string
|
||||
username string
|
||||
)
|
||||
|
||||
func init() {
|
||||
homeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defaultCacheDir := path.Join(homeDir, ".cache/go-lsf/sessions")
|
||||
flag.StringVar(&sessionCache, "session-cache", defaultCacheDir, "path where the session tokens are located")
|
||||
flag.StringVar(&username, "username", "", "username to login with in lsf")
|
||||
flag.Parse()
|
||||
|
||||
err = os.MkdirAll(sessionCache, os.ModePerm)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
if len(username) == 0 {
|
||||
var err error
|
||||
username, err = readUsername()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
s, err := session(username)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fmt.Printf("s: %+v\n", s)
|
||||
}
|
||||
|
||||
func readUsername() (string, error) {
|
||||
var username string
|
||||
fmt.Print("Username: ")
|
||||
_, err := fmt.Scanf("%s", &username)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "could not read username")
|
||||
}
|
||||
return username, nil
|
||||
}
|
||||
|
||||
func readPassword() (string, error) {
|
||||
var password string
|
||||
fmt.Print("Password: ")
|
||||
b, err := terminal.ReadPassword(int(syscall.Stdin))
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "could not read password")
|
||||
}
|
||||
fmt.Print("\n")
|
||||
password = string(b)
|
||||
return password, nil
|
||||
}
|
||||
|
||||
func session(username string) (*lsf.Session, error) {
|
||||
sessionPath := path.Join(sessionCache, username)
|
||||
sessionFile, err := os.Open(sessionPath)
|
||||
if err != nil {
|
||||
pErr, ok := err.(*os.PathError)
|
||||
if !ok {
|
||||
return nil, err
|
||||
}
|
||||
errno, ok := pErr.Unwrap().(syscall.Errno)
|
||||
if !ok {
|
||||
return nil, err
|
||||
}
|
||||
if errno != syscall.ENOENT {
|
||||
log.Fatal(err)
|
||||
}
|
||||
log.Printf("no session for %s cached\n", username)
|
||||
return login(username)
|
||||
}
|
||||
defer sessionFile.Close()
|
||||
|
||||
b, err := ioutil.ReadAll(sessionFile)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "could not read session file %s", sessionPath)
|
||||
}
|
||||
sid := strings.TrimSuffix(string(b), "\n")
|
||||
s := &lsf.Session{
|
||||
SID: sid,
|
||||
}
|
||||
valid, err := s.Valid()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not check session")
|
||||
}
|
||||
if !valid {
|
||||
fmt.Println("session is not valid")
|
||||
err := os.Remove(sessionPath)
|
||||
if err != nil {
|
||||
log.Println(errors.Wrap(err, "could not remove invalid session file"))
|
||||
}
|
||||
return login(username)
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func login(username string) (*lsf.Session, error) {
|
||||
password, err := readPassword()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "could not login")
|
||||
}
|
||||
s, err := lsf.Login(username, password)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sessionPath := path.Join(sessionCache, username)
|
||||
err = ioutil.WriteFile(sessionPath, []byte(s.SID), 0666)
|
||||
if err != nil {
|
||||
log.Println(errors.Wrap(err, "could not cache session id"))
|
||||
}
|
||||
return s, nil
|
||||
}
|
Reference in New Issue
Block a user