| @@ -829,6 +829,8 @@ auths.ms_ad_sa = Ms Ad SA | |||||
| auths.smtp_auth = SMTP Authentication Type | auths.smtp_auth = SMTP Authentication Type | ||||
| auths.smtphost = SMTP Host | auths.smtphost = SMTP Host | ||||
| auths.smtpport = SMTP Port | auths.smtpport = SMTP Port | ||||
| auths.allowed_domains = Allowed Domains | |||||
| auths.allowed_domains_helper = Leave it empty to not restrict any domains. Multiple domains should be separated by comma ','. | |||||
| auths.enable_tls = Enable TLS Encryption | auths.enable_tls = Enable TLS Encryption | ||||
| auths.skip_tls_verify = Skip TLS Verify | auths.skip_tls_verify = Skip TLS Verify | ||||
| auths.pam_service_name = PAM Service Name | auths.pam_service_name = PAM Service Name | ||||
| @@ -67,11 +67,12 @@ func (cfg *LDAPConfig) ToDB() ([]byte, error) { | |||||
| } | } | ||||
| type SMTPConfig struct { | type SMTPConfig struct { | ||||
| Auth string | |||||
| Host string | |||||
| Port int | |||||
| TLS bool | |||||
| SkipVerify bool | |||||
| Auth string | |||||
| Host string | |||||
| Port int | |||||
| AllowedDomains string `xorm:"TEXT"` | |||||
| TLS bool | |||||
| SkipVerify bool | |||||
| } | } | ||||
| func (cfg *SMTPConfig) FromDB(bs []byte) error { | func (cfg *SMTPConfig) FromDB(bs []byte) error { | ||||
| @@ -383,6 +384,16 @@ func SMTPAuth(a smtp.Auth, cfg *SMTPConfig) error { | |||||
| // Create a local user if success | // Create a local user if success | ||||
| // Return the same LoginUserPlain semantic | // Return the same LoginUserPlain semantic | ||||
| func LoginUserSMTPSource(u *User, name, passwd string, sourceId int64, cfg *SMTPConfig, autoRegister bool) (*User, error) { | func LoginUserSMTPSource(u *User, name, passwd string, sourceId int64, cfg *SMTPConfig, autoRegister bool) (*User, error) { | ||||
| // Verify allowed domains. | |||||
| if len(cfg.AllowedDomains) > 0 { | |||||
| idx := strings.Index(name, "@") | |||||
| if idx == -1 { | |||||
| return nil, ErrUserNotExist{0, name} | |||||
| } else if !com.IsSliceContainsStr(strings.Split(cfg.AllowedDomains, ","), name[idx+1:]) { | |||||
| return nil, ErrUserNotExist{0, name} | |||||
| } | |||||
| } | |||||
| var auth smtp.Auth | var auth smtp.Auth | ||||
| if cfg.Auth == SMTP_PLAIN { | if cfg.Auth == SMTP_PLAIN { | ||||
| auth = smtp.PlainAuth("", name, passwd, cfg.Host) | auth = smtp.PlainAuth("", name, passwd, cfg.Host) | ||||
| @@ -394,7 +405,8 @@ func LoginUserSMTPSource(u *User, name, passwd string, sourceId int64, cfg *SMTP | |||||
| if err := SMTPAuth(auth, cfg); err != nil { | if err := SMTPAuth(auth, cfg); err != nil { | ||||
| if strings.Contains(err.Error(), "Username and Password not accepted") { | if strings.Contains(err.Error(), "Username and Password not accepted") { | ||||
| return nil, ErrUserNotExist{u.Id, u.Name} | |||||
| fmt.Println(err) | |||||
| return nil, ErrUserNotExist{0, name} | |||||
| } | } | ||||
| return nil, err | return nil, err | ||||
| } | } | ||||
| @@ -28,6 +28,7 @@ type AuthenticationForm struct { | |||||
| SMTPAuth string | SMTPAuth string | ||||
| SMTPHost string | SMTPHost string | ||||
| SMTPPort int | SMTPPort int | ||||
| AllowedDomains string | |||||
| TLS bool | TLS bool | ||||
| SkipVerify bool | SkipVerify bool | ||||
| AllowAutoRegister bool | AllowAutoRegister bool | ||||
| @@ -88,11 +88,12 @@ func parseLDAPConfig(form auth.AuthenticationForm) *models.LDAPConfig { | |||||
| func parseSMTPConfig(form auth.AuthenticationForm) *models.SMTPConfig { | func parseSMTPConfig(form auth.AuthenticationForm) *models.SMTPConfig { | ||||
| return &models.SMTPConfig{ | return &models.SMTPConfig{ | ||||
| Auth: form.SMTPAuth, | |||||
| Host: form.SMTPHost, | |||||
| Port: form.SMTPPort, | |||||
| TLS: form.TLS, | |||||
| SkipVerify: form.SkipVerify, | |||||
| Auth: form.SMTPAuth, | |||||
| Host: form.SMTPHost, | |||||
| Port: form.SMTPPort, | |||||
| AllowedDomains: form.AllowedDomains, | |||||
| TLS: form.TLS, | |||||
| SkipVerify: form.SkipVerify, | |||||
| } | } | ||||
| } | } | ||||
| @@ -101,6 +101,11 @@ | |||||
| <label for="smtp_port">{{.i18n.Tr "admin.auths.smtpport"}}</label> | <label for="smtp_port">{{.i18n.Tr "admin.auths.smtpport"}}</label> | ||||
| <input id="smtp_port" name="smtp_port" value="{{$cfg.Port}}" required> | <input id="smtp_port" name="smtp_port" value="{{$cfg.Port}}" required> | ||||
| </div> | </div> | ||||
| <div class="field"> | |||||
| <label for="allowed_domains">{{.i18n.Tr "admin.auths.allowed_domains"}}</label> | |||||
| <input id="allowed_domains" name="allowed_domains" value="{{$cfg.AllowedDomains}}"> | |||||
| <p class="help">{{.i18n.Tr "admin.auths.allowed_domains_helper"}}</p> | |||||
| </div> | |||||
| {{end}} | {{end}} | ||||
| <!-- PAM --> | <!-- PAM --> | ||||
| @@ -103,6 +103,11 @@ | |||||
| <label for="smtp_port">{{.i18n.Tr "admin.auths.smtpport"}}</label> | <label for="smtp_port">{{.i18n.Tr "admin.auths.smtpport"}}</label> | ||||
| <input id="smtp_port" name="smtp_port" value="{{.smtp_port}}"> | <input id="smtp_port" name="smtp_port" value="{{.smtp_port}}"> | ||||
| </div> | </div> | ||||
| <div class="field"> | |||||
| <label for="allowed_domains">{{.i18n.Tr "admin.auths.allowed_domains"}}</label> | |||||
| <input id="allowed_domains" name="allowed_domains" value="{{.allowed_domains}}"> | |||||
| <p class="help">{{.i18n.Tr "admin.auths.allowed_domains_helper"}}</p> | |||||
| </div> | |||||
| </div> | </div> | ||||
| <!-- PAM --> | <!-- PAM --> | ||||