diff --git a/src/ui/api/systeminfo.go b/src/ui/api/systeminfo.go
index 154c4bea7..8c8d4fadc 100644
--- a/src/ui/api/systeminfo.go
+++ b/src/ui/api/systeminfo.go
@@ -2,6 +2,7 @@ package api
import (
"net/http"
+ "os"
"path/filepath"
"syscall"
@@ -18,6 +19,7 @@ type SystemInfoAPI struct {
}
const harborStoragePath = "/harbor_storage"
+const defaultRootCert = "/harbor_storage/ca-download-dir/ca.crt"
//SystemInfo models for system info.
type SystemInfo struct {
@@ -66,3 +68,17 @@ func (sia *SystemInfoAPI) GetVolumeInfo() {
sia.Data["json"] = systemInfo
sia.ServeJSON()
}
+
+//GetCert gets default self-signed certificate.
+func (sia *SystemInfoAPI) GetCert() {
+ if sia.isAdmin {
+ if _, err := os.Stat(defaultRootCert); !os.IsNotExist(err) {
+ sia.Ctx.Output.Header("Content-Disposition", "attachment; filename=ca.crt")
+ http.ServeFile(sia.Ctx.ResponseWriter, sia.Ctx.Request, defaultRootCert)
+ } else {
+ log.Error("No certificate found.")
+ sia.CustomAbort(http.StatusNotFound, "No certificate found.")
+ }
+ }
+ sia.CustomAbort(http.StatusUnauthorized, "")
+}
diff --git a/src/ui/controllers/base.go b/src/ui/controllers/base.go
index beaa10cf8..2a891ba03 100644
--- a/src/ui/controllers/base.go
+++ b/src/ui/controllers/base.go
@@ -31,9 +31,10 @@ type langType struct {
}
const (
- viewPath = "sections"
- prefixNg = ""
- defaultLang = "en-US"
+ viewPath = "sections"
+ prefixNg = ""
+ defaultLang = "en-US"
+ defaultRootCert = "/harbor_storage/ca-download-dir/ca.crt"
)
var supportLanguages map[string]langType
@@ -45,6 +46,8 @@ func (b *BaseController) Prepare() {
var lang string
var langHasChanged bool
+ var showDownloadCert bool
+
langRequest := b.GetString("lang")
if langRequest != "" {
lang = langRequest
@@ -120,6 +123,20 @@ func (b *BaseController) Prepare() {
b.SelfRegistration = config.SelfRegistration()
b.Data["SelfRegistration"] = config.SelfRegistration()
+
+ sessionUserID := b.GetSession("userId")
+ if sessionUserID != nil {
+ isAdmin, err := dao.IsAdminRole(sessionUserID.(int))
+ if err != nil {
+ log.Errorf("Error occurred in IsAdminRole: %v", err)
+ }
+ if isAdmin {
+ if _, err := os.Stat(defaultRootCert); !os.IsNotExist(err) {
+ showDownloadCert = true
+ }
+ }
+ }
+ b.Data["ShowDownloadCert"] = showDownloadCert
}
// Forward to setup layout and template for content for a page.
diff --git a/src/ui/router.go b/src/ui/router.go
index 0f5245d92..537748b03 100644
--- a/src/ui/router.go
+++ b/src/ui/router.go
@@ -86,6 +86,7 @@ func initRouters() {
beego.Router("/api/logs", &api.LogAPI{})
beego.Router("/api/systeminfo/volumes", &api.SystemInfoAPI{}, "get:GetVolumeInfo")
+ beego.Router("/api/systeminfo/getcert", &api.SystemInfoAPI{}, "get:GetCert")
//external service that hosted on harbor process:
beego.Router("/service/notifications", &service.NotificationHandler{})
beego.Router("/service/token", &token.Handler{})
diff --git a/src/ui/static/resources/js/components/optional-menu/optional-menu.directive.js b/src/ui/static/resources/js/components/optional-menu/optional-menu.directive.js
index 534a49b98..136763fd6 100644
--- a/src/ui/static/resources/js/components/optional-menu/optional-menu.directive.js
+++ b/src/ui/static/resources/js/components/optional-menu/optional-menu.directive.js
@@ -35,7 +35,7 @@
vm.setLanguage = setLanguage;
vm.logOut = logOut;
vm.about = about;
-
+
function setLanguage(language) {
vm.languageName = i18n.getLanguageName(vm.language);
var hash = $window.location.hash;
@@ -62,10 +62,12 @@
function about() {
$scope.$emit('modalTitle', $filter('tr')('about_harbor'));
- vm.modalMessage = $filter('tr')('current_version', [vm.version || 'Unknown']);
+ vm.modalMessage = $filter('tr')('current_version', [vm.version || 'Unknown']);
+ if(vm.showDownloadCert === 'true') {
+ appendDownloadCertLink();
+ }
GetVolumeInfoService("data")
.then(getVolumeInfoSuccess, getVolumeInfoFailed);
-
}
function getVolumeInfoSuccess(response) {
var storage = response.data;
@@ -79,10 +81,15 @@
$scope.$emit('modalMessage', vm.modalMessage);
$scope.$emit('raiseInfo', raiseInfo);
}
+
function toGigaBytes(val) {
return Math.round(val / (1024 * 1024 * 1024));
}
+ function appendDownloadCertLink() {
+ vm.modalMessage += '
' + $filter('tr')('default_root_cert', ['/api/systeminfo/getcert', $filter('tr')('download')]);
+ }
+
}
function optionalMenu() {
@@ -91,7 +98,8 @@
'templateUrl': '/optional_menu?timestamp=' + new Date().getTime(),
'scope': {
'version': '@',
- 'language': '@'
+ 'language': '@',
+ 'showDownloadCert': '@'
},
'controller': OptionalMenuController,
'controllerAs': 'vm',
diff --git a/src/ui/static/resources/js/services/i18n/locale_messages_en-US.js b/src/ui/static/resources/js/services/i18n/locale_messages_en-US.js
index 5f6a1cc43..ea8e24260 100644
--- a/src/ui/static/resources/js/services/i18n/locale_messages_en-US.js
+++ b/src/ui/static/resources/js/services/i18n/locale_messages_en-US.js
@@ -233,6 +233,8 @@ var locale_messages = {
'about_harbor': 'About Harbor',
'current_version': ' $0',
'current_storage': ' $0 GB available of $1 GB.',
+ 'default_root_cert': ' $1',
+ 'download': 'Download',
'failed_to_get_project_member': 'Failed to get current project member.',
'failed_to_delete_repo': 'Failed to delete repository. ',
'failed_to_delete_repo_insuffient_permissions': 'Failed to delete repository, insuffient permissions.',
@@ -285,4 +287,4 @@ var locale_messages = {
'confirm_to_toggle_disabled_policy_title': 'Disable Policy',
'confirm_to_toggle_disabled_policy': 'After disabling the policy, all unfinished replication jobs of this policy will be stopped and canceled. Please confirm to continue.',
'begin_date_is_later_than_end_date': 'Begin date should not be later than end date.'
-};
+};
\ No newline at end of file
diff --git a/src/ui/static/resources/js/services/i18n/locale_messages_zh-CN.js b/src/ui/static/resources/js/services/i18n/locale_messages_zh-CN.js
index 133dd0761..5b7b5175f 100644
--- a/src/ui/static/resources/js/services/i18n/locale_messages_zh-CN.js
+++ b/src/ui/static/resources/js/services/i18n/locale_messages_zh-CN.js
@@ -233,6 +233,8 @@ var locale_messages = {
'about_harbor': '关于 Harbor',
'current_version': ' $0',
'current_storage': ' 可用: $0 GB,总共: $1 GB。',
+ 'default_root_cert': ' $1',
+ 'download': '下载',
'failed_to_get_project_member': '无法获取当前项目成员。',
'failed_to_delete_repo': '无法删除镜像仓库。',
'failed_to_delete_repo_insuffient_permissions': '无法删除镜像仓库,权限不足。',
@@ -287,4 +289,4 @@ var locale_messages = {
'confirm_to_toggle_disabled_policy_title': '停用策略',
'confirm_to_toggle_disabled_policy': '停用策略后,所有未完成的复制任务将被终止和取消。请确认继续。',
'begin_date_is_later_than_end_date': '起始日期不能晚于结束日期。'
-};
+};
\ No newline at end of file
diff --git a/src/ui/views/sections/header-content.htm b/src/ui/views/sections/header-content.htm
index ab6a4b373..f927847f9 100644
--- a/src/ui/views/sections/header-content.htm
+++ b/src/ui/views/sections/header-content.htm
@@ -25,7 +25,7 @@