feat(policy): add policy to show/hide version number

Made-with: Cursor
This commit is contained in:
jamesread 2026-02-27 21:26:55 +00:00
parent f41fe2caba
commit aa2bd95ccb
11 changed files with 77 additions and 34 deletions

View File

@ -210,6 +210,11 @@ export declare type EffectivePolicy = Message<"olivetin.api.v1.EffectivePolicy">
* @generated from field: bool show_log_list = 2; * @generated from field: bool show_log_list = 2;
*/ */
showLogList: boolean; showLogList: boolean;
/**
* @generated from field: bool show_version_number = 3;
*/
showVersionNumber: boolean;
}; };
/** /**
@ -1853,4 +1858,3 @@ export declare const OliveTinApiService: GenService<{
output: typeof EntitySchema; output: typeof EntitySchema;
}, },
}>; }>;

File diff suppressed because one or more lines are too long

View File

@ -31,7 +31,7 @@
<footer title="footer" v-if="showFooter"> <footer title="footer" v-if="showFooter">
<p> <p>
<img title="application icon" :src="logoUrl" alt="OliveTin logo" style="height: 1em;" class="logo" /> <img title="application icon" :src="logoUrl" alt="OliveTin logo" style="height: 1em;" class="logo" />
OliveTin {{ currentVersion }} OliveTin <span v-if="showVersionNumber">{{ currentVersion }}</span>
</p> </p>
<p> <p>
<span> <span>
@ -52,7 +52,7 @@
<span>{{ t('connected') }}</span> <span>{{ t('connected') }}</span>
</p> </p>
<p> <p v-if="showVersionNumber">
<a id="available-version" href="http://olivetin.app" target="_blank" hidden>?</a> <a id="available-version" href="http://olivetin.app" target="_blank" hidden>?</a>
</p> </p>
</footer> </footer>
@ -126,6 +126,7 @@ const showFooter = ref(true)
const showNavigation = ref(true) const showNavigation = ref(true)
const showLogs = ref(true) const showLogs = ref(true)
const showDiagnostics = ref(true) const showDiagnostics = ref(true)
const showVersionNumber = ref(true)
const showLoginLink = ref(true) const showLoginLink = ref(true)
const sectionNavigationStyle = ref('sidebar') const sectionNavigationStyle = ref('sidebar')
@ -223,6 +224,7 @@ function updateHeaderFromInit() {
showNavigation.value = window.initResponse.showNavigation showNavigation.value = window.initResponse.showNavigation
showLogs.value = window.initResponse.showLogList showLogs.value = window.initResponse.showLogList
showDiagnostics.value = window.initResponse.showDiagnostics showDiagnostics.value = window.initResponse.showDiagnostics
showVersionNumber.value = window.initResponse.effectivePolicy?.showVersionNumber ?? true
sectionNavigationStyle.value = window.initResponse.sectionNavigationStyle || 'sidebar' sectionNavigationStyle.value = window.initResponse.sectionNavigationStyle || 'sidebar'
availableThemes.value = window.initResponse.availableThemes || [] availableThemes.value = window.initResponse.availableThemes || []

View File

@ -162,7 +162,10 @@ async function generateBrowserInfo() {
userAgentData: userAgentData userAgentData: userAgentData
} }
const olivetinVersion = window.initResponse?.currentVersion || t('diagnostics.unknown') const showVersionNumber = window.initResponse?.effectivePolicy?.showVersionNumber ?? true
const olivetinVersion = showVersionNumber
? (window.initResponse?.currentVersion || t('diagnostics.unknown'))
: '[hidden]'
const currentLanguage = locale.value || t('diagnostics.unknown') const currentLanguage = locale.value || t('diagnostics.unknown')
let output = ''; let output = '';

View File

@ -51,6 +51,7 @@ message GetDashboardResponse {
message EffectivePolicy { message EffectivePolicy {
bool show_diagnostics = 1; bool show_diagnostics = 1;
bool show_log_list = 2; bool show_log_list = 2;
bool show_version_number = 3;
} }
message GetDashboardRequest { message GetDashboardRequest {

View File

@ -410,11 +410,12 @@ func (x *GetDashboardResponse) GetDashboard() *Dashboard {
} }
type EffectivePolicy struct { type EffectivePolicy struct {
state protoimpl.MessageState `protogen:"open.v1"` state protoimpl.MessageState `protogen:"open.v1"`
ShowDiagnostics bool `protobuf:"varint,1,opt,name=show_diagnostics,json=showDiagnostics,proto3" json:"show_diagnostics,omitempty"` ShowDiagnostics bool `protobuf:"varint,1,opt,name=show_diagnostics,json=showDiagnostics,proto3" json:"show_diagnostics,omitempty"`
ShowLogList bool `protobuf:"varint,2,opt,name=show_log_list,json=showLogList,proto3" json:"show_log_list,omitempty"` ShowLogList bool `protobuf:"varint,2,opt,name=show_log_list,json=showLogList,proto3" json:"show_log_list,omitempty"`
unknownFields protoimpl.UnknownFields ShowVersionNumber bool `protobuf:"varint,3,opt,name=show_version_number,json=showVersionNumber,proto3" json:"show_version_number,omitempty"`
sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields
sizeCache protoimpl.SizeCache
} }
func (x *EffectivePolicy) Reset() { func (x *EffectivePolicy) Reset() {
@ -461,6 +462,13 @@ func (x *EffectivePolicy) GetShowLogList() bool {
return false return false
} }
func (x *EffectivePolicy) GetShowVersionNumber() bool {
if x != nil {
return x.ShowVersionNumber
}
return false
}
type GetDashboardRequest struct { type GetDashboardRequest struct {
state protoimpl.MessageState `protogen:"open.v1"` state protoimpl.MessageState `protogen:"open.v1"`
Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"`
@ -3934,10 +3942,11 @@ const file_olivetin_api_v1_olivetin_proto_rawDesc = "" +
"\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"f\n" + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"f\n" +
"\x14GetDashboardResponse\x12\x14\n" + "\x14GetDashboardResponse\x12\x14\n" +
"\x05title\x18\x01 \x01(\tR\x05title\x128\n" + "\x05title\x18\x01 \x01(\tR\x05title\x128\n" +
"\tdashboard\x18\x04 \x01(\v2\x1a.olivetin.api.v1.DashboardR\tdashboard\"`\n" + "\tdashboard\x18\x04 \x01(\v2\x1a.olivetin.api.v1.DashboardR\tdashboard\"\x90\x01\n" +
"\x0fEffectivePolicy\x12)\n" + "\x0fEffectivePolicy\x12)\n" +
"\x10show_diagnostics\x18\x01 \x01(\bR\x0fshowDiagnostics\x12\"\n" + "\x10show_diagnostics\x18\x01 \x01(\bR\x0fshowDiagnostics\x12\"\n" +
"\rshow_log_list\x18\x02 \x01(\bR\vshowLogList\"k\n" + "\rshow_log_list\x18\x02 \x01(\bR\vshowLogList\x12.\n" +
"\x13show_version_number\x18\x03 \x01(\bR\x11showVersionNumber\"k\n" +
"\x13GetDashboardRequest\x12\x14\n" + "\x13GetDashboardRequest\x12\x14\n" +
"\x05title\x18\x01 \x01(\tR\x05title\x12\x1f\n" + "\x05title\x18\x01 \x01(\tR\x05title\x12\x1f\n" +
"\ventity_type\x18\x02 \x01(\tR\n" + "\ventity_type\x18\x02 \x01(\tR\n" +

View File

@ -710,7 +710,9 @@ func (api *oliveTinAPI) WhoAmI(ctx ctx.Context, req *connect.Request[apiv1.WhoAm
} }
func (api *oliveTinAPI) SosReport(ctx ctx.Context, req *connect.Request[apiv1.SosReportRequest]) (*connect.Response[apiv1.SosReportResponse], error) { func (api *oliveTinAPI) SosReport(ctx ctx.Context, req *connect.Request[apiv1.SosReportRequest]) (*connect.Response[apiv1.SosReportResponse], error) {
sos := installationinfo.GetSosReport() user := auth.UserFromApiCall(ctx, req, api.cfg)
redactVersion := !user.EffectivePolicy.ShowVersionNumber
sos := installationinfo.GetSosReport(redactVersion)
if !api.cfg.InsecureAllowDumpSos { if !api.cfg.InsecureAllowDumpSos {
log.Info(sos) log.Info(sos)
@ -914,12 +916,19 @@ func (api *oliveTinAPI) Init(ctx ctx.Context, req *connect.Request[apiv1.InitReq
loginRequired := user.IsGuest() && api.cfg.AuthRequireGuestsToLogin loginRequired := user.IsGuest() && api.cfg.AuthRequireGuestsToLogin
showVersion := user.EffectivePolicy.ShowVersionNumber
currentVersion := ""
availableVersion := ""
if showVersion {
currentVersion = installationinfo.Build.Version
availableVersion = installationinfo.Runtime.AvailableVersion
}
res := &apiv1.InitResponse{ res := &apiv1.InitResponse{
ShowFooter: api.cfg.ShowFooter, ShowFooter: api.cfg.ShowFooter,
ShowNavigation: api.cfg.ShowNavigation, ShowNavigation: api.cfg.ShowNavigation,
ShowNewVersions: api.cfg.ShowNewVersions, ShowNewVersions: showVersion && api.cfg.ShowNewVersions,
AvailableVersion: installationinfo.Runtime.AvailableVersion, AvailableVersion: availableVersion,
CurrentVersion: installationinfo.Build.Version, CurrentVersion: currentVersion,
PageTitle: api.cfg.PageTitle, PageTitle: api.cfg.PageTitle,
SectionNavigationStyle: api.cfg.SectionNavigationStyle, SectionNavigationStyle: api.cfg.SectionNavigationStyle,
DefaultIconForBack: api.cfg.DefaultIconForBack, DefaultIconForBack: api.cfg.DefaultIconForBack,

View File

@ -55,8 +55,9 @@ func matchesEntity(binding *executor.ActionBinding, entity *entities.Entity) boo
func buildEffectivePolicy(policy *config.ConfigurationPolicy) *apiv1.EffectivePolicy { func buildEffectivePolicy(policy *config.ConfigurationPolicy) *apiv1.EffectivePolicy {
ret := &apiv1.EffectivePolicy{ ret := &apiv1.EffectivePolicy{
ShowDiagnostics: policy.ShowDiagnostics, ShowDiagnostics: policy.ShowDiagnostics,
ShowLogList: policy.ShowLogList, ShowLogList: policy.ShowLogList,
ShowVersionNumber: policy.ShowVersionNumber,
} }
return ret return ret

View File

@ -76,8 +76,9 @@ func (u *AuthenticatedUser) BuildUserAcls(cfg *config.Config) {
func getEffectivePolicy(cfg *config.Config, u *AuthenticatedUser) *config.ConfigurationPolicy { func getEffectivePolicy(cfg *config.Config, u *AuthenticatedUser) *config.ConfigurationPolicy {
ret := &config.ConfigurationPolicy{ ret := &config.ConfigurationPolicy{
ShowDiagnostics: cfg.DefaultPolicy.ShowDiagnostics, ShowDiagnostics: cfg.DefaultPolicy.ShowDiagnostics,
ShowLogList: cfg.DefaultPolicy.ShowLogList, ShowLogList: cfg.DefaultPolicy.ShowLogList,
ShowVersionNumber: cfg.DefaultPolicy.ShowVersionNumber,
} }
for _, acl := range cfg.AccessControlLists { for _, acl := range cfg.AccessControlLists {
@ -98,5 +99,9 @@ func buildConfigurationPolicy(ret *config.ConfigurationPolicy, policy config.Con
ret.ShowLogList = policy.ShowLogList ret.ShowLogList = policy.ShowLogList
} }
if policy.ShowVersionNumber {
ret.ShowVersionNumber = policy.ShowVersionNumber
}
return ret return ret
} }

View File

@ -98,8 +98,9 @@ type AccessControlList struct {
// ConfigurationPolicy defines global settings which are overridden with an ACL. // ConfigurationPolicy defines global settings which are overridden with an ACL.
type ConfigurationPolicy struct { type ConfigurationPolicy struct {
ShowDiagnostics bool `koanf:"showDiagnostics"` ShowDiagnostics bool `koanf:"showDiagnostics"`
ShowLogList bool `koanf:"showLogList"` ShowLogList bool `koanf:"showLogList"`
ShowVersionNumber bool `koanf:"showVersionNumber"`
} }
type PrometheusConfig struct { type PrometheusConfig struct {
@ -297,6 +298,7 @@ func DefaultConfigWithBasePort(basePort int) *Config {
config.DefaultPolicy.ShowDiagnostics = true config.DefaultPolicy.ShowDiagnostics = true
config.DefaultPolicy.ShowLogList = true config.DefaultPolicy.ShowLogList = true
config.DefaultPolicy.ShowVersionNumber = true
return &config return &config
} }

View File

@ -40,15 +40,23 @@ func configToSosreport(cfg *config.Config) *sosReportConfig {
} }
} }
func GetSosReport() string { func GetSosReport(redactVersion bool) string {
ret := "" ret := ""
ret += "### SOSREPORT START (copy all text to SOSREPORT END)\n" ret += "### SOSREPORT START (copy all text to SOSREPORT END)\n"
out, _ := yaml.Marshal(Build) buildForReport := *Build
if redactVersion {
buildForReport.Version = "[redacted]"
}
out, _ := yaml.Marshal(&buildForReport)
ret += fmt.Sprintf("# Build: \n%+v\n", string(out)) ret += fmt.Sprintf("# Build: \n%+v\n", string(out))
out, _ = yaml.Marshal(Runtime) runtimeForReport := *Runtime
if redactVersion {
runtimeForReport.AvailableVersion = "[redacted]"
}
out, _ = yaml.Marshal(&runtimeForReport)
ret += fmt.Sprintf("# Runtime:\n%+v\n", string(out)) ret += fmt.Sprintf("# Runtime:\n%+v\n", string(out))
out, _ = yaml.Marshal(configToSosreport(Config)) out, _ = yaml.Marshal(configToSosreport(Config))