Nuestro burocrata preferido: Sam Lowry
https://lowry.sindominio.net
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
141 lines
4.3 KiB
141 lines
4.3 KiB
package main |
|
|
|
import ( |
|
"bufio" |
|
"log" |
|
"os" |
|
"sort" |
|
"strings" |
|
"time" |
|
|
|
"git.sindominio.net/sindominio/lowry/db" |
|
"git.sindominio.net/sindominio/lowry/gitea" |
|
"git.sindominio.net/sindominio/lowry/ldap" |
|
"git.sindominio.net/sindominio/lowry/mail" |
|
"git.sindominio.net/sindominio/lowry/server" |
|
"github.com/namsral/flag" |
|
) |
|
|
|
var ( |
|
inviteExpireDuration = time.Hour * 24 * 30 // 30 days |
|
accountExpireDuration = time.Hour * 24 * 90 // 90 days |
|
accountBlockDuration = time.Hour * 24 * 6 * 30 // ~ 6 months |
|
accountDeleteDuration = time.Hour * 24 * 365 // ~ 1 year |
|
) |
|
|
|
func main() { |
|
var ( |
|
ldapaddr = flag.String("ldapaddr", "localhost:389", "LDAP server address and port") |
|
domain = flag.String("domain", "", "LDAP domain components") |
|
ldappass = flag.String("ldappass", "", "Password of the LDAP `admin' user") |
|
homepath = flag.String("homepath", "/home/", "Path to the user homes") |
|
smtpaddr = flag.String("smtpaddr", "localhost:25", "The address of the smtp server to send email") |
|
email = flag.String("email", "", "The email address to send notifications from") |
|
emailpass = flag.String("emailpass", "", "The password of the email address") |
|
httpaddr = flag.String("httpaddr", ":8080", "Web server address and port") |
|
dbpath = flag.String("dbpath", "bolt.db", "The path to store the lowry status database") |
|
ro = flag.Bool("ro", false, "Read-Only mode") |
|
giteaURL = flag.String("giteaURL", "", "Gitea server address") |
|
token = flag.String("token", "", "Gitea admin token") |
|
cloneAddr = flag.String("cloneAddr", "", "Template repo address to copy") |
|
webhookRepoSecret = flag.String("webhookRepoSecret", "", "Webhook secret of the created repo") |
|
webhookRepoURL = flag.String("webhookRepoURL", "", "Webhook url of the created repo") |
|
webhookURL = flag.String("webhookURL", "", "Webhook URL to send user keys") |
|
webhookSecret = flag.String("webhookSecret", "", "Webhook Secret to send user keys") |
|
) |
|
flag.String(flag.DefaultConfigFlagname, "/etc/lowry.conf", "Path to configuration file") |
|
flag.Parse() |
|
|
|
m := mail.Init(*email, *emailpass, *smtpaddr, *domain) |
|
l := ldap.Ldap{ |
|
Addr: *ldapaddr, |
|
Domain: *domain, |
|
Pass: *ldappass, |
|
HomePath: *homepath, |
|
RO: *ro, |
|
} |
|
err := l.Init() |
|
if err != nil { |
|
log.Fatal(err) |
|
} |
|
g := gitea.Init(*giteaURL, *token, *cloneAddr, *webhookRepoURL, *webhookRepoSecret, *webhookURL, *webhookSecret) |
|
|
|
go updateUsers(l) |
|
|
|
ldb, err := db.Init(*dbpath) |
|
if err != nil { |
|
log.Fatal(err) |
|
} |
|
defer ldb.Close() |
|
go cleanInvites(ldb) |
|
|
|
log.Fatal(server.Serve(*httpaddr, &l, m, ldb, g)) |
|
} |
|
|
|
func updateUsers(l ldap.Ldap) { |
|
for { |
|
users, err := l.ListUsers() |
|
if err != nil { |
|
log.Printf("Error listing users for locking: %v", err) |
|
time.Sleep(time.Minute * 61) |
|
continue |
|
} |
|
|
|
for _, u := range users { |
|
if u.Shell == "/bin/false" && u.Role == ldap.Sindominante { |
|
err := l.ChangeShell(u.Name, "/bin/bash") |
|
if err != nil { |
|
log.Println("An error ocurred changing shell of '", u.Name, "': ", err) |
|
} |
|
} |
|
|
|
newLocked := ldap.Unknown |
|
sinceLastLogin := time.Now().Sub(u.LastLogin) |
|
if u.Locked != ldap.Deleted && sinceLastLogin > accountDeleteDuration { |
|
newLocked = ldap.Deleted |
|
} else if u.Locked != ldap.Blocked && sinceLastLogin > accountBlockDuration && sinceLastLogin < accountDeleteDuration { |
|
newLocked = ldap.Blocked |
|
} else { |
|
continue |
|
} |
|
|
|
err = l.ChangeLocked(u.Name, newLocked) |
|
if err != nil { |
|
log.Printf("Error changing locked to %s for user %s: %v", newLocked.String(), u.Name, err) |
|
} |
|
if u.Role == ldap.Sindominante { |
|
err = l.ChangeRole(u.Name, ldap.Amiga) |
|
if err != nil { |
|
log.Printf("Error changing role for blocked user %s: %v", u.Name, err) |
|
} |
|
} |
|
} |
|
|
|
time.Sleep(time.Minute * 61) |
|
} |
|
} |
|
|
|
func cleanInvites(ldb *db.DB) { |
|
for { |
|
ldb.ExpireInvites(inviteExpireDuration) |
|
ldb.ExpireAccounts(accountExpireDuration) |
|
time.Sleep(time.Minute * 60) |
|
} |
|
} |
|
|
|
func readUserList(listPath string) []string { |
|
f, err := os.Open(listPath) |
|
if err != nil { |
|
log.Fatal(err) |
|
} |
|
defer f.Close() |
|
|
|
list := []string{} |
|
scanner := bufio.NewScanner(f) |
|
for scanner.Scan() { |
|
user := strings.TrimSpace(scanner.Text()) |
|
list = append(list, user) |
|
} |
|
sort.Strings(list) |
|
return list |
|
}
|
|
|