From 1df0b80c1f02045373f064c4534081fd2a45beca Mon Sep 17 00:00:00 2001 From: Paul Wilde Date: Sun, 15 Aug 2021 20:57:30 +0100 Subject: [PATCH 1/6] created gitversion branch --- src/main.go | 20 ++++++++++++++++++++ structs/structs.go | 4 ++++ 2 files changed, 24 insertions(+) create mode 100644 src/main.go create mode 100644 structs/structs.go diff --git a/src/main.go b/src/main.go new file mode 100644 index 0000000..bcb977f --- /dev/null +++ b/src/main.go @@ -0,0 +1,20 @@ +package main + +import ( + "fmt" + "net/http" + "log" +) + +func handler(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:]) +} + +func main() { + http.HandleFunc("/", handler) + log.Fatal(http.ListenAndServe(":8080", nil)) +} + +func do_this(){ + fmt.Println("doing this") +} diff --git a/structs/structs.go b/structs/structs.go new file mode 100644 index 0000000..c00292e --- /dev/null +++ b/structs/structs.go @@ -0,0 +1,4 @@ +type Page struct { + Title string + Body []byte +} From acef6e76d7530459416f359b7ec0eefa2ac51330 Mon Sep 17 00:00:00 2001 From: Paul Wilde Date: Sun, 15 Aug 2021 22:16:07 +0100 Subject: [PATCH 2/6] began new go version to lessen resource requirements --- src/global/global.go | 31 ++++++++++++++++++ src/go.mod | 7 ++++ src/go.sum | 2 ++ src/mailautoconf.go | 16 +++++++++ src/main.go | 20 ------------ src/structs/structs.go | 18 ++++++++++ src/templates/autoconfig.html | 58 +++++++++++++++++++++++++++++++++ src/templates/autodiscover.html | 45 +++++++++++++++++++++++++ src/web/handler/handler.go | 32 ++++++++++++++++++ src/web/responses/responses.go | 14 ++++++++ 10 files changed, 223 insertions(+), 20 deletions(-) create mode 100644 src/global/global.go create mode 100644 src/go.mod create mode 100644 src/go.sum create mode 100644 src/mailautoconf.go delete mode 100644 src/main.go create mode 100644 src/structs/structs.go create mode 100644 src/templates/autoconfig.html create mode 100644 src/templates/autodiscover.html create mode 100644 src/web/handler/handler.go create mode 100644 src/web/responses/responses.go diff --git a/src/global/global.go b/src/global/global.go new file mode 100644 index 0000000..a8b7268 --- /dev/null +++ b/src/global/global.go @@ -0,0 +1,31 @@ +package global +import ( + . "mailautoconf/structs" + "github.com/vaughan0/go-ini" + "fmt" +) + +// Global variables +var ThisSession Session +var MainConfig Config +const defaultConfigDir string = "default-config/" +const configDir string = "config/" + +func NewConfig() Config { + fmt.Println("Loading Config…") + cfg := "default-config/config.default.ini" + conf, err := ini.LoadFile(cfg) + if err != nil { + fmt.Println(err.Error()) + } + fmt.Println(conf) + fmt.Println("Loading Services…") + srv := "default-config/services.default.ini" + serv, err2 := ini.LoadFile(srv) + if err2 != nil { + fmt.Println(err2.Error()) + } + fmt.Println(serv) + newcfg := Config{} + return newcfg +} diff --git a/src/go.mod b/src/go.mod new file mode 100644 index 0000000..3bc798b --- /dev/null +++ b/src/go.mod @@ -0,0 +1,7 @@ +module mailautoconf + +go 1.16 + +require ( + github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec // indirect +) diff --git a/src/go.sum b/src/go.sum new file mode 100644 index 0000000..bac961c --- /dev/null +++ b/src/go.sum @@ -0,0 +1,2 @@ +github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec h1:DGmKwyZwEB8dI7tbLt/I/gQuP559o/0FrAkHKlQM/Ks= +github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec/go.mod h1:owBmyHYMLkxyrugmfwE/DLJyW8Ro9mkphwuVErQ0iUw= diff --git a/src/mailautoconf.go b/src/mailautoconf.go new file mode 100644 index 0000000..787a5e9 --- /dev/null +++ b/src/mailautoconf.go @@ -0,0 +1,16 @@ +package main + +import ( + "fmt" + "net/http" + "log" + "mailautoconf/web/handler" + . "mailautoconf/global" +) + +func main() { + MainConfig = NewConfig() + http.HandleFunc("/", handler.WebHandler) + fmt.Println("Starting up Web Listener on port 8080") + log.Fatal(http.ListenAndServe(":8080", nil)) +} diff --git a/src/main.go b/src/main.go deleted file mode 100644 index bcb977f..0000000 --- a/src/main.go +++ /dev/null @@ -1,20 +0,0 @@ -package main - -import ( - "fmt" - "net/http" - "log" -) - -func handler(w http.ResponseWriter, r *http.Request) { - fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:]) -} - -func main() { - http.HandleFunc("/", handler) - log.Fatal(http.ListenAndServe(":8080", nil)) -} - -func do_this(){ - fmt.Println("doing this") -} diff --git a/src/structs/structs.go b/src/structs/structs.go new file mode 100644 index 0000000..46db476 --- /dev/null +++ b/src/structs/structs.go @@ -0,0 +1,18 @@ +package structs +// I don't like the name of this package, consider naming it "core" or +// separating out the structs and core functions + +import "net/http" + +type Session struct { + ResponseWriter http.ResponseWriter + Request *http.Request + Path string + WebContent string +} +type Config struct { + Services []Service +} +type Service struct { + +} diff --git a/src/templates/autoconfig.html b/src/templates/autoconfig.html new file mode 100644 index 0000000..2ce1ccb --- /dev/null +++ b/src/templates/autoconfig.html @@ -0,0 +1,58 @@ + + + "> + + + + %EMAILADDRESS% + + "> + + + + get_username($service,$email_address); ?> + + + + "> + + + + get_username($service,$email_address);?> + + + + "> + get_username($service,$email_address);?> + + + + + "> + get_username($service,$email_address);?> + + + + + + " /> + "> + get_username($service,$email_address);?> + " name="" /> + " /> + " name=""/> + + + + + diff --git a/src/templates/autodiscover.html b/src/templates/autodiscover.html new file mode 100644 index 0000000..3a9342b --- /dev/null +++ b/src/templates/autodiscover.html @@ -0,0 +1,45 @@ + + + + + + email + settings + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/web/handler/handler.go b/src/web/handler/handler.go new file mode 100644 index 0000000..cd5d8ce --- /dev/null +++ b/src/web/handler/handler.go @@ -0,0 +1,32 @@ +package handler +import ( + . "mailautoconf/structs" + . "mailautoconf/global" + "mailautoconf/web/responses" + "strings" + "net/http" + "fmt" +) +func WebHandler(w http.ResponseWriter, r *http.Request) { + ThisSession = Session{} + ThisSession.ResponseWriter = w + ThisSession.Request = r + ThisSession.Path = strings.ToLower(r.URL.Path[1:]) + + switch ThisSession.Path { + case "mail/config-v1.1.xml": + ThisSession.WebContent = responses.MozAutoconfig() + case "autodiscover/autodiscover.xml": + ThisSession.WebContent = responses.MsAutoDiscoverXML() + case "autodiscover/autodiscover.json": + ThisSession.WebContent = responses.MsAutoDiscoverJSON() + default: + ThisSession.WebContent = responses.DefaultResponse() + } + + writeWebOutput() +} + +func writeWebOutput () { + fmt.Fprintf(ThisSession.ResponseWriter, ThisSession.WebContent) +} diff --git a/src/web/responses/responses.go b/src/web/responses/responses.go new file mode 100644 index 0000000..8f85c82 --- /dev/null +++ b/src/web/responses/responses.go @@ -0,0 +1,14 @@ +package responses + +func MozAutoconfig() string { + return "" +} +func MsAutoDiscoverXML() string { + return "" +} +func MsAutoDiscoverJSON() string { + return "" +} +func DefaultResponse() string { + return "" +} From c7bf57dab3ff21c3376b74d791e19bc7ff94de48 Mon Sep 17 00:00:00 2001 From: Paul Wilde Date: Mon, 16 Aug 2021 13:21:30 +0100 Subject: [PATCH 3/6] working on troubes with toiml parsing --- src/default-config/config.default.toml | 13 +++ src/default-config/services.default.toml | 121 +++++++++++++++++++++++ src/global/global.go | 103 +++++++++++++++---- src/go.mod | 3 +- src/go.sum | 12 ++- src/mailautoconf.go | 8 +- src/structs/structs.go | 28 +++++- 7 files changed, 260 insertions(+), 28 deletions(-) create mode 100644 src/default-config/config.default.toml create mode 100644 src/default-config/services.default.toml diff --git a/src/default-config/config.default.toml b/src/default-config/config.default.toml new file mode 100644 index 0000000..47015d4 --- /dev/null +++ b/src/default-config/config.default.toml @@ -0,0 +1,13 @@ +# Sample config.ini file. +# Copy this file to "config/config.ini" and adjust the settings to your requirements + +# The URL of this application +BaseURL = "https://autoconfig.example.com" + +# Set the email domains for use with this service. The first one is primary. +# each will need their own DNS A record for autoconfig.domain.name +Domains = ["example.com","example2,com"] + + +# If you use a different domain to authenticate with, enter it here +LogonDomain = "example.local" diff --git a/src/default-config/services.default.toml b/src/default-config/services.default.toml new file mode 100644 index 0000000..70fe484 --- /dev/null +++ b/src/default-config/services.default.toml @@ -0,0 +1,121 @@ +# The Incoming mail Server Config + +[InMail] + # Enable this service +Enabled = true + + # Mail Type, i.e. IMAP, POP3 + Type = "IMAP" + + # Your IMAP server + Server = "imap.example.com" + + # Your IMAP port + Port = 993 + + # The socket type = SSL, STARTTLS, or NONE + SocketType = "SSL" + + # Use Secure Password Authentication + SPA = false + + # Change to true if you need the domain/logondomain to form part of the username + UsernameIsFQDN = false + + # Do you need to authenticate to your mail server? You should! so this should be false! + NoAuthRequired = false + + # Authentication type, + #"password-cleartext" = Send password in the clear + # (dangerous, if SSL isn't used either). + # AUTH PLAIN, LOGIN or protocol-native login. + #"password-encrypted" = A secure encrypted password mechanism. + # Can be CRAM-MD5 or DIGEST-MD5. Not NTLM. + #"NTLM"= Use NTLM (or NTLMv2 or successors), + # the Windows login mechanism. + Authentication = "password-cleartext" + +# +# +# # The Outgoing mail server config +# [OutMail] +# Name = "OutMail" +# +# # Enable this service +# Enabled = true +# +# # Mail type, likely to only be SMTP +# Type = "SMTP" +# +# # Your SMTP server +# Server = "smtp.example.com" +# +# # Your SMTP port +# Port = 465 +# +# # The socket type = SSL, STARTTLS or NONE +# SocketType = "SSL" +# +# # See InMail > Authentication +# Authentication = "password-cleartext" +# +# # Use Secure Password Authentication +# SPA = false +# +# # Change to true if you need the domain/logondomain to form part of the username +# UsernameIsFQDN = false +# +# # Do you need to authenticate to your mail server? You should! so this should be false! +# NoAuthRequired = false +# +# # Use POP Authentication? You probably shouldn't be. +# POPAuth = false +# +# # This setting is here to limit errors, I'm not sure what it does yet. +# SMTPLast = false +# +# +# # Currently not implemented, see https://wiki.mozilla.org/Thunderbird=Autoconfiguration=ConfigFileFormat +# [Calendar] +# Name = "Calendar" +# # Disable this service +# Enabled = false +# Server = "https://example.com/remote.php/dav/" +# Port = 443 +# Type = "CalDAV" +# Authentication = "http-basic" +# UsernameIsFQDN = false +# +# # Currently not implemented, see https://wiki.mozilla.org/Thunderbird=Autoconfiguration=ConfigFileFormat +# [AddressBook] +# Name = "AddressBook" +# # Disable this service +# Enabled = false +# Server = "https://example.com/remote.php/dav/" +# Port = 443 +# Type = "CardDAV" +# Authentication = "http-basic" +# UsernameIsFQDN = false +# +# # Currently not implemented, see https://wiki.mozilla.org/Thunderbird=Autoconfiguration=ConfigFileFormat +# [WebMail] +# Name = "WebMail" +# # Disable this service +# Enabled = false +# Server = "https://mail.example.com" +# UsernameDivID = "username" +# UsernameDivName = "username" +# PasswordDivName = "password" +# SubmitButtonID = "submit" +# SubmitButtonName = "submit" +# UsernameIsFQDN = false +# +# +# # In theory, additional custom services can be configured and will be displayed with +# # their options on the /get/all URL of this service. The third-party clients would need to +# # check this service as part of their development for this to work +# # Will not be shown in autodiscover.xml/json or config-v1.1.xml/autoconfig.xml +# # i.e Nextcloud - ideally a nextcloud client could check autoconfig for this URL for ease of set up +# #[Nextcloud] +# # Name = "NextCloud" +# # Server = "https://nextcloud.example.com" diff --git a/src/global/global.go b/src/global/global.go index a8b7268..8f85a79 100644 --- a/src/global/global.go +++ b/src/global/global.go @@ -1,8 +1,11 @@ package global import ( . "mailautoconf/structs" - "github.com/vaughan0/go-ini" "fmt" + "github.com/pelletier/go-toml/v2" + "io/ioutil" + "os" + ) // Global variables @@ -12,20 +15,86 @@ const defaultConfigDir string = "default-config/" const configDir string = "config/" func NewConfig() Config { - fmt.Println("Loading Config…") - cfg := "default-config/config.default.ini" - conf, err := ini.LoadFile(cfg) - if err != nil { - fmt.Println(err.Error()) - } - fmt.Println(conf) - fmt.Println("Loading Services…") - srv := "default-config/services.default.ini" - serv, err2 := ini.LoadFile(srv) - if err2 != nil { - fmt.Println(err2.Error()) - } - fmt.Println(serv) - newcfg := Config{} - return newcfg + MainConfig = loadConfig() + return MainConfig +} +func loadConfig() Config { + cfg := Config{} + + fmt.Println("Loading Default Config…") + cfgfile := defaultConfigDir + "config.default.toml" + unmarshalConfig(cfgfile, &cfg) + fmt.Println(cfg) + customcfgfile := configDir + "config.toml" + unmarshalConfig(customcfgfile, &cfg) + fmt.Println(cfg) + svcfile := defaultConfigDir + "services.default.toml" + // cfg.Services = []Service{ + // Service{ + // Name : "first", + // }, + // Service{ + // Name : "second", + // }, + // Service{ + // Name : "third", + // }, + // } + // data, _ := toml.Marshal(cfg) + + // ioutil.WriteFile(svcfile, data, 0) + + unmarshalServices(svcfile, &cfg) + + customsvcfile := configDir + "services.toml" + unmarshalServices(customsvcfile, &cfg) + // fmt.Println(cfg) + fmt.Println("\r\nOur Config :") + fmt.Println(cfg) + return cfg +} + +func unmarshalConfig(file string, cfg *Config) { + if fileExists(file) { + content, err := ioutil.ReadFile(file) + if err != nil { + fmt.Println("Error reading config :", file, " : ", err) + } + err2 := toml.Unmarshal(content, &cfg) + if err2 != nil { + fmt.Println("Error unmarshalling config :", file, " : ", err2) + } + } +} + +func unmarshalServices(file string, cfg *Config) { + if fileExists(file) { + content, err := ioutil.ReadFile(file) + if err != nil { + fmt.Println("Error reading services :", file, " : ", err) + } + customsvcfile := configDir + "services.toml" + content2, err2 := ioutil.ReadFile(file) + if err2 != nil { + fmt.Println("Error reading services :", customsvcfile, " : ", err2) + } + content = []byte(fmt.Sprintf(string(content),string(content2))) + var x map[string]interface{} + err3 := toml.Unmarshal(content, &x) + if err3 != nil { + fmt.Println("Error unmarshalling services :", file, " : ", err3) + } + fmt.Println(x) + } +} + +func fileExists(file string) bool { + exists := false + if _, err := os.Stat(file); err == nil { + exists = true + } else { + fmt.Println(err) + fmt.Printf("File %s does not exist\n", file); + } + return exists } diff --git a/src/go.mod b/src/go.mod index 3bc798b..56c7d88 100644 --- a/src/go.mod +++ b/src/go.mod @@ -3,5 +3,6 @@ module mailautoconf go 1.16 require ( - github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec // indirect + github.com/pelletier/go-toml v1.9.3 // indirect + github.com/pelletier/go-toml/v2 v2.0.0-beta.3 // indirect ) diff --git a/src/go.sum b/src/go.sum index bac961c..91c5815 100644 --- a/src/go.sum +++ b/src/go.sum @@ -1,2 +1,10 @@ -github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec h1:DGmKwyZwEB8dI7tbLt/I/gQuP559o/0FrAkHKlQM/Ks= -github.com/vaughan0/go-ini v0.0.0-20130923145212-a98ad7ee00ec/go.mod h1:owBmyHYMLkxyrugmfwE/DLJyW8Ro9mkphwuVErQ0iUw= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= +github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml/v2 v2.0.0-beta.3 h1:PNCTU4naEJ8mKal97P3A2qDU74QRQGlv4FXiL1XDqi4= +github.com/pelletier/go-toml/v2 v2.0.0-beta.3/go.mod h1:aNseLYu/uKskg0zpr/kbr2z8yGuWtotWf/0BpGIAL2Y= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.1-0.20210427113832-6241f9ab9942/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/src/mailautoconf.go b/src/mailautoconf.go index 787a5e9..a42da48 100644 --- a/src/mailautoconf.go +++ b/src/mailautoconf.go @@ -5,12 +5,12 @@ import ( "net/http" "log" "mailautoconf/web/handler" - . "mailautoconf/global" + "mailautoconf/global" ) func main() { - MainConfig = NewConfig() + global.NewConfig() http.HandleFunc("/", handler.WebHandler) - fmt.Println("Starting up Web Listener on port 8080") - log.Fatal(http.ListenAndServe(":8080", nil)) + fmt.Println("Starting up Web Listener on port 8010") + log.Fatal(http.ListenAndServe(":8010", nil)) } diff --git a/src/structs/structs.go b/src/structs/structs.go index 46db476..9857770 100644 --- a/src/structs/structs.go +++ b/src/structs/structs.go @@ -1,9 +1,8 @@ package structs -// I don't like the name of this package, consider naming it "core" or -// separating out the structs and core functions import "net/http" + type Session struct { ResponseWriter http.ResponseWriter Request *http.Request @@ -11,8 +10,29 @@ type Session struct { WebContent string } type Config struct { - Services []Service + BaseURL string + Domains []string + LogonDomain string + Services []interface{} } type Service struct { - + Name string + Enabled bool + Type string + Server string + Port int + SocketType string + SPA bool + UsernameIsFQDN bool + NoAuthRequired bool + Authentication string + // For Outgoing Mail + POPAuth bool + SMTPLast bool + // For WebMail (Unused) + UsernameDivID string + UsernameDivName string + PasswordDivName string + SubmitButtonID string + SubmitButtonName string } From 89df3cca204a5acef93b6987e46f8c979c560f29 Mon Sep 17 00:00:00 2001 From: Paul Wilde Date: Mon, 16 Aug 2021 16:07:22 +0100 Subject: [PATCH 4/6] goversion main framework working, need to sort templates etc --- src/default-config/config.default.toml | 13 --- src/default-config/config.default.yaml | 17 ++++ src/default-config/services.default.toml | 121 ---------------------- src/default-config/services.default.yaml | 124 +++++++++++++++++++++++ src/global/global.go | 74 ++++---------- src/go.mod | 3 +- src/go.sum | 11 +- src/structs/structs.go | 64 ++++++++---- src/templates/autoconfig.html | 12 ++- src/web/handler/handler.go | 6 ++ src/web/responses/responses.go | 35 ++++++- 11 files changed, 257 insertions(+), 223 deletions(-) delete mode 100644 src/default-config/config.default.toml create mode 100644 src/default-config/config.default.yaml delete mode 100644 src/default-config/services.default.toml create mode 100644 src/default-config/services.default.yaml diff --git a/src/default-config/config.default.toml b/src/default-config/config.default.toml deleted file mode 100644 index 47015d4..0000000 --- a/src/default-config/config.default.toml +++ /dev/null @@ -1,13 +0,0 @@ -# Sample config.ini file. -# Copy this file to "config/config.ini" and adjust the settings to your requirements - -# The URL of this application -BaseURL = "https://autoconfig.example.com" - -# Set the email domains for use with this service. The first one is primary. -# each will need their own DNS A record for autoconfig.domain.name -Domains = ["example.com","example2,com"] - - -# If you use a different domain to authenticate with, enter it here -LogonDomain = "example.local" diff --git a/src/default-config/config.default.yaml b/src/default-config/config.default.yaml new file mode 100644 index 0000000..9d16d1a --- /dev/null +++ b/src/default-config/config.default.yaml @@ -0,0 +1,17 @@ +--- +Version : "0.1.1" +# Sample config.yaml file. +# Copy this file to "config/config.yaml" and adjust the +# settings to your requirements + +# The URL of this application +BaseURL : "https://autoconfig.example.com" + +# Set the email domains for use with this service. The first one is primary. +# each will need their own DNS A record for autoconfig.domain.name +Domains : + - "example.com" + - "example2,com" + +# If you use a different domain to authenticate with, enter it here +LogonDomain : "example.local" diff --git a/src/default-config/services.default.toml b/src/default-config/services.default.toml deleted file mode 100644 index 70fe484..0000000 --- a/src/default-config/services.default.toml +++ /dev/null @@ -1,121 +0,0 @@ -# The Incoming mail Server Config - -[InMail] - # Enable this service -Enabled = true - - # Mail Type, i.e. IMAP, POP3 - Type = "IMAP" - - # Your IMAP server - Server = "imap.example.com" - - # Your IMAP port - Port = 993 - - # The socket type = SSL, STARTTLS, or NONE - SocketType = "SSL" - - # Use Secure Password Authentication - SPA = false - - # Change to true if you need the domain/logondomain to form part of the username - UsernameIsFQDN = false - - # Do you need to authenticate to your mail server? You should! so this should be false! - NoAuthRequired = false - - # Authentication type, - #"password-cleartext" = Send password in the clear - # (dangerous, if SSL isn't used either). - # AUTH PLAIN, LOGIN or protocol-native login. - #"password-encrypted" = A secure encrypted password mechanism. - # Can be CRAM-MD5 or DIGEST-MD5. Not NTLM. - #"NTLM"= Use NTLM (or NTLMv2 or successors), - # the Windows login mechanism. - Authentication = "password-cleartext" - -# -# -# # The Outgoing mail server config -# [OutMail] -# Name = "OutMail" -# -# # Enable this service -# Enabled = true -# -# # Mail type, likely to only be SMTP -# Type = "SMTP" -# -# # Your SMTP server -# Server = "smtp.example.com" -# -# # Your SMTP port -# Port = 465 -# -# # The socket type = SSL, STARTTLS or NONE -# SocketType = "SSL" -# -# # See InMail > Authentication -# Authentication = "password-cleartext" -# -# # Use Secure Password Authentication -# SPA = false -# -# # Change to true if you need the domain/logondomain to form part of the username -# UsernameIsFQDN = false -# -# # Do you need to authenticate to your mail server? You should! so this should be false! -# NoAuthRequired = false -# -# # Use POP Authentication? You probably shouldn't be. -# POPAuth = false -# -# # This setting is here to limit errors, I'm not sure what it does yet. -# SMTPLast = false -# -# -# # Currently not implemented, see https://wiki.mozilla.org/Thunderbird=Autoconfiguration=ConfigFileFormat -# [Calendar] -# Name = "Calendar" -# # Disable this service -# Enabled = false -# Server = "https://example.com/remote.php/dav/" -# Port = 443 -# Type = "CalDAV" -# Authentication = "http-basic" -# UsernameIsFQDN = false -# -# # Currently not implemented, see https://wiki.mozilla.org/Thunderbird=Autoconfiguration=ConfigFileFormat -# [AddressBook] -# Name = "AddressBook" -# # Disable this service -# Enabled = false -# Server = "https://example.com/remote.php/dav/" -# Port = 443 -# Type = "CardDAV" -# Authentication = "http-basic" -# UsernameIsFQDN = false -# -# # Currently not implemented, see https://wiki.mozilla.org/Thunderbird=Autoconfiguration=ConfigFileFormat -# [WebMail] -# Name = "WebMail" -# # Disable this service -# Enabled = false -# Server = "https://mail.example.com" -# UsernameDivID = "username" -# UsernameDivName = "username" -# PasswordDivName = "password" -# SubmitButtonID = "submit" -# SubmitButtonName = "submit" -# UsernameIsFQDN = false -# -# -# # In theory, additional custom services can be configured and will be displayed with -# # their options on the /get/all URL of this service. The third-party clients would need to -# # check this service as part of their development for this to work -# # Will not be shown in autodiscover.xml/json or config-v1.1.xml/autoconfig.xml -# # i.e Nextcloud - ideally a nextcloud client could check autoconfig for this URL for ease of set up -# #[Nextcloud] -# # Name = "NextCloud" -# # Server = "https://nextcloud.example.com" diff --git a/src/default-config/services.default.yaml b/src/default-config/services.default.yaml new file mode 100644 index 0000000..b65d573 --- /dev/null +++ b/src/default-config/services.default.yaml @@ -0,0 +1,124 @@ +# Sample services.yaml file. +# Copy this file to "config/services.yaml" and adjust the +# settings to your requirements +--- + +# The Incoming mail Server Config +InMail: + Name: "InMail" + + # Enable this service + Enabled: true + + # Mail Type, i.e. IMAP, POP3 + Type: "IMAP" + + # Your IMAP server + Server: "imap.example.com" + + # Your IMAP port + Port: 993 + + # The socket type : SSL, STARTTLS, or NONE + SocketType: "SSL" + + # Use Secure Password Authentication + SPA: false + + # Change to true if you need the domain/logondomain to form part of the username + UsernameIsFQDN: false + + # Do you need to authenticate to your mail server? You should! so this should be false! + NoAuthRequired: false + + # Authentication type, + #"password-cleartext" : Send password in the clear + # (dangerous, if SSL isn't used either). + # AUTH PLAIN, LOGIN or protocol-native login. + #"password-encrypted" : A secure encrypted password mechanism. + # Can be CRAM-MD5 or DIGEST-MD5. Not NTLM. + #"NTLM": Use NTLM (or NTLMv2 or successors), + # the Windows login mechanism. + Authentication: "password-cleartext" + +# The Outgoing mail server config +OutMail: + # Enable this service + Enabled: true + + # Mail type, likely to only be SMTP + Type: "SMTP" + + # Your SMTP server + Server: "smtp.example.com" + + # Your SMTP port + Port: 465 + + # The socket type : SSL, STARTTLS or NONE + SocketType: "SSL" + + # See InMail > Authentication + Authentication: "password-cleartext" + + # Use Secure Password Authentication + SPA: false + + # Change to true if you need the domain/logondomain to form part of the username + UsernameIsFQDN: false + + # Do you need to authenticate to your mail server? You should! so this should be false! + NoAuthRequired: false + + # Use POP Authentication? You probably shouldn't be. + POPAuth: false + + # This setting is here to limit errors, I'm not sure what it does yet. + SMTPLast: false + + +# Currently not implemented, see https://wiki.mozilla.org/Thunderbird:Autoconfiguration:ConfigFileFormat +Calendar: + Name: "Calendar" + # Disable this service + Enabled: false + Server: "https://example.com/remote.php/dav/" + Port: 443 + Type: "CalDAV" + Authentication: "http-basic" + UsernameIsFQDN: false + +# Currently not implemented, see https://wiki.mozilla.org/Thunderbird:Autoconfiguration:ConfigFileFormat +AddressBook: + Name: "AddressBook" + # Disable this service + Enabled: false + Server: "https://example.com/remote.php/dav/" + Port: 443 + Type: "CardDAV" + Authentication: "http-basic" + UsernameIsFQDN: false + +# Currently not implemented, see https://wiki.mozilla.org/Thunderbird:Autoconfiguration:ConfigFileFormat +WebMail: + Name: "WebMail" + # Disable this service + Enabled: false + Server: "https://mail.example.com" + UsernameDivID: "username" + UsernameDivName: "username" + PasswordDivName: "password" + SubmitButtonID: "submit" + SubmitButtonName: "submit" + UsernameIsFQDN: false + + +# In theory, additional custom services can be configured and will be displayed with +# their options on the /get/all URL of this service. The third-party clients would need to +# check this service as part of their development for this to work +# Will not be shown in autodiscover.xml/json or config-v1.1.xml/autoconfig.xml +# i.e Nextcloud - ideally a nextcloud client could check autoconfig for this URL for ease of set up +#OtherServices: +# - +# Name : "NextCloud" +# Server : "https://nextcloud.example.com" diff --git a/src/global/global.go b/src/global/global.go index 8f85a79..b690295 100644 --- a/src/global/global.go +++ b/src/global/global.go @@ -2,9 +2,10 @@ package global import ( . "mailautoconf/structs" "fmt" - "github.com/pelletier/go-toml/v2" + "gopkg.in/yaml.v2" "io/ioutil" "os" + "encoding/json" ) @@ -20,75 +21,36 @@ func NewConfig() Config { } func loadConfig() Config { cfg := Config{} - fmt.Println("Loading Default Config…") - cfgfile := defaultConfigDir + "config.default.toml" + cfgfile := defaultConfigDir + "config.default.yaml" unmarshalConfig(cfgfile, &cfg) - fmt.Println(cfg) - customcfgfile := configDir + "config.toml" + fmt.Println("Loading Custom Config…") + customcfgfile := configDir + "config.yaml" unmarshalConfig(customcfgfile, &cfg) - fmt.Println(cfg) - svcfile := defaultConfigDir + "services.default.toml" - // cfg.Services = []Service{ - // Service{ - // Name : "first", - // }, - // Service{ - // Name : "second", - // }, - // Service{ - // Name : "third", - // }, - // } - // data, _ := toml.Marshal(cfg) - - // ioutil.WriteFile(svcfile, data, 0) - - unmarshalServices(svcfile, &cfg) - - customsvcfile := configDir + "services.toml" - unmarshalServices(customsvcfile, &cfg) - // fmt.Println(cfg) - fmt.Println("\r\nOur Config :") - fmt.Println(cfg) + fmt.Println("Loading Default Services…") + svcfile := defaultConfigDir + "services.default.yaml" + unmarshalConfig(svcfile, &cfg) + fmt.Println("Loading Custom Services…") + customsvcfile := configDir + "services.yaml" + unmarshalConfig(customsvcfile, &cfg) return cfg } func unmarshalConfig(file string, cfg *Config) { - if fileExists(file) { + if FileExists(file) { content, err := ioutil.ReadFile(file) if err != nil { fmt.Println("Error reading config :", file, " : ", err) } - err2 := toml.Unmarshal(content, &cfg) + err2 := yaml.Unmarshal(content, &cfg) if err2 != nil { fmt.Println("Error unmarshalling config :", file, " : ", err2) } } } -func unmarshalServices(file string, cfg *Config) { - if fileExists(file) { - content, err := ioutil.ReadFile(file) - if err != nil { - fmt.Println("Error reading services :", file, " : ", err) - } - customsvcfile := configDir + "services.toml" - content2, err2 := ioutil.ReadFile(file) - if err2 != nil { - fmt.Println("Error reading services :", customsvcfile, " : ", err2) - } - content = []byte(fmt.Sprintf(string(content),string(content2))) - var x map[string]interface{} - err3 := toml.Unmarshal(content, &x) - if err3 != nil { - fmt.Println("Error unmarshalling services :", file, " : ", err3) - } - fmt.Println(x) - } -} -func fileExists(file string) bool { +func FileExists(file string) bool { exists := false if _, err := os.Stat(file); err == nil { exists = true @@ -98,3 +60,11 @@ func fileExists(file string) bool { } return exists } + +func JSONify(content interface{}) string { + data, err := json.Marshal(content) + if err != nil { + fmt.Println(err) + } + return string(data) +} diff --git a/src/go.mod b/src/go.mod index 56c7d88..884016d 100644 --- a/src/go.mod +++ b/src/go.mod @@ -3,6 +3,5 @@ module mailautoconf go 1.16 require ( - github.com/pelletier/go-toml v1.9.3 // indirect - github.com/pelletier/go-toml/v2 v2.0.0-beta.3 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/src/go.sum b/src/go.sum index 91c5815..7534661 100644 --- a/src/go.sum +++ b/src/go.sum @@ -1,10 +1,3 @@ -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ= -github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml/v2 v2.0.0-beta.3 h1:PNCTU4naEJ8mKal97P3A2qDU74QRQGlv4FXiL1XDqi4= -github.com/pelletier/go-toml/v2 v2.0.0-beta.3/go.mod h1:aNseLYu/uKskg0zpr/kbr2z8yGuWtotWf/0BpGIAL2Y= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.7.1-0.20210427113832-6241f9ab9942/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/src/structs/structs.go b/src/structs/structs.go index 9857770..0a80933 100644 --- a/src/structs/structs.go +++ b/src/structs/structs.go @@ -8,31 +8,53 @@ type Session struct { Request *http.Request Path string WebContent string + ContentType string } type Config struct { - BaseURL string - Domains []string - LogonDomain string - Services []interface{} + Version string `yaml:"Version"` + BaseURL string `yaml:"BaseURL"` + Domains []string `yaml:"Domains"` + LogonDomain string `yaml:"LogonDomain"` + InMail Service `yaml:"InMail"` + OutMail Service `yaml:"OutMail"` + Calendar Service `yaml:"Calendar"` + AddressBook Service `yaml:"AddressBook"` + OtherServices []Service `yaml:"OtherServices"` + } type Service struct { - Name string - Enabled bool - Type string - Server string - Port int - SocketType string - SPA bool - UsernameIsFQDN bool - NoAuthRequired bool - Authentication string + Name string `yaml:"Name"` + Enabled bool `yaml:"Enabled"` + Type string `yaml:"Type"` + Server string `yaml:"Server"` + Port int `yaml:"Port"` + SocketType string `yaml:"SocketType"` + SPA bool `yaml:"SPA"` + UsernameIsFQDN bool `yaml:"UsernameIsFQDN"` + NoAuthRequired bool `yaml:"NoAuthRequired"` + Authentication string `yaml:"Authentication"` // For Outgoing Mail - POPAuth bool - SMTPLast bool + POPAuth bool `yaml:"POPAuth"` + SMTPLast bool `yaml:"SMTPLast"` // For WebMail (Unused) - UsernameDivID string - UsernameDivName string - PasswordDivName string - SubmitButtonID string - SubmitButtonName string + UsernameDivID string `yaml:"UsernameDivID"` + UsernameDivName string `yaml:"UsernameDivName"` + PasswordDivName string `yaml:"PasswordDivName"` + SubmitButtonID string `yaml:"SubmitButtonID"` + SubmitButtonName string `yaml:"SubmitButtonName"` +} +type Response struct { + Url string `json:"url"` + ContentType string `json:"content_type"` + Message string `json:"message"` + Content []interface{} `json:"content"` +} +type MSAutodiscoverJSONResponse struct { + // More work to do - handling of MS Autodiscover.json requests + Protocol string + Url string +} +type MSAutodiscoverJSONError struct{ + ErrorCode string + ErrorMessage string } diff --git a/src/templates/autoconfig.html b/src/templates/autoconfig.html index 2ce1ccb..169baf1 100644 --- a/src/templates/autoconfig.html +++ b/src/templates/autoconfig.html @@ -1,7 +1,13 @@ - + +

Go templates

+

The user is {{ .Name }}

+

Skills:

+{{ range .Skills }} +

{{ . }}

+{{ end }} + - "> + ">{{ . }} diff --git a/src/web/handler/handler.go b/src/web/handler/handler.go index cd5d8ce..b2144b9 100644 --- a/src/web/handler/handler.go +++ b/src/web/handler/handler.go @@ -12,6 +12,9 @@ func WebHandler(w http.ResponseWriter, r *http.Request) { ThisSession.ResponseWriter = w ThisSession.Request = r ThisSession.Path = strings.ToLower(r.URL.Path[1:]) + if ThisSession.Path == "" { + ThisSession.Path = "none" + } switch ThisSession.Path { case "mail/config-v1.1.xml": @@ -20,6 +23,8 @@ func WebHandler(w http.ResponseWriter, r *http.Request) { ThisSession.WebContent = responses.MsAutoDiscoverXML() case "autodiscover/autodiscover.json": ThisSession.WebContent = responses.MsAutoDiscoverJSON() + case "get/config": + ThisSession.WebContent = responses.OurConfig() default: ThisSession.WebContent = responses.DefaultResponse() } @@ -28,5 +33,6 @@ func WebHandler(w http.ResponseWriter, r *http.Request) { } func writeWebOutput () { + ThisSession.ResponseWriter.Header().Set("Content-Type", ThisSession.ContentType) fmt.Fprintf(ThisSession.ResponseWriter, ThisSession.WebContent) } diff --git a/src/web/responses/responses.go b/src/web/responses/responses.go index 8f85c82..6a4a05e 100644 --- a/src/web/responses/responses.go +++ b/src/web/responses/responses.go @@ -1,6 +1,27 @@ package responses - +import ( + "mailautoconf/global" + . "mailautoconf/structs" + "html/template" + // "fmt" +) func MozAutoconfig() string { + // The below link has config-v1.1.xml information + // https://wiki.mozilla.org/Thunderbird:Autoconfiguration:ConfigFileFormat + tmpl := "templates/autoconfig.html" + t := template.Must(template.ParseFiles(tmpl)) + data := struct { + Name string + Skills []string + }{ + Name: "John Doe", + Skills: []string{ + "C++", + "Java", + "Python", + }, + } + t.Execute(global.ThisSession.ResponseWriter, data) return "" } func MsAutoDiscoverXML() string { @@ -10,5 +31,15 @@ func MsAutoDiscoverJSON() string { return "" } func DefaultResponse() string { - return "" + response := Response{} + response.Url = global.ThisSession.Path + global.ThisSession.ContentType = "application/json" + response.ContentType = global.ThisSession.ContentType + response.Message = "Success! Things are working! Please request a valid URL i.e. /mail/config-v1.1.xml"; + return global.JSONify(response) +} +func OurConfig() string { + global.ThisSession.ContentType = "application/json" + content := global.JSONify(global.MainConfig) + return content } From c3831ed8ddac8c3cc444d3af5095da23a584cd99 Mon Sep 17 00:00:00 2001 From: Paul Wilde Date: Mon, 16 Aug 2021 16:09:48 +0100 Subject: [PATCH 5/6] goversion main framework working, need to sort templates etc --- .gitignore | 1 + structs/structs.go | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) delete mode 100644 structs/structs.go diff --git a/.gitignore b/.gitignore index 04204c7..77bb3a0 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ config +src/config diff --git a/structs/structs.go b/structs/structs.go deleted file mode 100644 index c00292e..0000000 --- a/structs/structs.go +++ /dev/null @@ -1,4 +0,0 @@ -type Page struct { - Title string - Body []byte -} From b435c1bf96f5b0ac69b5bb37e7a84907a882e141 Mon Sep 17 00:00:00 2001 From: Paul Wilde Date: Mon, 16 Aug 2021 20:15:27 +0100 Subject: [PATCH 6/6] goversion conversion completed --- Containerfile | 23 ++++-- entrypoint.sh | 20 ++--- src/default-config/config.default.yaml | 2 +- src/default-config/services.default.yaml | 9 +++ src/go.mod | 8 ++ src/go.sum | 25 ++++++ src/structs/structs.go | 16 ++-- src/templates/autoconfig.html | 64 ---------------- src/templates/autoconfig.xml | 50 ++++++++++++ src/templates/autodiscover.html | 45 ----------- src/templates/autodiscover.xml | 35 +++++++++ src/web/handler/handler.go | 5 +- src/web/responses/responses.go | 96 +++++++++++++++++++----- 13 files changed, 244 insertions(+), 154 deletions(-) delete mode 100644 src/templates/autoconfig.html create mode 100644 src/templates/autoconfig.xml delete mode 100644 src/templates/autodiscover.html create mode 100644 src/templates/autodiscover.xml diff --git a/Containerfile b/Containerfile index f8c164e..f7f2701 100644 --- a/Containerfile +++ b/Containerfile @@ -1,15 +1,22 @@ -FROM php:7.4-apache +FROM golang:1-alpine3.14 AS builder -COPY src/ /var/www/html/ +COPY src/ /mailautoconf +WORKDIR /mailautoconf +RUN go build -o /mailautoconf/mailautoconf + +FROM alpine:3.14 + +ENV UID=1426 \ + GID=1426 + +RUN apk add --no-cache bash +COPY --from=builder /mailautoconf/mailautoconf /mailautoconf/mailautoconf +COPY --from=builder /mailautoconf/default-config /mailautoconf/default-config +COPY --from=builder /mailautoconf/templates /mailautoconf/templates COPY ./entrypoint.sh / RUN chmod +x /entrypoint.sh -# Use the default production configuration -RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" - -RUN a2enmod rewrite - -EXPOSE 80 +EXPOSE 8010 ENTRYPOINT ["/entrypoint.sh"] diff --git a/entrypoint.sh b/entrypoint.sh index 57b8053..b3613b1 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,29 +1,29 @@ #!/usr/bin/env bash echo Removing old sample files… -rm /var/www/html/config/*.sample.ini +rm /mailautoconf/config/*.sample.yaml function write_file() { while read line; do first_char=${line:0:1} - if [[ $first_char != ";" ]]; then - line="; "$line + if [[ $first_char != "#" ]]; then + line="#"$line fi echo $line >> $2 done < $1 } echo Setting up new sample config files… -def_conf="/var/www/html/default-config/config.default.ini" -new_conf="/var/www/html/config/config.sample.ini" +def_conf="/mailautoconf/default-config/config.default.yaml" +new_conf="/mailautoconf/config/config.sample.yaml" write_file $def_conf $new_conf -def_serv="/var/www/html/default-config/services.default.ini" -new_serv="/var/www/html/config/services.sample.ini" +def_serv="/mailautoconf/default-config/services.default.yaml" +new_serv="/mailautoconf/config/services.sample.yaml" write_file $def_serv $new_serv +echo New sample files copied - -echo Running HTTPD… -exec apache2-foreground +cd /mailautoconf +exec /mailautoconf/mailautoconf diff --git a/src/default-config/config.default.yaml b/src/default-config/config.default.yaml index 9d16d1a..870d458 100644 --- a/src/default-config/config.default.yaml +++ b/src/default-config/config.default.yaml @@ -14,4 +14,4 @@ Domains : - "example2,com" # If you use a different domain to authenticate with, enter it here -LogonDomain : "example.local" +LocalDomain : "example.local" diff --git a/src/default-config/services.default.yaml b/src/default-config/services.default.yaml index b65d573..52d636b 100644 --- a/src/default-config/services.default.yaml +++ b/src/default-config/services.default.yaml @@ -28,6 +28,9 @@ InMail: # Change to true if you need the domain/logondomain to form part of the username UsernameIsFQDN: false + # Use the LogonDomain instead of the Email Domain + RequireLocalDomain : false + # Do you need to authenticate to your mail server? You should! so this should be false! NoAuthRequired: false @@ -67,6 +70,9 @@ OutMail: # Change to true if you need the domain/logondomain to form part of the username UsernameIsFQDN: false + # Use the LogonDomain instead of the Email Domain + RequireLocalDomain : false + # Do you need to authenticate to your mail server? You should! so this should be false! NoAuthRequired: false @@ -87,6 +93,7 @@ Calendar: Type: "CalDAV" Authentication: "http-basic" UsernameIsFQDN: false + RequireLocalDomain : false # Currently not implemented, see https://wiki.mozilla.org/Thunderbird:Autoconfiguration:ConfigFileFormat AddressBook: @@ -98,6 +105,7 @@ AddressBook: Type: "CardDAV" Authentication: "http-basic" UsernameIsFQDN: false + RequireLocalDomain : false # Currently not implemented, see https://wiki.mozilla.org/Thunderbird:Autoconfiguration:ConfigFileFormat WebMail: @@ -111,6 +119,7 @@ WebMail: SubmitButtonID: "submit" SubmitButtonName: "submit" UsernameIsFQDN: false + RequireLocalDomain : false # In theory, additional custom services can be configured and will be displayed with diff --git a/src/go.mod b/src/go.mod index 884016d..db9995d 100644 --- a/src/go.mod +++ b/src/go.mod @@ -3,5 +3,13 @@ module mailautoconf go 1.16 require ( + github.com/Masterminds/goutils v1.1.1 // indirect + github.com/Masterminds/semver v1.5.0 // indirect + github.com/Masterminds/sprig v2.22.0+incompatible // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/huandu/xstrings v1.3.2 // indirect + github.com/imdario/mergo v0.3.12 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect + golang.org/x/crypto v0.0.0-20210813211128-0a44fdfbc16e // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/src/go.sum b/src/go.sum index 7534661..bd2f174 100644 --- a/src/go.sum +++ b/src/go.sum @@ -1,3 +1,28 @@ +github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= +github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60= +github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw= +github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +golang.org/x/crypto v0.0.0-20210813211128-0a44fdfbc16e h1:VvfwVmMH40bpMeizC9/K7ipM5Qjucuu16RWfneFPyhQ= +golang.org/x/crypto v0.0.0-20210813211128-0a44fdfbc16e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/src/structs/structs.go b/src/structs/structs.go index 0a80933..358a0da 100644 --- a/src/structs/structs.go +++ b/src/structs/structs.go @@ -14,11 +14,12 @@ type Config struct { Version string `yaml:"Version"` BaseURL string `yaml:"BaseURL"` Domains []string `yaml:"Domains"` - LogonDomain string `yaml:"LogonDomain"` + LocalDomain string `yaml:"LocalDomain"` InMail Service `yaml:"InMail"` OutMail Service `yaml:"OutMail"` Calendar Service `yaml:"Calendar"` AddressBook Service `yaml:"AddressBook"` + WebMail Service `yaml:"WebMail"` OtherServices []Service `yaml:"OtherServices"` } @@ -29,8 +30,9 @@ type Service struct { Server string `yaml:"Server"` Port int `yaml:"Port"` SocketType string `yaml:"SocketType"` - SPA bool `yaml:"SPA"` + SPA bool `yaml:"SPA"` UsernameIsFQDN bool `yaml:"UsernameIsFQDN"` + RequireLocalDomain bool `yaml:"RequireLocalDomain"` NoAuthRequired bool `yaml:"NoAuthRequired"` Authentication string `yaml:"Authentication"` // For Outgoing Mail @@ -44,10 +46,12 @@ type Service struct { SubmitButtonName string `yaml:"SubmitButtonName"` } type Response struct { - Url string `json:"url"` - ContentType string `json:"content_type"` - Message string `json:"message"` - Content []interface{} `json:"content"` + Url string `json:"url"` + ContentType string `json:"content_type"` + Message string `json:"message"` + Content map[string]interface{} `json:"content"` + Config Config + Email string } type MSAutodiscoverJSONResponse struct { // More work to do - handling of MS Autodiscover.json requests diff --git a/src/templates/autoconfig.html b/src/templates/autoconfig.html deleted file mode 100644 index 169baf1..0000000 --- a/src/templates/autoconfig.html +++ /dev/null @@ -1,64 +0,0 @@ - -

Go templates

-

The user is {{ .Name }}

-

Skills:

-{{ range .Skills }} -

{{ . }}

-{{ end }} - - - ">{{ . }} - - - - %EMAILADDRESS% - - "> - - - - get_username($service,$email_address); ?> - - - - "> - - - - get_username($service,$email_address);?> - - - - "> - get_username($service,$email_address);?> - - - - - "> - get_username($service,$email_address);?> - - - - - - " /> - "> - get_username($service,$email_address);?> - " name="" /> - " /> - " name=""/> - - - - - diff --git a/src/templates/autoconfig.xml b/src/templates/autoconfig.xml new file mode 100644 index 0000000..9320e50 --- /dev/null +++ b/src/templates/autoconfig.xml @@ -0,0 +1,50 @@ + + + {{ range .Config.Domains }}{{ . }} + {{ end }} + {{ .Email }} + {{ with .Config.InMail }} + + {{ .Server }} + {{ .Port }} + {{ .SocketType }} + {{ . | parseUsername }} + {{ .Authentication }} + + {{ end }} + {{ with .Config.OutMail }} + + {{ .Server }} + {{ .Port }}> + {{ .SocketType }} + {{ . | parseUsername }} + {{ .Authentication }} + + {{ end }} + {{ with .Config.AddressBook }} + + {{ . | parseUsername }} + {{ .Authentication }} + {{ .Server }} + + {{ end }} + {{ with .Config.Calendar }} + + {{ . | parseUsername }} + {{ .Authentication }} + {{ .Server }} + + {{ end }} + {{ with .Config.WebMail }} + + + + {{ . | parseUsername }} + + + + + + {{ end }} + + diff --git a/src/templates/autodiscover.html b/src/templates/autodiscover.html deleted file mode 100644 index 3a9342b..0000000 --- a/src/templates/autodiscover.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - email - settings - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/templates/autodiscover.xml b/src/templates/autodiscover.xml new file mode 100644 index 0000000..b024b74 --- /dev/null +++ b/src/templates/autodiscover.xml @@ -0,0 +1,35 @@ + + + + + email + settings + {{ with .Config.InMail }} + + {{ .Type }} + {{ .Server }} + {{ .Port }} + {{ .UsernameIsFQDN | onoff }} + {{ . | parseUsername }} + {{ .SPA | onoff }} + {{ if eq .SocketType "SSL" }}on{{ else }}off{{ end }} + {{ not .NoAuthRequired | onoff }} + + {{ end }} + {{ with .Config.OutMail }} + + {{ .Type }} + {{ .Server }} + {{ .Port }} + {{ .UsernameIsFQDN | onoff }} + {{ . | parseUsername }} + {{ .SPA | onoff }} + {{ .SocketType }} + {{ not .NoAuthRequired | onoff }} + {{ .POPAuth | onoff }} + {{ .SMTPLast | onoff }} + + {{ end }} + + + diff --git a/src/web/handler/handler.go b/src/web/handler/handler.go index b2144b9..f9ceb1f 100644 --- a/src/web/handler/handler.go +++ b/src/web/handler/handler.go @@ -8,6 +8,7 @@ import ( "fmt" ) func WebHandler(w http.ResponseWriter, r *http.Request) { + fmt.Println("Request For :",r.URL) ThisSession = Session{} ThisSession.ResponseWriter = w ThisSession.Request = r @@ -15,9 +16,9 @@ func WebHandler(w http.ResponseWriter, r *http.Request) { if ThisSession.Path == "" { ThisSession.Path = "none" } - switch ThisSession.Path { - case "mail/config-v1.1.xml": + case "mail/config-v1.1.xml", + "mail/autoconfig.xml": ThisSession.WebContent = responses.MozAutoconfig() case "autodiscover/autodiscover.xml": ThisSession.WebContent = responses.MsAutoDiscoverXML() diff --git a/src/web/responses/responses.go b/src/web/responses/responses.go index 6a4a05e..d0cc973 100644 --- a/src/web/responses/responses.go +++ b/src/web/responses/responses.go @@ -2,30 +2,65 @@ package responses import ( "mailautoconf/global" . "mailautoconf/structs" - "html/template" - // "fmt" + "text/template" + "fmt" + "path" + "strings" + "bytes" + "regexp" ) +var email string +var fmap = template.FuncMap{ + "lower": strings.ToLower, + "parseUsername": parseUsername, + "onoff": chooseOnOff, + } func MozAutoconfig() string { // The below link has config-v1.1.xml information // https://wiki.mozilla.org/Thunderbird:Autoconfiguration:ConfigFileFormat - tmpl := "templates/autoconfig.html" - t := template.Must(template.ParseFiles(tmpl)) - data := struct { - Name string - Skills []string - }{ - Name: "John Doe", - Skills: []string{ - "C++", - "Java", - "Python", - }, - } - t.Execute(global.ThisSession.ResponseWriter, data) - return "" + tmpl := "templates/autoconfig.xml" + response := Response{} + response.Email = global.ThisSession.Request.FormValue("emailaddress") + response.Config = global.MainConfig + + name := path.Base(tmpl) + t, err1 := template.New(name).Funcs(fmap).ParseFiles(tmpl) + if err1 != nil { + panic (err1) + } + global.ThisSession.ContentType = "application/xml" + var result bytes.Buffer + err := t.Execute(&result, response) + if err != nil { + fmt.Println(err) + } + return result.String() } func MsAutoDiscoverXML() string { - return "" + // Example POST Request (sent from client) : + // + // + // + // your@email.address + // http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a + // + // + tmpl := "templates/autodiscover.xml" + email = global.ThisSession.Request.FormValue("EMailAddress") + response := Response{} + response.Config = global.MainConfig + name := path.Base(tmpl) + t, err1 := template.New(name).Funcs(fmap).ParseFiles(tmpl) + if err1 != nil { + panic (err1) + } + global.ThisSession.ContentType = "application/xml" + var result bytes.Buffer + err := t.Execute(&result, response) + if err != nil { + fmt.Println(err) + } + return result.String() } func MsAutoDiscoverJSON() string { return "" @@ -43,3 +78,28 @@ func OurConfig() string { content := global.JSONify(global.MainConfig) return content } +func parseUsername(svc Service) string { + if email == "" { + return "" + } + if svc.UsernameIsFQDN && !svc.RequireLocalDomain{ + return email + } else if svc.UsernameIsFQDN && svc.RequireLocalDomain { + re := regexp.MustCompile(`[^@]+$`) + domain := re.FindString(email) + localemail := strings.Replace(email, domain, + global.MainConfig.LocalDomain,1) + return localemail + } else { + re := regexp.MustCompile(`^[^@]+`) + username := re.FindString(email) + return username + } +} +func chooseOnOff(value bool) string { + if value { + return "on" + } else { + return "off" + } +}