// Copyright 2026 MarketAlly. All rights reserved. // SPDX-License-Identifier: MIT package admin import ( "net/http" "code.gitcaddy.com/server/v3/modules/plugins" "code.gitcaddy.com/server/v3/modules/setting" "code.gitcaddy.com/server/v3/modules/templates" "code.gitcaddy.com/server/v3/services/context" ) const ( tplAdminPlugins templates.TplName = "admin/plugins" ) // PluginInfo contains display information about a plugin type PluginInfo struct { Name string Version string Description string Features []string LicenseInfo *plugins.LicenseInfo } // Plugins shows the admin plugins page func Plugins(ctx *context.Context) { ctx.Data["Title"] = ctx.Tr("admin.plugins") ctx.Data["PageIsAdminPlugins"] = true ctx.Data["PluginsEnabled"] = setting.Plugins.Enabled ctx.Data["PluginsPath"] = setting.Plugins.Path if ctx.Data["PluginsPath"] == "" { ctx.Data["PluginsPath"] = setting.AppDataPath + "/plugins" } // Get all registered plugins allPlugins := plugins.All() pluginInfos := make([]PluginInfo, 0, len(allPlugins)) for _, p := range allPlugins { info := PluginInfo{ Name: p.Name(), Version: p.Version(), Description: p.Description(), Features: getPluginFeatures(p), } // Check if it's a licensed plugin if lp, ok := p.(plugins.LicensedPlugin); ok { info.LicenseInfo = lp.LicenseInfo() } pluginInfos = append(pluginInfos, info) } ctx.Data["Plugins"] = pluginInfos ctx.HTML(http.StatusOK, tplAdminPlugins) } // getPluginFeatures returns the feature labels for a plugin based on interfaces it implements func getPluginFeatures(p plugins.Plugin) []string { features := make([]string, 0) if _, ok := p.(plugins.DatabasePlugin); ok { features = append(features, "Database") } if _, ok := p.(plugins.WebRoutesPlugin); ok { features = append(features, "Web UI") } if _, ok := p.(plugins.APIRoutesPlugin); ok { features = append(features, "API") } if _, ok := p.(plugins.RepoRoutesPlugin); ok { features = append(features, "Repository") } if _, ok := p.(plugins.LicensedPlugin); ok { features = append(features, "Licensed") } return features }