|
@@ -1,325 +0,0 @@
|
|
|
-package main
|
|
|
-
|
|
|
-import (
|
|
|
- "bufio"
|
|
|
- "bytes"
|
|
|
- "crypto/tls"
|
|
|
- "fmt"
|
|
|
- "log"
|
|
|
- "os"
|
|
|
-
|
|
|
- "github.com/sethvargo/go-password/password"
|
|
|
-
|
|
|
- gomail "gopkg.in/gomail.v2"
|
|
|
- ldap "gopkg.in/ldap.v2"
|
|
|
-
|
|
|
- "text/template"
|
|
|
-
|
|
|
- karmen_client "gogs.carducci-dante.gov.it/karmen/client"
|
|
|
- "gogs.carducci-dante.gov.it/karmen/core/orm"
|
|
|
- karmen_ldap "gogs.carducci-dante.gov.it/karmen/ldap"
|
|
|
- tpl_util "gogs.carducci-dante.gov.it/karmen/util/template"
|
|
|
-)
|
|
|
-
|
|
|
-const (
|
|
|
- Remove = iota + 1
|
|
|
- Add
|
|
|
- Update
|
|
|
-)
|
|
|
-
|
|
|
-type Action struct {
|
|
|
- Id int
|
|
|
- Type int
|
|
|
-}
|
|
|
-
|
|
|
-var actDict = map[int]string{
|
|
|
- 1: "REMOVE",
|
|
|
- 2: "ADD",
|
|
|
- 3: "UPDATE",
|
|
|
-}
|
|
|
-
|
|
|
-func diff(dst []string, src []string, excludes []string) map[string]*Action {
|
|
|
- actions := make(map[string]*Action)
|
|
|
-
|
|
|
- for id, el := range dst {
|
|
|
- if !excluded(excludes, el) {
|
|
|
- actions[el] = &Action{id, Remove}
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- for id, el := range src {
|
|
|
- _, ok := actions[el]
|
|
|
- if !ok {
|
|
|
- actions[el] = &Action{id, Add}
|
|
|
- continue
|
|
|
- }
|
|
|
- actions[el] = &Action{id, Update}
|
|
|
- }
|
|
|
-
|
|
|
- return actions
|
|
|
-}
|
|
|
-
|
|
|
-func entriesToSliceFunc(elements []*ldap.Entry, fn func(*ldap.Entry) string) (result []string) {
|
|
|
- for _, el := range elements {
|
|
|
- result = append(result, fn(el))
|
|
|
- }
|
|
|
- return result
|
|
|
-}
|
|
|
-
|
|
|
-func teachersToSliceFunc(elements []*orm.Teacher, fn func(*orm.Teacher) string) (result []string) {
|
|
|
- for _, el := range elements {
|
|
|
- result = append(result, fn(el))
|
|
|
- }
|
|
|
- return result
|
|
|
-}
|
|
|
-
|
|
|
-func excluded(excludes []string, name string) bool {
|
|
|
- for _, excluded := range excludes {
|
|
|
- if name == excluded {
|
|
|
- return true
|
|
|
- }
|
|
|
- }
|
|
|
- return false
|
|
|
-}
|
|
|
-
|
|
|
-func filterTeachers(teachers []*orm.Teacher, excludes []string) []*orm.Teacher {
|
|
|
- fTeachers := teachers[:0]
|
|
|
- for _, t := range teachers {
|
|
|
- if t.Name != "Senza nome" && !excluded(excludes, t.CompleteName()) {
|
|
|
- fTeachers = append(fTeachers, t)
|
|
|
- }
|
|
|
- }
|
|
|
- return fTeachers
|
|
|
-}
|
|
|
-
|
|
|
-func sendMail(teacher *orm.Teacher, tpl *template.Template, dryRun bool) error {
|
|
|
- var buf bytes.Buffer
|
|
|
-
|
|
|
- err := tpl.Execute(&buf, teacher)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
-
|
|
|
- log.Printf("Send mail to %s", teacher.AltEmail)
|
|
|
-
|
|
|
- if !dryRun {
|
|
|
- m := gomail.NewMessage()
|
|
|
- m.SetHeader("From", "karmen@carducci-dante.gov.it")
|
|
|
- m.SetHeader("To", teacher.AltEmail)
|
|
|
- // m.SetHeader("To", "segreteria.automatica@carducci-dante.gov.it")
|
|
|
- m.SetHeader("Subject", "Credenziali servizi informatici del Liceo \"Carducci-Dante\" di Trieste")
|
|
|
- m.SetBody("text/plain", buf.String())
|
|
|
-
|
|
|
- d := gomail.NewDialer("smtps.aruba.it", 465, "postmaster@carducci-dante.gov.it", `8Eoda43e17`)
|
|
|
- d.TLSConfig = &tls.Config{InsecureSkipVerify: true}
|
|
|
-
|
|
|
- if err := d.DialAndSend(m); err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- }
|
|
|
- return nil
|
|
|
-}
|
|
|
-
|
|
|
-func syncTeachers(ldapClient *karmen_ldap.Client, karmenClient *karmen_client.Client, ldapTeachers []*ldap.Entry, teachers []*orm.Teacher, excludes []string, mailTpl *template.Template) error {
|
|
|
- actions := diff(
|
|
|
- entriesToSliceFunc(ldapTeachers, func(entry *ldap.Entry) string { return entry.DN }),
|
|
|
- teachersToSliceFunc(teachers, func(t *orm.Teacher) string { return ldapClient.TeacherDN(t) }),
|
|
|
- excludes,
|
|
|
- )
|
|
|
-
|
|
|
- for el, act := range actions {
|
|
|
- switch act.Type {
|
|
|
- case Remove:
|
|
|
- err := ldapClient.DeleteByDN(el)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- case Add:
|
|
|
- teacher := teachers[act.Id]
|
|
|
- log.Printf("ADD teacher %s", teacher.CompleteName())
|
|
|
- password, err := password.Generate(8, 2, 0, false, true)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- teacher.PlainPassword = password
|
|
|
- err = ldapClient.AddTeacher(teacher)
|
|
|
- if err != nil {
|
|
|
- panic(err)
|
|
|
- }
|
|
|
-
|
|
|
- if !teacher.MailSent {
|
|
|
- log.Printf("Sending credentials to %s, pw is %s", teacher.AltEmail, teacher.PlainPassword)
|
|
|
- err = sendMail(teacher, mailTpl, false)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- teacher.MailSent = true
|
|
|
- err = karmenClient.UpdateTeacher(teacher)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // case Update:
|
|
|
- // // teacher := teachers[act.Id]
|
|
|
- // // log.Printf("UPDATE teacher %s", teacher.CompleteName())
|
|
|
- // // err = ldapClient.UpdateTeacher(teacher)
|
|
|
- // // if err != nil {
|
|
|
- // // panic(err)
|
|
|
- // // }
|
|
|
-
|
|
|
- }
|
|
|
- }
|
|
|
- return nil
|
|
|
-}
|
|
|
-
|
|
|
-func syncMailingList(ldapClient *karmen_ldap.Client, teachers []*orm.Teacher, excludes []string, groupDN string) error {
|
|
|
- entries, err := ldapClient.GroupMembers(groupDN)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
-
|
|
|
- actions := diff(
|
|
|
- entries[0].Attributes[0].Values,
|
|
|
- teachersToSliceFunc(teachers, func(t *orm.Teacher) string { return ldapClient.TeacherDN(t) }),
|
|
|
- excludes,
|
|
|
- )
|
|
|
-
|
|
|
- for el, act := range actions {
|
|
|
- switch act.Type {
|
|
|
- case Remove:
|
|
|
- log.Printf("REMOVE teacher %s from %s", el, groupDN)
|
|
|
- ldapClient.RemoveTeacherFromGroupByMemberValue(el, groupDN)
|
|
|
- case Add:
|
|
|
- log.Printf("ADD teacher %s to %s", el, groupDN)
|
|
|
- teacher := teachers[act.Id]
|
|
|
- err = ldapClient.AddTeacherToGroup(teacher, groupDN)
|
|
|
- if err != nil {
|
|
|
- panic(err)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return nil
|
|
|
-}
|
|
|
-
|
|
|
-func syncTeachersGroup(ldapClient *karmen_ldap.Client, teachers []*orm.Teacher, excludes []string, groupDN string) error {
|
|
|
- entries, err := ldapClient.GroupMembers(groupDN)
|
|
|
- if err != nil {
|
|
|
- return err
|
|
|
- }
|
|
|
-
|
|
|
- actions := diff(
|
|
|
- entries[0].Attributes[0].Values,
|
|
|
- teachersToSliceFunc(teachers, func(t *orm.Teacher) string { return t.Username() }),
|
|
|
- excludes,
|
|
|
- )
|
|
|
-
|
|
|
- for el, act := range actions {
|
|
|
- switch act.Type {
|
|
|
- case Remove:
|
|
|
- log.Printf("REMOVE teacher %s from %s", el, groupDN)
|
|
|
- ldapClient.RemoveTeacherFromGroupByMemberValue(el, groupDN)
|
|
|
- case Add:
|
|
|
- log.Printf("ADD teacher %s to %s", el, groupDN)
|
|
|
- teacher := teachers[act.Id]
|
|
|
- err = ldapClient.AddTeacherToGroup(teacher, groupDN)
|
|
|
- if err != nil {
|
|
|
- panic(err)
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
- }
|
|
|
- return nil
|
|
|
-}
|
|
|
-
|
|
|
-func main() {
|
|
|
- log.Printf("Connecting to karmen at %s...", "https://karmen.andreafazzi.eu")
|
|
|
- karmenClient, err := karmen_client.Dial("https://karmen.andreafazzi.eu", "admin", "aolieVooju")
|
|
|
- if err != nil {
|
|
|
- panic(err)
|
|
|
- }
|
|
|
-
|
|
|
- teachers, err := karmenClient.GetTeachers()
|
|
|
- if err != nil {
|
|
|
- panic(err)
|
|
|
- }
|
|
|
-
|
|
|
- departments, err := karmenClient.GetDepartments()
|
|
|
- if err != nil {
|
|
|
- panic(err)
|
|
|
- }
|
|
|
-
|
|
|
- conf := &karmen_ldap.Config{
|
|
|
- Domain: "carducci-dante.gov.it",
|
|
|
- AdminCN: "admin",
|
|
|
- AdminPassword: "CDlinux2016",
|
|
|
- TeachersDN: "ou=Docenti,ou=Persone",
|
|
|
- GroupsDN: "ou=Gruppi",
|
|
|
- PeopleDN: "ou=Persone",
|
|
|
- MailDirPath: "/var/mail/carducci-dante.gov.it",
|
|
|
- MailQuota: "10240",
|
|
|
- FirstUIDNumber: "5000",
|
|
|
- MailGIDNumber: "5000",
|
|
|
- }
|
|
|
-
|
|
|
- log.Printf("Connecting to LDAP at %s...", "ldap.carducci-dante.gov.it:389")
|
|
|
- ldapClient, err := karmen_ldap.NewClient("ldap.carducci-dante.gov.it:389", conf)
|
|
|
- if err != nil {
|
|
|
- panic(err)
|
|
|
- }
|
|
|
-
|
|
|
- log.Println("Getting LDAP registered teachers...")
|
|
|
- ldapTeachers, err := ldapClient.Teachers()
|
|
|
- if err != nil {
|
|
|
- panic(err)
|
|
|
- }
|
|
|
-
|
|
|
- excludes := make([]string, 0)
|
|
|
- log.Print("Read excludes...")
|
|
|
- f, err := os.Open("./excludes.txt")
|
|
|
- defer f.Close()
|
|
|
- if err != nil {
|
|
|
- log.Println(err)
|
|
|
- } else {
|
|
|
- scanner := bufio.NewScanner(f)
|
|
|
- for scanner.Scan() {
|
|
|
- excludes = append(excludes, scanner.Text())
|
|
|
- }
|
|
|
-
|
|
|
- if err := scanner.Err(); err != nil {
|
|
|
- panic(err)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- tpl, err := tpl_util.LoadTextTemplate("mail.tpl")
|
|
|
- if err != nil {
|
|
|
- panic(err)
|
|
|
- }
|
|
|
-
|
|
|
- fTeachers := filterTeachers(teachers, excludes)
|
|
|
-
|
|
|
- err = syncTeachers(ldapClient, karmenClient, ldapTeachers, fTeachers, excludes, tpl)
|
|
|
- if err != nil {
|
|
|
- panic(err)
|
|
|
- }
|
|
|
-
|
|
|
- for _, department := range departments {
|
|
|
- group := fmt.Sprintf("cn=%s,ou=Mailing Lists", department.Name)
|
|
|
- err = syncMailingList(ldapClient, filterTeachers(department.Teachers, excludes), excludes, group)
|
|
|
- if err != nil {
|
|
|
- panic(err)
|
|
|
- }
|
|
|
- group = fmt.Sprintf("cn=%s,ou=Dipartimenti", department.Name)
|
|
|
- err = syncTeachersGroup(ldapClient, filterTeachers(department.Teachers, excludes), excludes, group)
|
|
|
- if err != nil {
|
|
|
- panic(err)
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- err = syncTeachersGroup(ldapClient, fTeachers, excludes, "cn=Docenti")
|
|
|
- if err != nil {
|
|
|
- panic(err)
|
|
|
- }
|
|
|
-
|
|
|
-}
|