register/reguser/main.go

98 lines
2.3 KiB
Go
Raw Normal View History

2018-11-07 18:00:06 +00:00
package main
import (
"strings"
"flag"
"bytes"
"strconv"
"fmt"
"os"
"os/user"
"os/exec"
"encoding/json"
"io/ioutil"
"log"
"github.com/tilde-cat/register"
)
var verbose = flag.Bool("v", false, "verbose")
var dry = flag.Bool("dry", true, "dry run")
func readRequest(path string) (*register.Request, error) {
b, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
var r register.Request
err = json.Unmarshal(b, &r)
return &r, err
}
func shell(cmd string, args... string) {
var errOut bytes.Buffer
c := exec.Command(cmd, args...)
c.Stderr = &errOut
if err := c.Run(); err != nil {
log.Fatalf("%v failed:\n%v", cmd, errOut.String())
os.Exit(1)
}
}
func fixKey(key string) string {
return strings.Replace(strings.Replace(key, "\n", "", -1), "\r", "", -1)
}
func main() {
flag.Parse()
if len(flag.Args()) != 1 {
fmt.Fprintf(os.Stderr, "usage: %s [OPTIONS] file\n", os.Args[0])
flag.PrintDefaults()
os.Exit(1)
}
path := flag.Arg(0)
r, err := readRequest(path)
if err != nil {
log.Fatalf("Failed to read request: %v", err)
}
if *verbose || *dry {
log.Printf("Username: '%v'\n", r.Username)
log.Printf("Email: '%v'\n", r.Email)
log.Printf("Why:\n%v\n", r.Why)
log.Printf("SSH key:\n%v\n", r.SSHPublicKey)
log.Printf("Status: '%v'\n", r.Status)
}
if r.Status != "Pending" {
log.Fatalf("This request is not pending")
}
if *dry {
log.Println("dry run ends")
return
}
shell("adduser", "--disabled-login", "--gecos", "", r.Username)
authorizedKeysPath := "/home/"+r.Username+"/.ssh/authorized_keys"
if err = ioutil.WriteFile(authorizedKeysPath, []byte(fixKey(r.SSHPublicKey)), 0664); err != nil {
log.Fatal("sshkey instalation failed: %v", err)
}
user, err := user.Lookup(r.Username)
if err != nil {
log.Fatalf("Failed to get user '%v': %v", r.Username, err)
}
if *verbose {
log.Printf("user: %#v\n", user)
}
userId, _ := strconv.Atoi(user.Uid)
groupId, _ := strconv.Atoi(user.Gid)
if err := os.Chown(authorizedKeysPath, userId, groupId); err != nil {
log.Fatal("chown failed: %v", err)
}
r.Status = "Account created"
b, err := json.MarshalIndent(r, "", "\t")
if err != nil {
log.Fatalf("Failed to serialize request: %v\n", err)
}
if err := ioutil.WriteFile(path, b, 0666); err != nil {
log.Fatalf("Failed to save request: %v\n", err)
}
}