mirror of
https://github.com/goharbor/harbor.git
synced 2025-01-20 22:51:23 +01:00
support ping email server
This commit is contained in:
parent
ac6c26d6db
commit
23bf2f0ddf
@ -17,15 +17,16 @@ package email
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/tls"
|
tlspkg "crypto/tls"
|
||||||
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
//"strings"
|
"time"
|
||||||
|
|
||||||
"net/smtp"
|
"net/smtp"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
//"github.com/astaxie/beego"
|
|
||||||
"github.com/vmware/harbor/src/common/models"
|
"github.com/vmware/harbor/src/common/models"
|
||||||
|
"github.com/vmware/harbor/src/common/utils/log"
|
||||||
"github.com/vmware/harbor/src/ui/config"
|
"github.com/vmware/harbor/src/ui/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -72,7 +73,7 @@ func sendMail(m Mail, auth smtp.Auth, content []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func sendMailWithTLS(m Mail, auth smtp.Auth, content []byte) error {
|
func sendMailWithTLS(m Mail, auth smtp.Auth, content []byte) error {
|
||||||
conn, err := tls.Dial("tcp", mc.Host+":"+strconv.Itoa(mc.Port), nil)
|
conn, err := tlspkg.Dial("tcp", mc.Host+":"+strconv.Itoa(mc.Port), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -117,24 +118,77 @@ func sendMailWithTLS(m Mail, auth smtp.Auth, content []byte) error {
|
|||||||
return client.Quit()
|
return client.Quit()
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// Ping tests the connection and authentication with email server
|
||||||
func loadConfig() {
|
// If tls is true, a secure connection is established, or the
|
||||||
config, err := beego.AppConfig.GetSection("mail")
|
// connection is insecure, and if starttls is true, Ping trys to
|
||||||
|
// upgrate the insecure connection to a secure one if email server
|
||||||
|
// supports it.
|
||||||
|
// Ping doesn't verify the server's certificate and hostname
|
||||||
|
// if the parameter insecure is ture when the connection is insecure
|
||||||
|
func Ping(addr, identity, username, password string,
|
||||||
|
timeout int, tls, starttls, insecure bool) (err error) {
|
||||||
|
log.Debugf("establishing TCP connection with %s ...", addr)
|
||||||
|
conn, err := net.DialTimeout("tcp", addr,
|
||||||
|
time.Duration(timeout)*time.Second)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
return
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
host, _, err := net.SplitHostPort(addr)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var useTLS = false
|
if tls {
|
||||||
if config["ssl"] != "" && strings.ToLower(config["ssl"]) == "true" {
|
log.Debugf("establishing SSL/TLS connection with %s ...", addr)
|
||||||
useTLS = true
|
tlsConn := tlspkg.Client(conn, &tlspkg.Config{
|
||||||
|
ServerName: host,
|
||||||
|
InsecureSkipVerify: insecure,
|
||||||
|
})
|
||||||
|
if err = tlsConn.Handshake(); err != nil {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
mc = MailConfig{
|
defer tlsConn.Close()
|
||||||
Identity: config["identity"],
|
|
||||||
Host: config["host"],
|
conn = tlsConn
|
||||||
Port: config["port"],
|
}
|
||||||
Username: config["username"],
|
|
||||||
Password: config["password"],
|
log.Debugf("creating SMTP client for %s ...", host)
|
||||||
TLS: useTLS,
|
client, err := smtp.NewClient(conn, host)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer client.Close()
|
||||||
|
|
||||||
|
//swith to SSL/TLS
|
||||||
|
if !tls && starttls {
|
||||||
|
if ok, _ := client.Extension("STARTTLS"); ok {
|
||||||
|
log.Debugf("switching the connection with %s to SSL/TLS ...", addr)
|
||||||
|
if err = client.StartTLS(&tlspkg.Config{
|
||||||
|
ServerName: host,
|
||||||
|
InsecureSkipVerify: insecure,
|
||||||
|
}); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Debugf("the email server %s does not support STARTTLS", addr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
if ok, _ := client.Extension("AUTH"); ok {
|
||||||
|
log.Debug("authenticating the client...")
|
||||||
|
// only support plain auth
|
||||||
|
if err = client.Auth(smtp.PlainAuth(identity,
|
||||||
|
username, password, host)); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Debugf("the email server %s does not support AUTH, skip",
|
||||||
|
addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Debug("ping email server successfully")
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
117
src/ui/api/email.go
Normal file
117
src/ui/api/email.go
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/vmware/harbor/src/common/api"
|
||||||
|
comcfg "github.com/vmware/harbor/src/common/config"
|
||||||
|
"github.com/vmware/harbor/src/common/dao"
|
||||||
|
"github.com/vmware/harbor/src/common/utils/email"
|
||||||
|
"github.com/vmware/harbor/src/common/utils/log"
|
||||||
|
"github.com/vmware/harbor/src/ui/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
pingEmailTimeout = 60
|
||||||
|
)
|
||||||
|
|
||||||
|
// EmailAPI ...
|
||||||
|
type EmailAPI struct {
|
||||||
|
api.BaseAPI
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare ...
|
||||||
|
func (e *EmailAPI) Prepare() {
|
||||||
|
userID := e.ValidateUser()
|
||||||
|
isSysAdmin, err := dao.IsAdminRole(userID)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed to check the role of user: %v", err)
|
||||||
|
e.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
|
||||||
|
}
|
||||||
|
|
||||||
|
if !isSysAdmin {
|
||||||
|
e.CustomAbort(http.StatusForbidden, http.StatusText(http.StatusForbidden))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ping tests connection and authentication with email server
|
||||||
|
func (e *EmailAPI) Ping() {
|
||||||
|
m := map[string]string{}
|
||||||
|
e.DecodeJSONReq(&m)
|
||||||
|
|
||||||
|
settings, err := config.Email()
|
||||||
|
if err != nil {
|
||||||
|
e.CustomAbort(http.StatusInternalServerError,
|
||||||
|
http.StatusText(http.StatusInternalServerError))
|
||||||
|
}
|
||||||
|
|
||||||
|
host, ok := m[comcfg.EmailHost]
|
||||||
|
if ok {
|
||||||
|
if len(host) == 0 {
|
||||||
|
e.CustomAbort(http.StatusBadRequest, "empty email server host")
|
||||||
|
}
|
||||||
|
settings.Host = host
|
||||||
|
}
|
||||||
|
|
||||||
|
port, ok := m[comcfg.EmailPort]
|
||||||
|
if ok {
|
||||||
|
if len(port) == 0 {
|
||||||
|
e.CustomAbort(http.StatusBadRequest, "empty email server port")
|
||||||
|
}
|
||||||
|
p, err := strconv.Atoi(port)
|
||||||
|
if err != nil || p <= 0 {
|
||||||
|
e.CustomAbort(http.StatusBadRequest, "invalid email server port")
|
||||||
|
}
|
||||||
|
settings.Port = p
|
||||||
|
}
|
||||||
|
|
||||||
|
username, ok := m[comcfg.EmailUsername]
|
||||||
|
if ok {
|
||||||
|
settings.Username = username
|
||||||
|
}
|
||||||
|
|
||||||
|
password, ok := m[comcfg.EmailPassword]
|
||||||
|
if ok {
|
||||||
|
settings.Password = password
|
||||||
|
}
|
||||||
|
|
||||||
|
identity, ok := m[comcfg.EmailIdentity]
|
||||||
|
if ok {
|
||||||
|
settings.Identity = identity
|
||||||
|
}
|
||||||
|
|
||||||
|
ssl, ok := m[comcfg.EmailSSL]
|
||||||
|
if ok {
|
||||||
|
if ssl != "0" && ssl != "1" {
|
||||||
|
e.CustomAbort(http.StatusBadRequest,
|
||||||
|
fmt.Sprintf("%s should be 0 or 1", comcfg.EmailSSL))
|
||||||
|
}
|
||||||
|
settings.SSL = ssl == "1"
|
||||||
|
}
|
||||||
|
|
||||||
|
addr := net.JoinHostPort(settings.Host, strconv.Itoa(settings.Port))
|
||||||
|
if err := email.Ping(
|
||||||
|
addr, settings.Identity, settings.Username,
|
||||||
|
settings.Password, pingEmailTimeout, settings.SSL, true, false); err != nil {
|
||||||
|
log.Debugf("ping %s failed: %v", addr, err)
|
||||||
|
e.CustomAbort(http.StatusBadRequest, err.Error())
|
||||||
|
}
|
||||||
|
}
|
@ -96,6 +96,7 @@ func initRouters() {
|
|||||||
beego.Router("/api/ldap/ping", &api.LdapAPI{}, "post:Ping")
|
beego.Router("/api/ldap/ping", &api.LdapAPI{}, "post:Ping")
|
||||||
beego.Router("/api/ldap/users/search", &api.LdapAPI{}, "post:Search")
|
beego.Router("/api/ldap/users/search", &api.LdapAPI{}, "post:Search")
|
||||||
beego.Router("/api/ldap/users/import", &api.LdapAPI{}, "post:ImportUser")
|
beego.Router("/api/ldap/users/import", &api.LdapAPI{}, "post:ImportUser")
|
||||||
|
beego.Router("/api/email/ping", &api.EmailAPI{}, "post:Ping")
|
||||||
|
|
||||||
//external service that hosted on harbor process:
|
//external service that hosted on harbor process:
|
||||||
beego.Router("/service/notifications", &service.NotificationHandler{})
|
beego.Router("/service/notifications", &service.NotificationHandler{})
|
||||||
|
Loading…
Reference in New Issue
Block a user