2023-07-26 07:01:08 +00:00
/ *
gpas is GVoisin password reset
* /
package main
import (
"bytes"
"errors"
"fmt"
"html/template"
"log"
// "github.com/emersion/go-sasl"
// "github.com/emersion/go-smtp"
"net/smtp"
"github.com/go-ldap/ldap/v3"
// "strings"
b64 "encoding/base64"
)
// type InvitationAccount struct {
// UID string
// Password string
// BaseDN string
// }
// var EMAIL_REGEXP := regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")
func passwordLost ( user User , config * ConfigFile , ldapConn * ldap . Conn ) error {
if user . CN == "" && user . Mail == "" && user . OtherMailbox == "" {
return errors . New ( "Il n'y a pas de quoi identifier l'utilisateur" )
}
searchFilter := "(|"
if user . CN != "" {
searchFilter += "(cn=" + user . UID + ")"
}
if user . Mail != "" {
searchFilter += "(mail=" + user . Mail + ")"
}
if user . OtherMailbox != "" {
searchFilter += "(carLicense=" + user . OtherMailbox + ")"
}
searchFilter += ")"
searchReq := ldap . NewSearchRequest ( config . UserBaseDN , ldap . ScopeSingleLevel , ldap . NeverDerefAliases , 0 , 0 , false , searchFilter , [ ] string { "cn" , "uid" , "mail" , "carLicense" , "sn" , "displayName" , "givenName" } , nil )
searchRes , err := ldapConn . Search ( searchReq )
if err != nil {
2023-07-26 11:29:31 +00:00
log . Printf ( "passwordLost search : %v %v" , err , ldapConn )
log . Printf ( "passwordLost search : %v" , searchReq )
log . Printf ( "passwordLost search : %v" , searchRes )
log . Printf ( "passwordLost search: %v" , user )
2023-07-26 07:01:08 +00:00
return err
}
if len ( searchRes . Entries ) == 0 {
log . Printf ( "Il n'y a pas d'utilisateur qui correspond %v" , searchReq )
return errors . New ( "Il n'y a pas d'utilisateur qui correspond" )
}
2023-07-26 11:29:31 +00:00
// log.Printf("passwordLost 58 : %v", user)
// log.Printf("passwordLost 59 : %v", searchRes.Entries[0])
// log.Printf("passwordLost 60 : %v", searchRes.Entries[0].GetAttributeValue("cn"))
// log.Printf("passwordLost 61 : %v", searchRes.Entries[0].GetAttributeValue("uid"))
// log.Printf("passwordLost 62 : %v", searchRes.Entries[0].GetAttributeValue("mail"))
// log.Printf("passwordLost 63 : %v", searchRes.Entries[0].GetAttributeValue("carLicense"))
2023-07-26 07:01:08 +00:00
// Préparation du courriel à envoyer
user . Password = suggestPassword ( )
code := b64 . URLEncoding . EncodeToString ( [ ] byte ( user . UID + ";" + user . Password ) )
2023-07-26 12:51:03 +00:00
2023-07-26 11:03:45 +00:00
user . DN = "uid=" + searchRes . Entries [ 0 ] . GetAttributeValue ( "cn" ) + "," + config . InvitationBaseDN
2023-07-26 07:01:08 +00:00
user . UID = searchRes . Entries [ 0 ] . GetAttributeValue ( "cn" )
user . CN = searchRes . Entries [ 0 ] . GetAttributeValue ( "cn" )
user . Mail = searchRes . Entries [ 0 ] . GetAttributeValue ( "mail" )
user . OtherMailbox = searchRes . Entries [ 0 ] . GetAttributeValue ( "carLicense" )
/* Check for outstanding invitation */
2023-07-26 12:33:48 +00:00
searchReq = ldap . NewSearchRequest ( config . InvitationBaseDN , ldap . ScopeSingleLevel ,
2023-07-26 07:01:08 +00:00
ldap . NeverDerefAliases , 0 , 0 , false , "(uid=" + user . UID + ")" , [ ] string { "seeAlso" } , nil )
searchRes , err = ldapConn . Search ( searchReq )
if err != nil {
log . Printf ( fmt . Sprintf ( "passwordLost (Check existing invitation) : %v" , err ) )
log . Printf ( fmt . Sprintf ( "passwordLost (Check existing invitation) : %v" , user ) )
return err
}
2023-07-26 12:43:00 +00:00
// if len(searchRes.Entries) == 0 {
/* Add the invitation */
addReq := ldap . NewAddRequest (
"uid=" + user . UID + "," + config . InvitationBaseDN ,
nil )
addReq . Attribute ( "objectClass" , [ ] string { "top" , "account" , "simpleSecurityObject" } )
addReq . Attribute ( "uid" , [ ] string { user . UID } )
addReq . Attribute ( "userPassword" , [ ] string { suggestPassword ( ) } )
2023-07-26 12:53:44 +00:00
addReq . Attribute ( "seeAlso" , [ ] string { config . UserNameAttr + "=" + user . UID + "," + config . UserBaseDN } )
2023-07-26 12:43:00 +00:00
err = ldapConn . Add ( addReq )
if err != nil {
log . Printf ( "passwordLost 83 : %v" , err )
log . Printf ( "passwordLost 84 : %v" , user )
2023-07-26 12:44:48 +00:00
log . Printf ( "passwordLost 84 : %v" , addReq )
2023-07-26 12:43:00 +00:00
// // log.Printf("passwordLost 85 : %v", searchRes.Entries[0]))
// // For some reason I get here even if the entry exists already
// return err
2023-07-26 07:01:08 +00:00
}
2023-07-26 12:43:00 +00:00
// }
2023-07-26 11:29:31 +00:00
ldapNewConn , err := openNewUserLdap ( config )
2023-07-26 07:01:08 +00:00
if err != nil {
2023-07-26 11:29:31 +00:00
log . Printf ( "passwordLost openNewUserLdap : %v" , err )
}
err = passwd ( user , config , ldapNewConn )
if err != nil {
log . Printf ( "passwordLost passwd : %v" , err )
2023-07-26 12:15:46 +00:00
log . Printf ( "passwordLost passwd : %v" , user )
log . Printf ( "passwordLost passwd : %v" , searchRes . Entries [ 0 ] )
2023-07-26 07:01:08 +00:00
return err
}
2023-07-26 07:18:12 +00:00
templateMail := template . Must ( template . ParseFiles ( templatePath + "/passwd/lost_password_email.txt" ) )
2023-07-26 07:01:08 +00:00
buf := bytes . NewBuffer ( [ ] byte { } )
templateMail . Execute ( buf , & CodeMailFields {
To : user . OtherMailbox ,
From : config . MailFrom ,
InviteFrom : user . UID ,
Code : code ,
WebBaseAddress : config . WebAddress ,
} )
// message := []byte("Hi " + user.OtherMailbox)
log . Printf ( "Sending mail to: %s" , user . OtherMailbox )
// var auth sasl.Client = nil
// if config.SMTPUsername != "" {
// auth = sasl.NewPlainClient("", config.SMTPUsername, config.SMTPPassword)
// }
message := buf . Bytes ( )
auth := smtp . PlainAuth ( "" , config . SMTPUsername , config . SMTPPassword , config . SMTPServer )
log . Printf ( "auth: %v" , auth )
err = smtp . SendMail ( config . SMTPServer + ":587" , auth , config . SMTPUsername , [ ] string { user . OtherMailbox } , message )
if err != nil {
log . Printf ( "email send error %v" , err )
return err
}
log . Printf ( "Mail sent." )
2023-07-26 12:15:46 +00:00
return err
2023-07-26 07:01:08 +00:00
}
func passwordFound ( user User , config * ConfigFile , ldapConn * ldap . Conn ) ( string , error ) {
l , err := openLdap ( config )
if err != nil {
2023-07-26 11:36:10 +00:00
log . Printf ( "passwordFound openLdap %v" , err )
// log.Printf("passwordFound openLdap Config : %v", config)
2023-07-26 07:01:08 +00:00
return "" , err
}
if user . DN == "" && user . UID != "" {
2023-07-26 11:29:31 +00:00
user . DN = "uid=" + user . UID + "," + config . InvitationBaseDN
2023-07-26 07:01:08 +00:00
}
err = l . Bind ( user . DN , user . Password )
if err != nil {
2023-07-26 11:36:10 +00:00
log . Printf ( "passwordFound l.Bind %v" , err )
log . Printf ( "passwordFound l.Bind %v" , user . DN )
log . Printf ( "passwordFound l.Bind %v" , user . UID )
2023-07-26 07:01:08 +00:00
return "" , err
}
searchReq := ldap . NewSearchRequest ( user . DN , ldap . ScopeBaseObject ,
ldap . NeverDerefAliases , 0 , 0 , false , "(uid=" + user . UID + ")" , [ ] string { "seeAlso" } , nil )
var searchRes * ldap . SearchResult
searchRes , err = ldapConn . Search ( searchReq )
if err != nil {
log . Printf ( "passwordFound %v" , err )
log . Printf ( "passwordFound %v" , searchReq )
log . Printf ( "passwordFound %v" , ldapConn )
log . Printf ( "passwordFound %v" , searchRes )
return "" , err
}
if len ( searchRes . Entries ) == 0 {
log . Printf ( "passwordFound %v" , err )
log . Printf ( "passwordFound %v" , searchReq )
log . Printf ( "passwordFound %v" , ldapConn )
log . Printf ( "passwordFound %v" , searchRes )
return "" , err
}
2023-07-26 08:35:11 +00:00
delReq := ldap . NewDelRequest ( "uid=" + user . CN + "," + config . InvitationBaseDN , nil )
ldapConn . Del ( delReq )
2023-07-26 07:01:08 +00:00
return searchRes . Entries [ 0 ] . GetAttributeValue ( "seeAlso" ) , err
}