feat: domain blocker plugin
This commit is contained in:
parent
c9edb57505
commit
7dd02c0056
25 changed files with 898 additions and 63 deletions
|
@ -98,6 +98,7 @@ func New(cfg *config.Config, database *db.Database, version string) *Admin {
|
|||
"channel_detail.html",
|
||||
"plugin_list.html",
|
||||
"channel_plugins_list.html",
|
||||
"channel_plugin_config.html",
|
||||
}
|
||||
|
||||
for _, tf := range templateFiles {
|
||||
|
@ -143,6 +144,7 @@ func (a *Admin) RegisterRoutes(mux *http.ServeMux) {
|
|||
mux.HandleFunc("/admin/channels", a.handleChannelList)
|
||||
mux.HandleFunc("/admin/channels/", a.handleChannelDetail)
|
||||
mux.HandleFunc("/admin/channelplugins", a.handleChannelPluginList)
|
||||
mux.HandleFunc("/admin/channelplugins/config/", a.handleChannelPluginConfig)
|
||||
mux.HandleFunc("/admin/channelplugins/", a.handleChannelPluginDetailOrDelete)
|
||||
}
|
||||
|
||||
|
@ -628,6 +630,96 @@ func (a *Admin) handleChannelPluginList(w http.ResponseWriter, r *http.Request)
|
|||
})
|
||||
}
|
||||
|
||||
// handleChannelPluginConfig handles the channel plugin configuration route
|
||||
func (a *Admin) handleChannelPluginConfig(w http.ResponseWriter, r *http.Request) {
|
||||
// Check if user is logged in
|
||||
if !a.isLoggedIn(r) {
|
||||
http.Redirect(w, r, "/admin/login", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
// Extract channel plugin ID from path
|
||||
path := r.URL.Path
|
||||
channelPluginID := strings.TrimPrefix(path, "/admin/channelplugins/config/")
|
||||
|
||||
// Convert channel plugin ID to int64
|
||||
id, err := strconv.ParseInt(channelPluginID, 10, 64)
|
||||
if err != nil {
|
||||
http.Error(w, "Invalid channel plugin ID", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Get the channel plugin
|
||||
channelPlugin, err := a.db.GetChannelPluginByID(id)
|
||||
if err != nil {
|
||||
http.Error(w, "Channel plugin not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
// Get the plugin
|
||||
p, err := plugin.Get(channelPlugin.PluginID)
|
||||
if err != nil {
|
||||
http.Error(w, "Plugin not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
// Handle form submission
|
||||
if r.Method == http.MethodPost {
|
||||
// Parse form
|
||||
if err := r.ParseForm(); err != nil {
|
||||
http.Error(w, "Bad request", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Create config map from form values
|
||||
config := make(map[string]interface{})
|
||||
|
||||
// Process form values based on plugin type
|
||||
if channelPlugin.PluginID == "security.domainblock" {
|
||||
// Get blocked domains from form
|
||||
blockedDomains := r.FormValue("blocked_domains")
|
||||
config["blocked_domains"] = blockedDomains
|
||||
} else {
|
||||
// Generic handling for other plugins
|
||||
for key, values := range r.Form {
|
||||
if key == "form_submitted" {
|
||||
continue
|
||||
}
|
||||
if len(values) == 1 {
|
||||
config[key] = values[0]
|
||||
} else {
|
||||
config[key] = values
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update plugin configuration
|
||||
if err := a.db.UpdateChannelPluginConfig(id, config); err != nil {
|
||||
http.Error(w, "Failed to update plugin configuration", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Get the channel to redirect back to the channel detail page
|
||||
channel, err := a.db.GetChannelByID(channelPlugin.ChannelID)
|
||||
if err != nil {
|
||||
a.addFlash(w, r, "Plugin configuration updated", "success")
|
||||
http.Redirect(w, r, "/admin/channelplugins", http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
a.addFlash(w, r, "Plugin configuration updated", "success")
|
||||
http.Redirect(w, r, fmt.Sprintf("/admin/channels/%d", channel.ID), http.StatusSeeOther)
|
||||
return
|
||||
}
|
||||
|
||||
// Render template
|
||||
a.render(w, r, "channel_plugin_config.html", TemplateData{
|
||||
Title: "Configure Plugin: " + p.GetName(),
|
||||
ChannelPlugin: channelPlugin,
|
||||
Plugins: map[string]model.Plugin{channelPlugin.PluginID: p},
|
||||
})
|
||||
}
|
||||
|
||||
// handleChannelPluginDetailOrDelete handles the channel plugin detail or delete route
|
||||
func (a *Admin) handleChannelPluginDetailOrDelete(w http.ResponseWriter, r *http.Request) {
|
||||
// Check if user is logged in
|
||||
|
|
|
@ -68,6 +68,10 @@
|
|||
{{if $channelPlugin.Enabled}}Disable{{else}}Enable{{end}}
|
||||
</button>
|
||||
</form>
|
||||
{{$plugin := index $.Plugins $pluginID}}
|
||||
{{if $plugin.RequiresConfig}}
|
||||
<a href="/admin/channelplugins/config/{{$channelPlugin.ID}}" class="btn btn-info btn-sm">Configure</a>
|
||||
{{end}}
|
||||
<form method="post" action="/admin/channelplugins/{{$channelPlugin.ID}}/delete" class="d-inline">
|
||||
<button type="submit" class="btn btn-danger btn-sm"
|
||||
onclick="return confirm('Are you sure you want to remove this plugin?')">Remove</button>
|
||||
|
|
37
internal/admin/templates/channel_plugin_config.html
Normal file
37
internal/admin/templates/channel_plugin_config.html
Normal file
|
@ -0,0 +1,37 @@
|
|||
{{define "content"}}
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<h3 class="card-title">Configure Plugin: {{(index .Plugins .ChannelPlugin.PluginID).GetName}}</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form method="post">
|
||||
<!-- Plugin configuration fields -->
|
||||
{{if eq .ChannelPlugin.PluginID "security.domainblock"}}
|
||||
<div class="mb-3">
|
||||
<label class="form-label">Blocked Domains</label>
|
||||
<input type="text" class="form-control" name="blocked_domains"
|
||||
value="{{with .ChannelPlugin.Config}}{{index . "blocked_domains"}}{{end}}"
|
||||
placeholder="example.com, evil.org, ads.com">
|
||||
<div class="form-text text-muted">
|
||||
Enter comma-separated list of domains to block (e.g., example.com, evil.org).
|
||||
Messages containing links to these domains will be blocked.
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="alert alert-warning">
|
||||
This plugin doesn't have specific configuration fields implemented yet.
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
<div class="form-footer">
|
||||
<button type="submit" class="btn btn-primary">Save Configuration</button>
|
||||
<a href="/admin/channels/{{.ChannelPlugin.ChannelID}}" class="btn btn-secondary">Cancel</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
|
@ -38,6 +38,10 @@
|
|||
{{if $channelPlugin.Enabled}}Disable{{else}}Enable{{end}}
|
||||
</button>
|
||||
</form>
|
||||
{{$plugin := index $.Plugins $pluginID}}
|
||||
{{if $plugin.ConfigRequired}}
|
||||
<a href="/admin/channelplugins/config/{{$channelPlugin.ID}}" class="btn btn-info btn-sm">Configure</a>
|
||||
{{end}}
|
||||
<form method="post" action="/admin/channelplugins/{{$channelPlugin.ID}}/delete" class="d-inline">
|
||||
<button type="submit" class="btn btn-danger btn-sm"
|
||||
onclick="return confirm('Are you sure you want to remove this plugin?')">Remove</button>
|
||||
|
@ -90,4 +94,4 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{end}}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue