Unifi login
This commit is contained in:
1
go.mod
1
go.mod
@@ -7,4 +7,5 @@ require (
|
|||||||
github.com/mdlayher/lldp v0.0.0-20150915211757-afd9f83164c5
|
github.com/mdlayher/lldp v0.0.0-20150915211757-afd9f83164c5
|
||||||
github.com/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065
|
github.com/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065
|
||||||
github.com/vishvananda/netlink v1.1.0
|
github.com/vishvananda/netlink v1.1.0
|
||||||
|
gopkg.in/yaml.v2 v2.3.0
|
||||||
)
|
)
|
||||||
|
|||||||
3
go.sum
3
go.sum
@@ -21,3 +21,6 @@ golang.org/x/sys v0.0.0-20190606122018-79a91cf218c4/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444 h1:/d2cWp6PSamH4jDPFLyO150psQdqvtoNX8Zjg3AQ31g=
|
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444 h1:/d2cWp6PSamH4jDPFLyO150psQdqvtoNX8Zjg3AQ31g=
|
||||||
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||||
|
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
|||||||
14
main.go
14
main.go
@@ -31,11 +31,23 @@ func main() {
|
|||||||
}
|
}
|
||||||
log.Printf("UniFi API URL: %s", api)
|
log.Printf("UniFi API URL: %s", api)
|
||||||
|
|
||||||
|
/*
|
||||||
upstream, err := getUpstream(link.Attrs().Name)
|
upstream, err := getUpstream(link.Attrs().Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
log.Printf("Connected to %s [%s] on %s", upstream.device, upstream.addr, upstream.port)
|
log.Printf("Connected to %s [%s] on %s", upstream.device, upstream.addr, upstream.port)
|
||||||
|
*/
|
||||||
|
|
||||||
|
unifi, err := NewClient(api)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = unifi.Login()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type upstream struct {
|
type upstream struct {
|
||||||
@@ -137,7 +149,7 @@ func findApis(start_ip, end_ip uint32) ([]string, error) {
|
|||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
url := fmt.Sprintf(
|
url := fmt.Sprintf(
|
||||||
"https://%d.%d.%d.%d/",
|
"https://%d.%d.%d.%d",
|
||||||
ip >> 24 & 0xff,
|
ip >> 24 & 0xff,
|
||||||
ip >> 16 & 0xff,
|
ip >> 16 & 0xff,
|
||||||
ip >> 8 & 0xff,
|
ip >> 8 & 0xff,
|
||||||
|
|||||||
164
unifi.go
Normal file
164
unifi.go
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"crypto/tls"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"net/http/cookiejar"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"gopkg.in/yaml.v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Client struct {
|
||||||
|
http_client *http.Client
|
||||||
|
base_url string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewClient(base_url string) (*Client, error) {
|
||||||
|
jar, err := cookiejar.New(nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Client{
|
||||||
|
http_client: &http.Client{
|
||||||
|
Timeout: 5 * time.Second,
|
||||||
|
Transport: &http.Transport{
|
||||||
|
TLSClientConfig: &tls.Config{
|
||||||
|
InsecureSkipVerify: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Jar: jar,
|
||||||
|
},
|
||||||
|
base_url: base_url,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type Creds struct {
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ErrorResp struct {
|
||||||
|
Errors []string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) Login() error {
|
||||||
|
needSave := false
|
||||||
|
|
||||||
|
creds, err := loadCreds()
|
||||||
|
if err != nil {
|
||||||
|
creds, err = promptCreds()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
needSave = true
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := json.Marshal(creds)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest("POST", fmt.Sprintf("%s/api/auth/login", c.base_url), bytes.NewBuffer(body))
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
resp, err := c.http_client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
dec := json.NewDecoder(resp.Body)
|
||||||
|
error_resp := ErrorResp{}
|
||||||
|
err = dec.Decode(&error_resp)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return fmt.Errorf("Failed to log into UniFi with saved credentials (\"%s\"). Delete %s to prompt again.", error_resp.Errors[0], credPath())
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Logged into UniFi as %s", creds.Username)
|
||||||
|
|
||||||
|
if needSave {
|
||||||
|
err = creds.Save()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadCreds() (*Creds, error) {
|
||||||
|
fh, err := os.OpenFile(credPath(), os.O_RDONLY, 0)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer fh.Close()
|
||||||
|
|
||||||
|
dec := yaml.NewDecoder(fh)
|
||||||
|
|
||||||
|
ret := &Creds{}
|
||||||
|
|
||||||
|
err = dec.Decode(ret)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func promptCreds() (*Creds, error) {
|
||||||
|
reader := bufio.NewReader(os.Stdin)
|
||||||
|
|
||||||
|
fmt.Print("UniFi username: ")
|
||||||
|
username, err := reader.ReadString('\n')
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Print("UniFi password: ")
|
||||||
|
password, err := reader.ReadString('\n')
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Creds{
|
||||||
|
Username: strings.TrimSuffix(username, "\n"),
|
||||||
|
Password: strings.TrimSuffix(password, "\n"),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Creds) Save() error {
|
||||||
|
fh, err := os.OpenFile(credPath(), os.O_WRONLY|os.O_CREATE, 0600)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer fh.Close()
|
||||||
|
|
||||||
|
enc := yaml.NewEncoder(fh)
|
||||||
|
defer enc.Close()
|
||||||
|
|
||||||
|
err = enc.Encode(c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Printf("Saved credentials to %s", credPath())
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func credPath() string {
|
||||||
|
return path.Join(os.Getenv("HOME"), ".netperfect.creds")
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user