mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-26 04:05:40 +01:00
Remove email configuration (#17712)
Email related settings are deprecated Remove email ping API Fixes #17683 Signed-off-by: stonezdj <stonezdj@gmail.com> Signed-off-by: stonezdj <stonezdj@gmail.com>
This commit is contained in:
parent
484abd6213
commit
a47e175056
@ -20,33 +20,6 @@ security:
|
||||
- basic: []
|
||||
- {}
|
||||
paths:
|
||||
/email/ping:
|
||||
post:
|
||||
summary: Test connection and authentication with email server.
|
||||
description: |
|
||||
Test connection and authentication with email server.
|
||||
parameters:
|
||||
- name: settings
|
||||
in: body
|
||||
description: 'Email server settings, if some of the settings are not assigned, they will be read from system configuration.'
|
||||
required: false
|
||||
schema:
|
||||
$ref: '#/definitions/EmailServerSetting'
|
||||
tags:
|
||||
- Products
|
||||
responses:
|
||||
'200':
|
||||
description: Ping email server successfully.
|
||||
'400':
|
||||
description: Inviald email server settings.
|
||||
'401':
|
||||
description: User need to login first.
|
||||
'403':
|
||||
description: Only admin has this authority.
|
||||
'415':
|
||||
$ref: '#/responses/UnsupportedMediaType'
|
||||
'500':
|
||||
description: Unexpected internal errors.
|
||||
/chartrepo/{repo}/charts/{name}/{version}/labels:
|
||||
get:
|
||||
summary: Return the attached labels of chart.
|
||||
|
@ -8477,27 +8477,6 @@ definitions:
|
||||
auth_mode:
|
||||
$ref: '#/definitions/StringConfigItem'
|
||||
description: The auth mode of current system, such as "db_auth", "ldap_auth", "oidc_auth"
|
||||
email_from:
|
||||
$ref: '#/definitions/StringConfigItem'
|
||||
description: The sender name for Email notification.
|
||||
email_host:
|
||||
$ref: '#/definitions/StringConfigItem'
|
||||
description: The hostname of SMTP server that sends Email notification.
|
||||
email_identity:
|
||||
$ref: '#/definitions/StringConfigItem'
|
||||
description: By default it's empty so the email_username is picked
|
||||
email_insecure:
|
||||
$ref: '#/definitions/BoolConfigItem'
|
||||
description: Whether or not the certificate will be verified when Harbor tries to access the email server.
|
||||
email_port:
|
||||
$ref: '#/definitions/IntegerConfigItem'
|
||||
description: The port of SMTP server
|
||||
email_ssl:
|
||||
$ref: '#/definitions/BoolConfigItem'
|
||||
description: When it''s set to true the system will access Email server via TLS by default. If it''s set to false, it still will handle "STARTTLS" from server side.
|
||||
email_username:
|
||||
$ref: '#/definitions/StringConfigItem'
|
||||
description: The username for authenticate against SMTP server
|
||||
ldap_base_dn:
|
||||
$ref: '#/definitions/StringConfigItem'
|
||||
description: The Base DN for LDAP binding.
|
||||
@ -8660,46 +8639,6 @@ definitions:
|
||||
description: The auth mode of current system, such as "db_auth", "ldap_auth", "oidc_auth"
|
||||
x-omitempty: true
|
||||
x-isnullable: true
|
||||
email_from:
|
||||
type: string
|
||||
description: The sender name for Email notification.
|
||||
x-omitempty: true
|
||||
x-isnullable: true
|
||||
email_host:
|
||||
type: string
|
||||
description: The hostname of SMTP server that sends Email notification.
|
||||
x-omitempty: true
|
||||
x-isnullable: true
|
||||
email_identity:
|
||||
type: string
|
||||
description: By default it's empty so the email_username is picked
|
||||
x-omitempty: true
|
||||
x-isnullable: true
|
||||
email_insecure:
|
||||
type: boolean
|
||||
description: Whether or not the certificate will be verified when Harbor tries to access the email server.
|
||||
x-omitempty: true
|
||||
x-isnullable: true
|
||||
email_password:
|
||||
type: string
|
||||
description: Email password
|
||||
x-omitempty: true
|
||||
x-isnullable: true
|
||||
email_port:
|
||||
type: integer
|
||||
description: The port of SMTP server
|
||||
x-omitempty: true
|
||||
x-isnullable: true
|
||||
email_ssl:
|
||||
type: boolean
|
||||
description: When it''s set to true the system will access Email server via TLS by default. If it''s set to false, it still will handle "STARTTLS" from server side.
|
||||
x-omitempty: true
|
||||
x-isnullable: true
|
||||
email_username:
|
||||
type: string
|
||||
description: The username for authenticate against SMTP server
|
||||
x-omitempty: true
|
||||
x-isnullable: true
|
||||
ldap_base_dn:
|
||||
type: string
|
||||
description: The Base DN for LDAP binding.
|
||||
|
@ -31,7 +31,6 @@ import (
|
||||
var TestDBConfig = map[string]interface{}{
|
||||
common.LDAPBaseDN: "dc=example,dc=com",
|
||||
common.LDAPURL: "ldap.example.com",
|
||||
common.EmailHost: "127.0.0.1",
|
||||
}
|
||||
|
||||
var TestConfigWithScanAll = map[string]interface{}{
|
||||
@ -42,7 +41,6 @@ var TestConfigWithScanAll = map[string]interface{}{
|
||||
"postgresql_sslmode": "disable",
|
||||
"ldap_base_dn": "dc=example,dc=com",
|
||||
"ldap_url": "ldap.example.com",
|
||||
"email_host": "127.0.0.1",
|
||||
"scan_all_policy": `{"parameter":{"daily_time":0},"type":"daily"}`,
|
||||
}
|
||||
|
||||
@ -65,7 +63,6 @@ func (c *controllerTestSuite) TestGetUserCfg() {
|
||||
c.Error(err, "failed to get user config")
|
||||
}
|
||||
c.Equal("dc=example,dc=com", resp["ldap_base_dn"].Val)
|
||||
c.Equal("127.0.0.1", resp["email_host"].Val)
|
||||
c.Equal("ldap.example.com", resp["ldap_url"].Val)
|
||||
}
|
||||
|
||||
@ -107,7 +104,6 @@ func (c *controllerTestSuite) TestGetAll() {
|
||||
c.Error(err, "failed to get user config")
|
||||
}
|
||||
c.Equal("dc=example,dc=com", resp["ldap_base_dn"])
|
||||
c.Equal("127.0.0.1", resp["email_host"])
|
||||
c.Equal("ldap.example.com", resp["ldap_url"])
|
||||
}
|
||||
|
||||
|
@ -1,120 +0,0 @@
|
||||
// Copyright 2018 Project Harbor Authors
|
||||
//
|
||||
// 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 (
|
||||
"errors"
|
||||
"net"
|
||||
"strconv"
|
||||
|
||||
"github.com/goharbor/harbor/src/common/utils/email"
|
||||
"github.com/goharbor/harbor/src/lib/config"
|
||||
"github.com/goharbor/harbor/src/lib/log"
|
||||
"github.com/goharbor/harbor/src/lib/orm"
|
||||
)
|
||||
|
||||
const (
|
||||
pingEmailTimeout = 60
|
||||
)
|
||||
|
||||
// EmailAPI ...
|
||||
type EmailAPI struct {
|
||||
BaseController
|
||||
}
|
||||
|
||||
// Prepare ...
|
||||
func (e *EmailAPI) Prepare() {
|
||||
e.BaseController.Prepare()
|
||||
if !e.SecurityCtx.IsAuthenticated() {
|
||||
e.SendUnAuthorizedError(errors.New("UnAuthorized"))
|
||||
return
|
||||
}
|
||||
|
||||
if !e.SecurityCtx.IsSysAdmin() {
|
||||
e.SendForbiddenError(errors.New(e.SecurityCtx.GetUsername()))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Ping tests connection and authentication with email server
|
||||
func (e *EmailAPI) Ping() {
|
||||
var host, username, password, identity string
|
||||
var port int
|
||||
var ssl, insecure bool
|
||||
ctx := orm.Context()
|
||||
body := e.Ctx.Input.CopyBody(1 << 32)
|
||||
if len(body) == 0 {
|
||||
cfg, err := config.Email(ctx)
|
||||
if err != nil {
|
||||
log.Errorf("failed to get email configurations: %v", err)
|
||||
e.SendInternalServerError(err)
|
||||
return
|
||||
}
|
||||
host = cfg.Host
|
||||
port = cfg.Port
|
||||
username = cfg.Username
|
||||
password = cfg.Password
|
||||
identity = cfg.Identity
|
||||
ssl = cfg.SSL
|
||||
insecure = cfg.Insecure
|
||||
} else {
|
||||
settings := &struct {
|
||||
Host string `json:"email_host"`
|
||||
Port *int `json:"email_port"`
|
||||
Username string `json:"email_username"`
|
||||
Password *string `json:"email_password"`
|
||||
SSL bool `json:"email_ssl"`
|
||||
Identity string `json:"email_identity"`
|
||||
Insecure bool `json:"email_insecure"`
|
||||
}{}
|
||||
if err := e.DecodeJSONReq(&settings); err != nil {
|
||||
e.SendBadRequestError(err)
|
||||
return
|
||||
}
|
||||
|
||||
if len(settings.Host) == 0 || settings.Port == nil {
|
||||
e.SendBadRequestError(errors.New("empty host or port"))
|
||||
return
|
||||
}
|
||||
|
||||
if settings.Password == nil {
|
||||
cfg, err := config.Email(ctx)
|
||||
if err != nil {
|
||||
log.Errorf("failed to get email configurations: %v", err)
|
||||
e.SendInternalServerError(err)
|
||||
return
|
||||
}
|
||||
|
||||
settings.Password = &cfg.Password
|
||||
}
|
||||
|
||||
host = settings.Host
|
||||
port = *settings.Port
|
||||
username = settings.Username
|
||||
password = *settings.Password
|
||||
identity = settings.Identity
|
||||
ssl = settings.SSL
|
||||
insecure = settings.Insecure
|
||||
}
|
||||
|
||||
addr := net.JoinHostPort(host, strconv.Itoa(port))
|
||||
if err := email.Ping(addr, identity, username,
|
||||
password, pingEmailTimeout, ssl, insecure); err != nil {
|
||||
log.Errorf("failed to ping email server: %v", err)
|
||||
// do not return any detail information of the error, or may cause SSRF security issue #3755
|
||||
e.SendBadRequestError(errors.New("failed to ping email server"))
|
||||
return
|
||||
}
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
// Copyright 2018 Project Harbor Authors
|
||||
//
|
||||
// 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"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestPingEmail(t *testing.T) {
|
||||
fmt.Println("Testing ping email server")
|
||||
assert := assert.New(t)
|
||||
apiTest := newHarborAPI()
|
||||
|
||||
// case 1: ping email server without admin role
|
||||
code, _, err := apiTest.PingEmail(*testUser, nil)
|
||||
if err != nil {
|
||||
t.Errorf("failed to test ping email server: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
assert.Equal(401, code, "the status code of ping email server with non-admin user should be 401")
|
||||
|
||||
// case 2: empty email host
|
||||
settings := `{
|
||||
"email_host": ""
|
||||
}`
|
||||
|
||||
code, _, err = apiTest.PingEmail(*admin, []byte(settings))
|
||||
if err != nil {
|
||||
t.Errorf("failed to test ping email server: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
assert.Equal(400, code)
|
||||
|
||||
// case 3: secure connection with admin role
|
||||
settings = `{
|
||||
"email_host": "smtp.gmail.com",
|
||||
"email_port": 465,
|
||||
"email_identity": "",
|
||||
"email_username": "wrong_username",
|
||||
"email_ssl": true
|
||||
}`
|
||||
|
||||
code, _, err = apiTest.PingEmail(*admin, []byte(settings))
|
||||
if err != nil {
|
||||
t.Errorf("failed to test ping email server: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
assert.Equal(400, code)
|
||||
|
||||
// case 4: ping email server whose settings are read from config
|
||||
code, _, err = apiTest.PingEmail(*admin, nil)
|
||||
if err != nil {
|
||||
t.Errorf("failed to test ping email server: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
assert.Equal(400, code)
|
||||
}
|
@ -16,7 +16,6 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
@ -88,8 +87,6 @@ func init() {
|
||||
beego.BConfig.WebConfig.Session.SessionOn = true
|
||||
beego.TestBeegoInit(apppath)
|
||||
|
||||
beego.Router("/api/email/ping", &EmailAPI{}, "post:Ping")
|
||||
|
||||
// Charts are controlled under projects
|
||||
chartRepositoryAPIType := &ChartRepositoryAPI{}
|
||||
beego.Router("/api/chartrepo/health", chartRepositoryAPIType, "get:GetHealthStatus")
|
||||
@ -146,11 +143,3 @@ func request(_sling *sling.Sling, acceptHeader string, authInfo ...usrInfo) (int
|
||||
code, _, body, err := request0(_sling, acceptHeader, authInfo...)
|
||||
return code, body, err
|
||||
}
|
||||
|
||||
func (a testapi) PingEmail(authInfo usrInfo, settings []byte) (int, string, error) {
|
||||
_sling := sling.New().Base(a.basePath).Post("/api/email/ping").Body(bytes.NewReader(settings))
|
||||
|
||||
code, body, err := request(_sling, jsonAcceptHeader, authInfo)
|
||||
|
||||
return code, string(body), err
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ import "github.com/goharbor/harbor/src/common"
|
||||
type Item struct {
|
||||
// The Scope of this configuration item: eg: SystemScope, UserScope
|
||||
Scope string `json:"scope,omitempty"`
|
||||
// email, ldapbasic, ldapgroup, uaa settings, used to retieve configure items by group
|
||||
// ldapbasic, ldapgroup, uaa settings, used to retieve configure items by group
|
||||
Group string `json:"group,omitempty"`
|
||||
// environment key to retrieves this value when initialize, for example: POSTGRESQL_HOST, only used for system settings, for user settings no EnvKey
|
||||
EnvKey string `json:"environment_key,omitempty"`
|
||||
@ -44,7 +44,6 @@ const (
|
||||
// Group
|
||||
LdapBasicGroup = "ldapbasic"
|
||||
LdapGroupGroup = "ldapgroup"
|
||||
EmailGroup = "email"
|
||||
UAAGroup = "uaa"
|
||||
HTTPAuthGroup = "http_auth"
|
||||
OIDCGroup = "oidc"
|
||||
@ -74,15 +73,6 @@ var (
|
||||
{Name: common.CoreLocalURL, Scope: SystemScope, Group: BasicGroup, EnvKey: "CORE_LOCAL_URL", DefaultValue: "http://127.0.0.1:8080", ItemType: &StringType{}, Editable: false},
|
||||
{Name: common.DatabaseType, Scope: SystemScope, Group: BasicGroup, EnvKey: "DATABASE_TYPE", DefaultValue: "postgresql", ItemType: &StringType{}, Editable: false},
|
||||
|
||||
{Name: common.EmailFrom, Scope: UserScope, Group: EmailGroup, EnvKey: "EMAIL_FROM", DefaultValue: "admin <sample_admin@mydomain.com>", ItemType: &StringType{}, Editable: false, Description: `The sender name for Email notification.`},
|
||||
{Name: common.EmailHost, Scope: UserScope, Group: EmailGroup, EnvKey: "EMAIL_HOST", DefaultValue: "smtp.mydomain.com", ItemType: &StringType{}, Editable: false, Description: `The hostname of SMTP server that sends Email notification.`},
|
||||
{Name: common.EmailIdentity, Scope: UserScope, Group: EmailGroup, EnvKey: "EMAIL_IDENTITY", DefaultValue: "", ItemType: &StringType{}, Editable: false, Description: `By default it's empty so the email_username is picked`},
|
||||
{Name: common.EmailInsecure, Scope: UserScope, Group: EmailGroup, EnvKey: "EMAIL_INSECURE", DefaultValue: "false", ItemType: &BoolType{}, Editable: false, Description: `Whether or not the certificate will be verified when Harbor tries to access the email server.`},
|
||||
{Name: common.EmailPassword, Scope: UserScope, Group: EmailGroup, EnvKey: "EMAIL_PWD", DefaultValue: "", ItemType: &PasswordType{}, Editable: false, Description: `Email password`},
|
||||
{Name: common.EmailPort, Scope: UserScope, Group: EmailGroup, EnvKey: "EMAIL_PORT", DefaultValue: "25", ItemType: &PortType{}, Editable: false, Description: `The port of SMTP server`},
|
||||
{Name: common.EmailSSL, Scope: UserScope, Group: EmailGroup, EnvKey: "EMAIL_SSL", DefaultValue: "false", ItemType: &BoolType{}, Editable: false, Description: `When it''s set to true the system will access Email server via TLS by default. If it''s set to false, it still will handle "STARTTLS" from server side.`},
|
||||
{Name: common.EmailUsername, Scope: UserScope, Group: EmailGroup, EnvKey: "EMAIL_USR", DefaultValue: "sample_admin@mydomain.com", ItemType: &StringType{}, Editable: false, Description: `The username for authenticate against SMTP server`},
|
||||
|
||||
{Name: common.ExtEndpoint, Scope: SystemScope, Group: BasicGroup, EnvKey: "EXT_ENDPOINT", DefaultValue: "https://host01.com", ItemType: &StringType{}, Editable: false},
|
||||
{Name: common.JobServiceURL, Scope: SystemScope, Group: BasicGroup, EnvKey: "JOBSERVICE_URL", DefaultValue: "http://jobservice:8080", ItemType: &StringType{}, Editable: false},
|
||||
|
||||
|
@ -18,18 +18,6 @@ import (
|
||||
"github.com/beego/beego/orm"
|
||||
)
|
||||
|
||||
// Email ...
|
||||
type Email struct {
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
SSL bool `json:"ssl"`
|
||||
Identity string `json:"identity"`
|
||||
From string `json:"from"`
|
||||
Insecure bool `json:"insecure"`
|
||||
}
|
||||
|
||||
// HTTPAuthProxy wraps the settings for HTTP auth proxy
|
||||
type HTTPAuthProxy struct {
|
||||
Endpoint string `json:"endpoint"`
|
||||
|
@ -132,10 +132,6 @@ func TestConfig(t *testing.T) {
|
||||
t.Fatalf("failed to get onldy admin create project: %v", err)
|
||||
}
|
||||
|
||||
if _, err := Email(ctx); err != nil {
|
||||
t.Fatalf("failed to get email settings: %v", err)
|
||||
}
|
||||
|
||||
if _, err := Database(); err != nil {
|
||||
t.Fatalf("failed to get database: %v", err)
|
||||
}
|
||||
|
@ -108,25 +108,6 @@ func OnlyAdminCreateProject(ctx context.Context) (bool, error) {
|
||||
return DefaultMgr().Get(ctx, common.ProjectCreationRestriction).GetString() == common.ProCrtRestrAdmOnly, nil
|
||||
}
|
||||
|
||||
// Email returns email server settings
|
||||
func Email(ctx context.Context) (*cfgModels.Email, error) {
|
||||
mgr := DefaultMgr()
|
||||
err := mgr.Load(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &cfgModels.Email{
|
||||
Host: mgr.Get(ctx, common.EmailHost).GetString(),
|
||||
Port: mgr.Get(ctx, common.EmailPort).GetInt(),
|
||||
Username: mgr.Get(ctx, common.EmailUsername).GetString(),
|
||||
Password: mgr.Get(ctx, common.EmailPassword).GetString(),
|
||||
SSL: mgr.Get(ctx, common.EmailSSL).GetBool(),
|
||||
From: mgr.Get(ctx, common.EmailFrom).GetString(),
|
||||
Identity: mgr.Get(ctx, common.EmailIdentity).GetString(),
|
||||
Insecure: mgr.Get(ctx, common.EmailInsecure).GetBool(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UAASettings returns the UAASettings to access UAA service.
|
||||
func UAASettings(ctx context.Context) (*models.UAASettings, error) {
|
||||
mgr := DefaultMgr()
|
||||
|
@ -36,7 +36,6 @@ var TestDBConfig = map[string]interface{}{
|
||||
"postgresql_password": "root123",
|
||||
"postgresql_username": "postgres",
|
||||
"postgresql_sslmode": "disable",
|
||||
"email_host": "127.0.0.1",
|
||||
"scan_all_policy": `{"parameter":{"daily_time":0},"type":"daily"}`,
|
||||
}
|
||||
|
||||
@ -54,7 +53,6 @@ func TestMain(m *testing.M) {
|
||||
func TestLoadFromDatabase(t *testing.T) {
|
||||
configManager.UpdateConfig(testCtx, TestDBConfig)
|
||||
configManager.Load(testCtx)
|
||||
assert.Equal(t, "127.0.0.1", configManager.Get(testCtx, "email_host").GetString())
|
||||
assert.Equal(t, `{"parameter":{"daily_time":0},"type":"daily"}`, configManager.Get(testCtx, "scan_all_policy").GetString())
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,6 @@ import (
|
||||
// RegisterRoutes for Harbor legacy APIs
|
||||
func registerLegacyRoutes() {
|
||||
version := APIVersion
|
||||
beego.Router("/api/"+version+"/email/ping", &api.EmailAPI{}, "post:Ping")
|
||||
|
||||
// APIs for chart repository
|
||||
if config.WithChartMuseum() {
|
||||
|
Loading…
Reference in New Issue
Block a user