From 89df3cca204a5acef93b6987e46f8c979c560f29 Mon Sep 17 00:00:00 2001 From: Paul Wilde Date: Mon, 16 Aug 2021 16:07:22 +0100 Subject: [PATCH] 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 }