|
@@ -43,11 +43,11 @@ const (
|
|
folderPageModeTemplate
|
|
folderPageModeTemplate
|
|
)
|
|
)
|
|
|
|
|
|
-type groupPageMode int
|
|
|
|
|
|
+type genericPageMode int
|
|
|
|
|
|
const (
|
|
const (
|
|
- groupPageModeAdd groupPageMode = iota + 1
|
|
|
|
- groupPageModeUpdate
|
|
|
|
|
|
+ genericPageModeAdd genericPageMode = iota + 1
|
|
|
|
+ genericPageModeUpdate
|
|
)
|
|
)
|
|
|
|
|
|
const (
|
|
const (
|
|
@@ -65,6 +65,10 @@ const (
|
|
templateGroup = "group.html"
|
|
templateGroup = "group.html"
|
|
templateFolders = "folders.html"
|
|
templateFolders = "folders.html"
|
|
templateFolder = "folder.html"
|
|
templateFolder = "folder.html"
|
|
|
|
+ templateEventRules = "eventrules.html"
|
|
|
|
+ templateEventRule = "eventrule.html"
|
|
|
|
+ templateEventActions = "eventactions.html"
|
|
|
|
+ templateEventAction = "eventaction.html"
|
|
templateMessage = "message.html"
|
|
templateMessage = "message.html"
|
|
templateStatus = "status.html"
|
|
templateStatus = "status.html"
|
|
templateLogin = "login.html"
|
|
templateLogin = "login.html"
|
|
@@ -80,6 +84,8 @@ const (
|
|
pageStatusTitle = "Status"
|
|
pageStatusTitle = "Status"
|
|
pageFoldersTitle = "Folders"
|
|
pageFoldersTitle = "Folders"
|
|
pageGroupsTitle = "Groups"
|
|
pageGroupsTitle = "Groups"
|
|
|
|
+ pageEventRulesTitle = "Event rules"
|
|
|
|
+ pageEventActionsTitle = "Event actions"
|
|
pageProfileTitle = "My profile"
|
|
pageProfileTitle = "My profile"
|
|
pageChangePwdTitle = "Change password"
|
|
pageChangePwdTitle = "Change password"
|
|
pageMaintenanceTitle = "Maintenance"
|
|
pageMaintenanceTitle = "Maintenance"
|
|
@@ -114,6 +120,10 @@ type basePage struct {
|
|
ProfileURL string
|
|
ProfileURL string
|
|
ChangePwdURL string
|
|
ChangePwdURL string
|
|
MFAURL string
|
|
MFAURL string
|
|
|
|
+ EventRulesURL string
|
|
|
|
+ EventRuleURL string
|
|
|
|
+ EventActionsURL string
|
|
|
|
+ EventActionURL string
|
|
FolderQuotaScanURL string
|
|
FolderQuotaScanURL string
|
|
StatusURL string
|
|
StatusURL string
|
|
MaintenanceURL string
|
|
MaintenanceURL string
|
|
@@ -123,11 +133,14 @@ type basePage struct {
|
|
ConnectionsTitle string
|
|
ConnectionsTitle string
|
|
FoldersTitle string
|
|
FoldersTitle string
|
|
GroupsTitle string
|
|
GroupsTitle string
|
|
|
|
+ EventRulesTitle string
|
|
|
|
+ EventActionsTitle string
|
|
StatusTitle string
|
|
StatusTitle string
|
|
MaintenanceTitle string
|
|
MaintenanceTitle string
|
|
DefenderTitle string
|
|
DefenderTitle string
|
|
Version string
|
|
Version string
|
|
CSRFToken string
|
|
CSRFToken string
|
|
|
|
+ IsEventManagerPage bool
|
|
HasDefender bool
|
|
HasDefender bool
|
|
HasExternalLogin bool
|
|
HasExternalLogin bool
|
|
LoggedAdmin *dataprovider.Admin
|
|
LoggedAdmin *dataprovider.Admin
|
|
@@ -154,6 +167,16 @@ type groupsPage struct {
|
|
Groups []dataprovider.Group
|
|
Groups []dataprovider.Group
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+type eventRulesPage struct {
|
|
|
|
+ basePage
|
|
|
|
+ Rules []dataprovider.EventRule
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+type eventActionsPage struct {
|
|
|
|
+ basePage
|
|
|
|
+ Actions []dataprovider.BaseEventAction
|
|
|
|
+}
|
|
|
|
+
|
|
type connectionsPage struct {
|
|
type connectionsPage struct {
|
|
basePage
|
|
basePage
|
|
Connections []common.ConnectionStatus
|
|
Connections []common.ConnectionStatus
|
|
@@ -183,7 +206,6 @@ type userPage struct {
|
|
TwoFactorProtocols []string
|
|
TwoFactorProtocols []string
|
|
WebClientOptions []string
|
|
WebClientOptions []string
|
|
RootDirPerms []string
|
|
RootDirPerms []string
|
|
- RedactedSecret string
|
|
|
|
Mode userPageMode
|
|
Mode userPageMode
|
|
VirtualFolders []vfs.BaseVirtualFolder
|
|
VirtualFolders []vfs.BaseVirtualFolder
|
|
Groups []dataprovider.Group
|
|
Groups []dataprovider.Group
|
|
@@ -253,7 +275,7 @@ type groupPage struct {
|
|
basePage
|
|
basePage
|
|
Group *dataprovider.Group
|
|
Group *dataprovider.Group
|
|
Error string
|
|
Error string
|
|
- Mode groupPageMode
|
|
|
|
|
|
+ Mode genericPageMode
|
|
ValidPerms []string
|
|
ValidPerms []string
|
|
ValidLoginMethods []string
|
|
ValidLoginMethods []string
|
|
ValidProtocols []string
|
|
ValidProtocols []string
|
|
@@ -263,6 +285,30 @@ type groupPage struct {
|
|
FsWrapper fsWrapper
|
|
FsWrapper fsWrapper
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+type eventActionPage struct {
|
|
|
|
+ basePage
|
|
|
|
+ Action dataprovider.BaseEventAction
|
|
|
|
+ ActionTypes []dataprovider.EnumMapping
|
|
|
|
+ HTTPMethods []string
|
|
|
|
+ RedactedSecret string
|
|
|
|
+ Error string
|
|
|
|
+ Mode genericPageMode
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+type eventRulePage struct {
|
|
|
|
+ basePage
|
|
|
|
+ Rule dataprovider.EventRule
|
|
|
|
+ TriggerTypes []dataprovider.EnumMapping
|
|
|
|
+ Actions []dataprovider.BaseEventAction
|
|
|
|
+ FsEvents []string
|
|
|
|
+ Protocols []string
|
|
|
|
+ ProviderEvents []string
|
|
|
|
+ ProviderObjects []string
|
|
|
|
+ Error string
|
|
|
|
+ Mode genericPageMode
|
|
|
|
+ IsShared bool
|
|
|
|
+}
|
|
|
|
+
|
|
type messagePage struct {
|
|
type messagePage struct {
|
|
basePage
|
|
basePage
|
|
Error string
|
|
Error string
|
|
@@ -341,6 +387,26 @@ func loadAdminTemplates(templatesPath string) {
|
|
filepath.Join(templatesPath, templateAdminDir, templateSharedComponents),
|
|
filepath.Join(templatesPath, templateAdminDir, templateSharedComponents),
|
|
filepath.Join(templatesPath, templateAdminDir, templateGroup),
|
|
filepath.Join(templatesPath, templateAdminDir, templateGroup),
|
|
}
|
|
}
|
|
|
|
+ eventRulesPaths := []string{
|
|
|
|
+ filepath.Join(templatesPath, templateCommonDir, templateCommonCSS),
|
|
|
|
+ filepath.Join(templatesPath, templateAdminDir, templateBase),
|
|
|
|
+ filepath.Join(templatesPath, templateAdminDir, templateEventRules),
|
|
|
|
+ }
|
|
|
|
+ eventRulePaths := []string{
|
|
|
|
+ filepath.Join(templatesPath, templateCommonDir, templateCommonCSS),
|
|
|
|
+ filepath.Join(templatesPath, templateAdminDir, templateBase),
|
|
|
|
+ filepath.Join(templatesPath, templateAdminDir, templateEventRule),
|
|
|
|
+ }
|
|
|
|
+ eventActionsPaths := []string{
|
|
|
|
+ filepath.Join(templatesPath, templateCommonDir, templateCommonCSS),
|
|
|
|
+ filepath.Join(templatesPath, templateAdminDir, templateBase),
|
|
|
|
+ filepath.Join(templatesPath, templateAdminDir, templateEventActions),
|
|
|
|
+ }
|
|
|
|
+ eventActionPaths := []string{
|
|
|
|
+ filepath.Join(templatesPath, templateCommonDir, templateCommonCSS),
|
|
|
|
+ filepath.Join(templatesPath, templateAdminDir, templateBase),
|
|
|
|
+ filepath.Join(templatesPath, templateAdminDir, templateEventAction),
|
|
|
|
+ }
|
|
statusPaths := []string{
|
|
statusPaths := []string{
|
|
filepath.Join(templatesPath, templateCommonDir, templateCommonCSS),
|
|
filepath.Join(templatesPath, templateCommonDir, templateCommonCSS),
|
|
filepath.Join(templatesPath, templateAdminDir, templateBase),
|
|
filepath.Join(templatesPath, templateAdminDir, templateBase),
|
|
@@ -408,6 +474,10 @@ func loadAdminTemplates(templatesPath string) {
|
|
groupTmpl := util.LoadTemplate(fsBaseTpl, groupPaths...)
|
|
groupTmpl := util.LoadTemplate(fsBaseTpl, groupPaths...)
|
|
foldersTmpl := util.LoadTemplate(nil, foldersPaths...)
|
|
foldersTmpl := util.LoadTemplate(nil, foldersPaths...)
|
|
folderTmpl := util.LoadTemplate(fsBaseTpl, folderPaths...)
|
|
folderTmpl := util.LoadTemplate(fsBaseTpl, folderPaths...)
|
|
|
|
+ eventRulesTmpl := util.LoadTemplate(nil, eventRulesPaths...)
|
|
|
|
+ eventRuleTmpl := util.LoadTemplate(nil, eventRulePaths...)
|
|
|
|
+ eventActionsTmpl := util.LoadTemplate(nil, eventActionsPaths...)
|
|
|
|
+ eventActionTmpl := util.LoadTemplate(nil, eventActionPaths...)
|
|
statusTmpl := util.LoadTemplate(nil, statusPaths...)
|
|
statusTmpl := util.LoadTemplate(nil, statusPaths...)
|
|
loginTmpl := util.LoadTemplate(nil, loginPaths...)
|
|
loginTmpl := util.LoadTemplate(nil, loginPaths...)
|
|
profileTmpl := util.LoadTemplate(nil, profilePaths...)
|
|
profileTmpl := util.LoadTemplate(nil, profilePaths...)
|
|
@@ -431,6 +501,10 @@ func loadAdminTemplates(templatesPath string) {
|
|
adminTemplates[templateGroup] = groupTmpl
|
|
adminTemplates[templateGroup] = groupTmpl
|
|
adminTemplates[templateFolders] = foldersTmpl
|
|
adminTemplates[templateFolders] = foldersTmpl
|
|
adminTemplates[templateFolder] = folderTmpl
|
|
adminTemplates[templateFolder] = folderTmpl
|
|
|
|
+ adminTemplates[templateEventRules] = eventRulesTmpl
|
|
|
|
+ adminTemplates[templateEventRule] = eventRuleTmpl
|
|
|
|
+ adminTemplates[templateEventActions] = eventActionsTmpl
|
|
|
|
+ adminTemplates[templateEventAction] = eventActionTmpl
|
|
adminTemplates[templateStatus] = statusTmpl
|
|
adminTemplates[templateStatus] = statusTmpl
|
|
adminTemplates[templateLogin] = loginTmpl
|
|
adminTemplates[templateLogin] = loginTmpl
|
|
adminTemplates[templateProfile] = profileTmpl
|
|
adminTemplates[templateProfile] = profileTmpl
|
|
@@ -445,6 +519,22 @@ func loadAdminTemplates(templatesPath string) {
|
|
adminTemplates[templateResetPassword] = resetPwdTmpl
|
|
adminTemplates[templateResetPassword] = resetPwdTmpl
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+func isEventManagerResource(currentURL string) bool {
|
|
|
|
+ if currentURL == webAdminEventRulesPath {
|
|
|
|
+ return true
|
|
|
|
+ }
|
|
|
|
+ if currentURL == webAdminEventActionsPath {
|
|
|
|
+ return true
|
|
|
|
+ }
|
|
|
|
+ if currentURL == webAdminEventRulePath || strings.HasPrefix(currentURL, webAdminEventRulePath+"/") {
|
|
|
|
+ return true
|
|
|
|
+ }
|
|
|
|
+ if currentURL == webAdminEventActionPath || strings.HasPrefix(currentURL, webAdminEventActionPath+"/") {
|
|
|
|
+ return true
|
|
|
|
+ }
|
|
|
|
+ return false
|
|
|
|
+}
|
|
|
|
+
|
|
func (s *httpdServer) getBasePageData(title, currentURL string, r *http.Request) basePage {
|
|
func (s *httpdServer) getBasePageData(title, currentURL string, r *http.Request) basePage {
|
|
var csrfToken string
|
|
var csrfToken string
|
|
if currentURL != "" {
|
|
if currentURL != "" {
|
|
@@ -468,6 +558,10 @@ func (s *httpdServer) getBasePageData(title, currentURL string, r *http.Request)
|
|
ProfileURL: webAdminProfilePath,
|
|
ProfileURL: webAdminProfilePath,
|
|
ChangePwdURL: webChangeAdminPwdPath,
|
|
ChangePwdURL: webChangeAdminPwdPath,
|
|
MFAURL: webAdminMFAPath,
|
|
MFAURL: webAdminMFAPath,
|
|
|
|
+ EventRulesURL: webAdminEventRulesPath,
|
|
|
|
+ EventRuleURL: webAdminEventRulePath,
|
|
|
|
+ EventActionsURL: webAdminEventActionsPath,
|
|
|
|
+ EventActionURL: webAdminEventActionPath,
|
|
QuotaScanURL: webQuotaScanPath,
|
|
QuotaScanURL: webQuotaScanPath,
|
|
ConnectionsURL: webConnectionsPath,
|
|
ConnectionsURL: webConnectionsPath,
|
|
StatusURL: webStatusPath,
|
|
StatusURL: webStatusPath,
|
|
@@ -479,11 +573,14 @@ func (s *httpdServer) getBasePageData(title, currentURL string, r *http.Request)
|
|
ConnectionsTitle: pageConnectionsTitle,
|
|
ConnectionsTitle: pageConnectionsTitle,
|
|
FoldersTitle: pageFoldersTitle,
|
|
FoldersTitle: pageFoldersTitle,
|
|
GroupsTitle: pageGroupsTitle,
|
|
GroupsTitle: pageGroupsTitle,
|
|
|
|
+ EventRulesTitle: pageEventRulesTitle,
|
|
|
|
+ EventActionsTitle: pageEventActionsTitle,
|
|
StatusTitle: pageStatusTitle,
|
|
StatusTitle: pageStatusTitle,
|
|
MaintenanceTitle: pageMaintenanceTitle,
|
|
MaintenanceTitle: pageMaintenanceTitle,
|
|
DefenderTitle: pageDefenderTitle,
|
|
DefenderTitle: pageDefenderTitle,
|
|
Version: version.GetAsString(),
|
|
Version: version.GetAsString(),
|
|
LoggedAdmin: getAdminFromToken(r),
|
|
LoggedAdmin: getAdminFromToken(r),
|
|
|
|
+ IsEventManagerPage: isEventManagerResource(currentURL),
|
|
HasDefender: common.Config.DefenderConfig.Enabled,
|
|
HasDefender: common.Config.DefenderConfig.Enabled,
|
|
HasExternalLogin: isLoggedInWithOIDC(r),
|
|
HasExternalLogin: isLoggedInWithOIDC(r),
|
|
CSRFToken: csrfToken,
|
|
CSRFToken: csrfToken,
|
|
@@ -721,7 +818,7 @@ func (s *httpdServer) renderUserPage(w http.ResponseWriter, r *http.Request, use
|
|
}
|
|
}
|
|
|
|
|
|
func (s *httpdServer) renderGroupPage(w http.ResponseWriter, r *http.Request, group dataprovider.Group,
|
|
func (s *httpdServer) renderGroupPage(w http.ResponseWriter, r *http.Request, group dataprovider.Group,
|
|
- mode groupPageMode, error string,
|
|
|
|
|
|
+ mode genericPageMode, error string,
|
|
) {
|
|
) {
|
|
folders, err := s.getWebVirtualFolders(w, r, defaultQueryLimit, true)
|
|
folders, err := s.getWebVirtualFolders(w, r, defaultQueryLimit, true)
|
|
if err != nil {
|
|
if err != nil {
|
|
@@ -731,10 +828,10 @@ func (s *httpdServer) renderGroupPage(w http.ResponseWriter, r *http.Request, gr
|
|
group.UserSettings.FsConfig.RedactedSecret = redactedSecret
|
|
group.UserSettings.FsConfig.RedactedSecret = redactedSecret
|
|
var title, currentURL string
|
|
var title, currentURL string
|
|
switch mode {
|
|
switch mode {
|
|
- case groupPageModeAdd:
|
|
|
|
|
|
+ case genericPageModeAdd:
|
|
title = "Add a new group"
|
|
title = "Add a new group"
|
|
currentURL = webGroupPath
|
|
currentURL = webGroupPath
|
|
- case groupPageModeUpdate:
|
|
|
|
|
|
+ case genericPageModeUpdate:
|
|
title = "Update group"
|
|
title = "Update group"
|
|
currentURL = fmt.Sprintf("%v/%v", webGroupPath, url.PathEscape(group.Name))
|
|
currentURL = fmt.Sprintf("%v/%v", webGroupPath, url.PathEscape(group.Name))
|
|
}
|
|
}
|
|
@@ -763,6 +860,71 @@ func (s *httpdServer) renderGroupPage(w http.ResponseWriter, r *http.Request, gr
|
|
renderAdminTemplate(w, templateGroup, data)
|
|
renderAdminTemplate(w, templateGroup, data)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+func (s *httpdServer) renderEventActionPage(w http.ResponseWriter, r *http.Request, action dataprovider.BaseEventAction,
|
|
|
|
+ mode genericPageMode, error string,
|
|
|
|
+) {
|
|
|
|
+ action.Options.SetEmptySecretsIfNil()
|
|
|
|
+ var title, currentURL string
|
|
|
|
+ switch mode {
|
|
|
|
+ case genericPageModeAdd:
|
|
|
|
+ title = "Add a new event action"
|
|
|
|
+ currentURL = webAdminEventActionPath
|
|
|
|
+ case genericPageModeUpdate:
|
|
|
|
+ title = "Update event action"
|
|
|
|
+ currentURL = fmt.Sprintf("%v/%v", webAdminEventActionPath, url.PathEscape(action.Name))
|
|
|
|
+ }
|
|
|
|
+ if action.Options.HTTPConfig.Timeout == 0 {
|
|
|
|
+ action.Options.HTTPConfig.Timeout = 20
|
|
|
|
+ }
|
|
|
|
+ if action.Options.CmdConfig.Timeout == 0 {
|
|
|
|
+ action.Options.CmdConfig.Timeout = 20
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ data := eventActionPage{
|
|
|
|
+ basePage: s.getBasePageData(title, currentURL, r),
|
|
|
|
+ Action: action,
|
|
|
|
+ ActionTypes: dataprovider.EventActionTypes,
|
|
|
|
+ HTTPMethods: dataprovider.SupportedHTTPActionMethods,
|
|
|
|
+ RedactedSecret: redactedSecret,
|
|
|
|
+ Error: error,
|
|
|
|
+ Mode: mode,
|
|
|
|
+ }
|
|
|
|
+ renderAdminTemplate(w, templateEventAction, data)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *httpdServer) renderEventRulePage(w http.ResponseWriter, r *http.Request, rule dataprovider.EventRule,
|
|
|
|
+ mode genericPageMode, error string,
|
|
|
|
+) {
|
|
|
|
+ actions, err := s.getWebEventActions(w, r, defaultQueryLimit, true)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ var title, currentURL string
|
|
|
|
+ switch mode {
|
|
|
|
+ case genericPageModeAdd:
|
|
|
|
+ title = "Add new event rules"
|
|
|
|
+ currentURL = webAdminEventRulePath
|
|
|
|
+ case genericPageModeUpdate:
|
|
|
|
+ title = "Update event rules"
|
|
|
|
+ currentURL = fmt.Sprintf("%v/%v", webAdminEventRulePath, url.PathEscape(rule.Name))
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ data := eventRulePage{
|
|
|
|
+ basePage: s.getBasePageData(title, currentURL, r),
|
|
|
|
+ Rule: rule,
|
|
|
|
+ TriggerTypes: dataprovider.EventTriggerTypes,
|
|
|
|
+ Actions: actions,
|
|
|
|
+ FsEvents: dataprovider.SupportedFsEvents,
|
|
|
|
+ Protocols: dataprovider.SupportedRuleConditionProtocols,
|
|
|
|
+ ProviderEvents: dataprovider.SupportedProviderEvents,
|
|
|
|
+ ProviderObjects: dataprovider.SupporteRuleConditionProviderObjects,
|
|
|
|
+ Error: error,
|
|
|
|
+ Mode: mode,
|
|
|
|
+ IsShared: s.isShared > 0,
|
|
|
|
+ }
|
|
|
|
+ renderAdminTemplate(w, templateEventRule, data)
|
|
|
|
+}
|
|
|
|
+
|
|
func (s *httpdServer) renderFolderPage(w http.ResponseWriter, r *http.Request, folder vfs.BaseVirtualFolder,
|
|
func (s *httpdServer) renderFolderPage(w http.ResponseWriter, r *http.Request, folder vfs.BaseVirtualFolder,
|
|
mode folderPageMode, error string,
|
|
mode folderPageMode, error string,
|
|
) {
|
|
) {
|
|
@@ -1630,6 +1792,204 @@ func getGroupFromPostFields(r *http.Request) (dataprovider.Group, error) {
|
|
return group, nil
|
|
return group, nil
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+func getKeyValsFromPostFields(r *http.Request, key, val string) []dataprovider.KeyValue {
|
|
|
|
+ var res []dataprovider.KeyValue
|
|
|
|
+ for k := range r.Form {
|
|
|
|
+ if strings.HasPrefix(k, key) {
|
|
|
|
+ formKey := r.Form.Get(k)
|
|
|
|
+ idx := strings.TrimPrefix(k, key)
|
|
|
|
+ formVal := r.Form.Get(fmt.Sprintf("%s%s", val, idx))
|
|
|
|
+ if formKey != "" && formVal != "" {
|
|
|
|
+ res = append(res, dataprovider.KeyValue{
|
|
|
|
+ Key: formKey,
|
|
|
|
+ Value: formVal,
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return res
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func getEventActionOptionsFromPostFields(r *http.Request) (dataprovider.BaseEventActionOptions, error) {
|
|
|
|
+ httpTimeout, err := strconv.Atoi(r.Form.Get("http_timeout"))
|
|
|
|
+ if err != nil {
|
|
|
|
+ return dataprovider.BaseEventActionOptions{}, fmt.Errorf("invalid http timeout: %w", err)
|
|
|
|
+ }
|
|
|
|
+ cmdTimeout, err := strconv.Atoi(r.Form.Get("cmd_timeout"))
|
|
|
|
+ if err != nil {
|
|
|
|
+ return dataprovider.BaseEventActionOptions{}, fmt.Errorf("invalid command timeout: %w", err)
|
|
|
|
+ }
|
|
|
|
+ options := dataprovider.BaseEventActionOptions{
|
|
|
|
+ HTTPConfig: dataprovider.EventActionHTTPConfig{
|
|
|
|
+ Endpoint: r.Form.Get("http_endpoint"),
|
|
|
|
+ Username: r.Form.Get("http_username"),
|
|
|
|
+ Password: getSecretFromFormField(r, "http_password"),
|
|
|
|
+ Headers: getKeyValsFromPostFields(r, "http_header_key", "http_header_val"),
|
|
|
|
+ Timeout: httpTimeout,
|
|
|
|
+ SkipTLSVerify: r.Form.Get("http_skip_tls_verify") != "",
|
|
|
|
+ Method: r.Form.Get("http_method"),
|
|
|
|
+ QueryParameters: getKeyValsFromPostFields(r, "http_query_key", "http_query_val"),
|
|
|
|
+ Body: r.Form.Get("http_body"),
|
|
|
|
+ },
|
|
|
|
+ CmdConfig: dataprovider.EventActionCommandConfig{
|
|
|
|
+ Cmd: r.Form.Get("cmd_path"),
|
|
|
|
+ Timeout: cmdTimeout,
|
|
|
|
+ EnvVars: getKeyValsFromPostFields(r, "cmd_env_key", "cmd_env_val"),
|
|
|
|
+ },
|
|
|
|
+ EmailConfig: dataprovider.EventActionEmailConfig{
|
|
|
|
+ Recipients: strings.Split(strings.ReplaceAll(r.Form.Get("email_recipients"), " ", ""), ","),
|
|
|
|
+ Subject: r.Form.Get("email_subject"),
|
|
|
|
+ Body: r.Form.Get("email_body"),
|
|
|
|
+ },
|
|
|
|
+ }
|
|
|
|
+ return options, nil
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func getEventActionFromPostFields(r *http.Request) (dataprovider.BaseEventAction, error) {
|
|
|
|
+ err := r.ParseForm()
|
|
|
|
+ if err != nil {
|
|
|
|
+ return dataprovider.BaseEventAction{}, err
|
|
|
|
+ }
|
|
|
|
+ actionType, err := strconv.Atoi(r.Form.Get("type"))
|
|
|
|
+ if err != nil {
|
|
|
|
+ return dataprovider.BaseEventAction{}, fmt.Errorf("invalid action type: %w", err)
|
|
|
|
+ }
|
|
|
|
+ options, err := getEventActionOptionsFromPostFields(r)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return dataprovider.BaseEventAction{}, err
|
|
|
|
+ }
|
|
|
|
+ action := dataprovider.BaseEventAction{
|
|
|
|
+ Name: r.Form.Get("name"),
|
|
|
|
+ Description: r.Form.Get("description"),
|
|
|
|
+ Type: actionType,
|
|
|
|
+ Options: options,
|
|
|
|
+ }
|
|
|
|
+ return action, nil
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func getEventRuleConditionsFromPostFields(r *http.Request) (dataprovider.EventConditions, error) {
|
|
|
|
+ var schedules []dataprovider.Schedule
|
|
|
|
+ var names, fsPaths []dataprovider.ConditionPattern
|
|
|
|
+ for k := range r.Form {
|
|
|
|
+ if strings.HasPrefix(k, "schedule_hour") {
|
|
|
|
+ hour := r.Form.Get(k)
|
|
|
|
+ if hour != "" {
|
|
|
|
+ idx := strings.TrimPrefix(k, "schedule_hour")
|
|
|
|
+ dayOfWeek := r.Form.Get(fmt.Sprintf("schedule_day_of_week%s", idx))
|
|
|
|
+ dayOfMonth := r.Form.Get(fmt.Sprintf("schedule_day_of_month%s", idx))
|
|
|
|
+ month := r.Form.Get(fmt.Sprintf("schedule_month%s", idx))
|
|
|
|
+ schedules = append(schedules, dataprovider.Schedule{
|
|
|
|
+ Hours: hour,
|
|
|
|
+ DayOfWeek: dayOfWeek,
|
|
|
|
+ DayOfMonth: dayOfMonth,
|
|
|
|
+ Month: month,
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if strings.HasPrefix(k, "name_pattern") {
|
|
|
|
+ pattern := r.Form.Get(k)
|
|
|
|
+ if pattern != "" {
|
|
|
|
+ idx := strings.TrimPrefix(k, "name_pattern")
|
|
|
|
+ patternType := r.Form.Get(fmt.Sprintf("type_name_pattern%s", idx))
|
|
|
|
+ names = append(names, dataprovider.ConditionPattern{
|
|
|
|
+ Pattern: pattern,
|
|
|
|
+ InverseMatch: patternType == "inverse",
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if strings.HasPrefix(k, "fs_path_pattern") {
|
|
|
|
+ pattern := r.Form.Get(k)
|
|
|
|
+ if pattern != "" {
|
|
|
|
+ idx := strings.TrimPrefix(k, "fs_path_pattern")
|
|
|
|
+ patternType := r.Form.Get(fmt.Sprintf("type_fs_path_pattern%s", idx))
|
|
|
|
+ fsPaths = append(fsPaths, dataprovider.ConditionPattern{
|
|
|
|
+ Pattern: pattern,
|
|
|
|
+ InverseMatch: patternType == "inverse",
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ minFileSize, err := strconv.ParseInt(r.Form.Get("fs_min_size"), 10, 64)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return dataprovider.EventConditions{}, fmt.Errorf("invalid min file size: %w", err)
|
|
|
|
+ }
|
|
|
|
+ maxFileSize, err := strconv.ParseInt(r.Form.Get("fs_max_size"), 10, 64)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return dataprovider.EventConditions{}, fmt.Errorf("invalid max file size: %w", err)
|
|
|
|
+ }
|
|
|
|
+ conditions := dataprovider.EventConditions{
|
|
|
|
+ FsEvents: r.Form["fs_events"],
|
|
|
|
+ ProviderEvents: r.Form["provider_events"],
|
|
|
|
+ Schedules: schedules,
|
|
|
|
+ Options: dataprovider.ConditionOptions{
|
|
|
|
+ Names: names,
|
|
|
|
+ FsPaths: fsPaths,
|
|
|
|
+ Protocols: r.Form["fs_protocols"],
|
|
|
|
+ ProviderObjects: r.Form["provider_objects"],
|
|
|
|
+ MinFileSize: minFileSize,
|
|
|
|
+ MaxFileSize: maxFileSize,
|
|
|
|
+ ConcurrentExecution: r.Form.Get("concurrent_execution") != "",
|
|
|
|
+ },
|
|
|
|
+ }
|
|
|
|
+ return conditions, nil
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func getEventRuleActionsFromPostFields(r *http.Request) ([]dataprovider.EventAction, error) {
|
|
|
|
+ var actions []dataprovider.EventAction
|
|
|
|
+ for k := range r.Form {
|
|
|
|
+ if strings.HasPrefix(k, "action_name") {
|
|
|
|
+ name := r.Form.Get(k)
|
|
|
|
+ if name != "" {
|
|
|
|
+ idx := strings.TrimPrefix(k, "action_name")
|
|
|
|
+ order, err := strconv.Atoi(r.Form.Get(fmt.Sprintf("action_order%s", idx)))
|
|
|
|
+ if err != nil {
|
|
|
|
+ return actions, fmt.Errorf("invalid order: %w", err)
|
|
|
|
+ }
|
|
|
|
+ options := r.Form[fmt.Sprintf("action_options%s", idx)]
|
|
|
|
+ actions = append(actions, dataprovider.EventAction{
|
|
|
|
+ BaseEventAction: dataprovider.BaseEventAction{
|
|
|
|
+ Name: name,
|
|
|
|
+ },
|
|
|
|
+ Order: order + 1,
|
|
|
|
+ Options: dataprovider.EventActionOptions{
|
|
|
|
+ IsFailureAction: util.Contains(options, "1"),
|
|
|
|
+ StopOnFailure: util.Contains(options, "2"),
|
|
|
|
+ ExecuteSync: util.Contains(options, "3"),
|
|
|
|
+ },
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return actions, nil
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func getEventRuleFromPostFields(r *http.Request) (dataprovider.EventRule, error) {
|
|
|
|
+ err := r.ParseForm()
|
|
|
|
+ if err != nil {
|
|
|
|
+ return dataprovider.EventRule{}, err
|
|
|
|
+ }
|
|
|
|
+ trigger, err := strconv.Atoi(r.Form.Get("trigger"))
|
|
|
|
+ if err != nil {
|
|
|
|
+ return dataprovider.EventRule{}, fmt.Errorf("invalid trigger: %w", err)
|
|
|
|
+ }
|
|
|
|
+ conditions, err := getEventRuleConditionsFromPostFields(r)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return dataprovider.EventRule{}, err
|
|
|
|
+ }
|
|
|
|
+ actions, err := getEventRuleActionsFromPostFields(r)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return dataprovider.EventRule{}, err
|
|
|
|
+ }
|
|
|
|
+ rule := dataprovider.EventRule{
|
|
|
|
+ Name: r.Form.Get("name"),
|
|
|
|
+ Description: r.Form.Get("description"),
|
|
|
|
+ Trigger: trigger,
|
|
|
|
+ Conditions: conditions,
|
|
|
|
+ Actions: actions,
|
|
|
|
+ }
|
|
|
|
+ return rule, nil
|
|
|
|
+}
|
|
|
|
+
|
|
func (s *httpdServer) handleWebAdminForgotPwd(w http.ResponseWriter, r *http.Request) {
|
|
func (s *httpdServer) handleWebAdminForgotPwd(w http.ResponseWriter, r *http.Request) {
|
|
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
|
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
|
if !smtp.IsEnabled() {
|
|
if !smtp.IsEnabled() {
|
|
@@ -2450,7 +2810,7 @@ func (s *httpdServer) handleWebGetGroups(w http.ResponseWriter, r *http.Request)
|
|
|
|
|
|
func (s *httpdServer) handleWebAddGroupGet(w http.ResponseWriter, r *http.Request) {
|
|
func (s *httpdServer) handleWebAddGroupGet(w http.ResponseWriter, r *http.Request) {
|
|
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
|
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
|
- s.renderGroupPage(w, r, dataprovider.Group{}, groupPageModeAdd, "")
|
|
|
|
|
|
+ s.renderGroupPage(w, r, dataprovider.Group{}, genericPageModeAdd, "")
|
|
}
|
|
}
|
|
|
|
|
|
func (s *httpdServer) handleWebAddGroupPost(w http.ResponseWriter, r *http.Request) {
|
|
func (s *httpdServer) handleWebAddGroupPost(w http.ResponseWriter, r *http.Request) {
|
|
@@ -2462,7 +2822,7 @@ func (s *httpdServer) handleWebAddGroupPost(w http.ResponseWriter, r *http.Reque
|
|
}
|
|
}
|
|
group, err := getGroupFromPostFields(r)
|
|
group, err := getGroupFromPostFields(r)
|
|
if err != nil {
|
|
if err != nil {
|
|
- s.renderGroupPage(w, r, group, groupPageModeAdd, err.Error())
|
|
|
|
|
|
+ s.renderGroupPage(w, r, group, genericPageModeAdd, err.Error())
|
|
return
|
|
return
|
|
}
|
|
}
|
|
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
|
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
|
@@ -2472,7 +2832,7 @@ func (s *httpdServer) handleWebAddGroupPost(w http.ResponseWriter, r *http.Reque
|
|
}
|
|
}
|
|
err = dataprovider.AddGroup(&group, claims.Username, ipAddr)
|
|
err = dataprovider.AddGroup(&group, claims.Username, ipAddr)
|
|
if err != nil {
|
|
if err != nil {
|
|
- s.renderGroupPage(w, r, group, groupPageModeAdd, err.Error())
|
|
|
|
|
|
+ s.renderGroupPage(w, r, group, genericPageModeAdd, err.Error())
|
|
return
|
|
return
|
|
}
|
|
}
|
|
http.Redirect(w, r, webGroupsPath, http.StatusSeeOther)
|
|
http.Redirect(w, r, webGroupsPath, http.StatusSeeOther)
|
|
@@ -2483,7 +2843,7 @@ func (s *httpdServer) handleWebUpdateGroupGet(w http.ResponseWriter, r *http.Req
|
|
name := getURLParam(r, "name")
|
|
name := getURLParam(r, "name")
|
|
group, err := dataprovider.GroupExists(name)
|
|
group, err := dataprovider.GroupExists(name)
|
|
if err == nil {
|
|
if err == nil {
|
|
- s.renderGroupPage(w, r, group, groupPageModeUpdate, "")
|
|
|
|
|
|
+ s.renderGroupPage(w, r, group, genericPageModeUpdate, "")
|
|
} else if _, ok := err.(*util.RecordNotFoundError); ok {
|
|
} else if _, ok := err.(*util.RecordNotFoundError); ok {
|
|
s.renderNotFoundPage(w, r, err)
|
|
s.renderNotFoundPage(w, r, err)
|
|
} else {
|
|
} else {
|
|
@@ -2509,7 +2869,7 @@ func (s *httpdServer) handleWebUpdateGroupPost(w http.ResponseWriter, r *http.Re
|
|
}
|
|
}
|
|
updatedGroup, err := getGroupFromPostFields(r)
|
|
updatedGroup, err := getGroupFromPostFields(r)
|
|
if err != nil {
|
|
if err != nil {
|
|
- s.renderGroupPage(w, r, group, groupPageModeUpdate, err.Error())
|
|
|
|
|
|
+ s.renderGroupPage(w, r, group, genericPageModeUpdate, err.Error())
|
|
return
|
|
return
|
|
}
|
|
}
|
|
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
|
ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
|
@@ -2530,8 +2890,245 @@ func (s *httpdServer) handleWebUpdateGroupPost(w http.ResponseWriter, r *http.Re
|
|
|
|
|
|
err = dataprovider.UpdateGroup(&updatedGroup, group.Users, claims.Username, ipAddr)
|
|
err = dataprovider.UpdateGroup(&updatedGroup, group.Users, claims.Username, ipAddr)
|
|
if err != nil {
|
|
if err != nil {
|
|
- s.renderGroupPage(w, r, updatedGroup, groupPageModeUpdate, err.Error())
|
|
|
|
|
|
+ s.renderGroupPage(w, r, updatedGroup, genericPageModeUpdate, err.Error())
|
|
return
|
|
return
|
|
}
|
|
}
|
|
http.Redirect(w, r, webGroupsPath, http.StatusSeeOther)
|
|
http.Redirect(w, r, webGroupsPath, http.StatusSeeOther)
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+func (s *httpdServer) getWebEventActions(w http.ResponseWriter, r *http.Request, limit int, minimal bool,
|
|
|
|
+) ([]dataprovider.BaseEventAction, error) {
|
|
|
|
+ actions := make([]dataprovider.BaseEventAction, 0, limit)
|
|
|
|
+ for {
|
|
|
|
+ res, err := dataprovider.GetEventActions(limit, len(actions), dataprovider.OrderASC, minimal)
|
|
|
|
+ if err != nil {
|
|
|
|
+ s.renderInternalServerErrorPage(w, r, err)
|
|
|
|
+ return actions, err
|
|
|
|
+ }
|
|
|
|
+ actions = append(actions, res...)
|
|
|
|
+ if len(res) < limit {
|
|
|
|
+ break
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return actions, nil
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *httpdServer) handleWebGetEventActions(w http.ResponseWriter, r *http.Request) {
|
|
|
|
+ r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
|
|
|
+ limit := defaultQueryLimit
|
|
|
|
+ if _, ok := r.URL.Query()["qlimit"]; ok {
|
|
|
|
+ var err error
|
|
|
|
+ limit, err = strconv.Atoi(r.URL.Query().Get("qlimit"))
|
|
|
|
+ if err != nil {
|
|
|
|
+ limit = defaultQueryLimit
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ actions, err := s.getWebEventActions(w, r, limit, false)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ data := eventActionsPage{
|
|
|
|
+ basePage: s.getBasePageData(pageEventActionsTitle, webAdminEventActionsPath, r),
|
|
|
|
+ Actions: actions,
|
|
|
|
+ }
|
|
|
|
+ renderAdminTemplate(w, templateEventActions, data)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *httpdServer) handleWebAddEventActionGet(w http.ResponseWriter, r *http.Request) {
|
|
|
|
+ r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
|
|
|
+ action := dataprovider.BaseEventAction{
|
|
|
|
+ Type: dataprovider.ActionTypeHTTP,
|
|
|
|
+ }
|
|
|
|
+ s.renderEventActionPage(w, r, action, genericPageModeAdd, "")
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *httpdServer) handleWebAddEventActionPost(w http.ResponseWriter, r *http.Request) {
|
|
|
|
+ r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
|
|
|
+ claims, err := getTokenClaims(r)
|
|
|
|
+ if err != nil || claims.Username == "" {
|
|
|
|
+ s.renderBadRequestPage(w, r, errors.New("invalid token claims"))
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ action, err := getEventActionFromPostFields(r)
|
|
|
|
+ if err != nil {
|
|
|
|
+ s.renderEventActionPage(w, r, action, genericPageModeAdd, err.Error())
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
|
|
|
+ if err := verifyCSRFToken(r.Form.Get(csrfFormToken), ipAddr); err != nil {
|
|
|
|
+ s.renderForbiddenPage(w, r, err.Error())
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ if err = dataprovider.AddEventAction(&action, claims.Username, ipAddr); err != nil {
|
|
|
|
+ s.renderEventActionPage(w, r, action, genericPageModeAdd, err.Error())
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ http.Redirect(w, r, webAdminEventActionsPath, http.StatusSeeOther)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *httpdServer) handleWebUpdateEventActionGet(w http.ResponseWriter, r *http.Request) {
|
|
|
|
+ r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
|
|
|
+ name := getURLParam(r, "name")
|
|
|
|
+ action, err := dataprovider.EventActionExists(name)
|
|
|
|
+ if err == nil {
|
|
|
|
+ s.renderEventActionPage(w, r, action, genericPageModeUpdate, "")
|
|
|
|
+ } else if _, ok := err.(*util.RecordNotFoundError); ok {
|
|
|
|
+ s.renderNotFoundPage(w, r, err)
|
|
|
|
+ } else {
|
|
|
|
+ s.renderInternalServerErrorPage(w, r, err)
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *httpdServer) handleWebUpdateEventActionPost(w http.ResponseWriter, r *http.Request) {
|
|
|
|
+ r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
|
|
|
+ claims, err := getTokenClaims(r)
|
|
|
|
+ if err != nil || claims.Username == "" {
|
|
|
|
+ s.renderBadRequestPage(w, r, errors.New("invalid token claims"))
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ name := getURLParam(r, "name")
|
|
|
|
+ action, err := dataprovider.EventActionExists(name)
|
|
|
|
+ if _, ok := err.(*util.RecordNotFoundError); ok {
|
|
|
|
+ s.renderNotFoundPage(w, r, err)
|
|
|
|
+ return
|
|
|
|
+ } else if err != nil {
|
|
|
|
+ s.renderInternalServerErrorPage(w, r, err)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ updatedAction, err := getEventActionFromPostFields(r)
|
|
|
|
+ if err != nil {
|
|
|
|
+ s.renderEventActionPage(w, r, updatedAction, genericPageModeUpdate, err.Error())
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
|
|
|
+ if err := verifyCSRFToken(r.Form.Get(csrfFormToken), ipAddr); err != nil {
|
|
|
|
+ s.renderForbiddenPage(w, r, err.Error())
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ updatedAction.ID = action.ID
|
|
|
|
+ updatedAction.Name = action.Name
|
|
|
|
+ updatedAction.Options.SetEmptySecretsIfNil()
|
|
|
|
+ switch updatedAction.Type {
|
|
|
|
+ case dataprovider.ActionTypeHTTP:
|
|
|
|
+ if updatedAction.Options.HTTPConfig.Password.IsNotPlainAndNotEmpty() {
|
|
|
|
+ updatedAction.Options.HTTPConfig.Password = action.Options.HTTPConfig.Password
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ err = dataprovider.UpdateEventAction(&updatedAction, claims.Username, ipAddr)
|
|
|
|
+ if err != nil {
|
|
|
|
+ s.renderEventActionPage(w, r, updatedAction, genericPageModeUpdate, err.Error())
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ http.Redirect(w, r, webAdminEventActionsPath, http.StatusSeeOther)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *httpdServer) handleWebGetEventRules(w http.ResponseWriter, r *http.Request) {
|
|
|
|
+ r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
|
|
|
+ limit := defaultQueryLimit
|
|
|
|
+ if _, ok := r.URL.Query()["qlimit"]; ok {
|
|
|
|
+ if lim, err := strconv.Atoi(r.URL.Query().Get("qlimit")); err == nil {
|
|
|
|
+ limit = lim
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ rules := make([]dataprovider.EventRule, 0, limit)
|
|
|
|
+ for {
|
|
|
|
+ res, err := dataprovider.GetEventRules(limit, len(rules), dataprovider.OrderASC)
|
|
|
|
+ if err != nil {
|
|
|
|
+ s.renderInternalServerErrorPage(w, r, err)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ rules = append(rules, res...)
|
|
|
|
+ if len(res) < limit {
|
|
|
|
+ break
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ data := eventRulesPage{
|
|
|
|
+ basePage: s.getBasePageData(pageEventRulesTitle, webAdminEventRulesPath, r),
|
|
|
|
+ Rules: rules,
|
|
|
|
+ }
|
|
|
|
+ renderAdminTemplate(w, templateEventRules, data)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *httpdServer) handleWebAddEventRuleGet(w http.ResponseWriter, r *http.Request) {
|
|
|
|
+ r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
|
|
|
+ rule := dataprovider.EventRule{
|
|
|
|
+ Trigger: dataprovider.EventTriggerFsEvent,
|
|
|
|
+ }
|
|
|
|
+ s.renderEventRulePage(w, r, rule, genericPageModeAdd, "")
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *httpdServer) handleWebAddEventRulePost(w http.ResponseWriter, r *http.Request) {
|
|
|
|
+ r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
|
|
|
+ claims, err := getTokenClaims(r)
|
|
|
|
+ if err != nil || claims.Username == "" {
|
|
|
|
+ s.renderBadRequestPage(w, r, errors.New("invalid token claims"))
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ rule, err := getEventRuleFromPostFields(r)
|
|
|
|
+ if err != nil {
|
|
|
|
+ s.renderEventRulePage(w, r, rule, genericPageModeAdd, err.Error())
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
|
|
|
+ err = verifyCSRFToken(r.Form.Get(csrfFormToken), ipAddr)
|
|
|
|
+ if err != nil {
|
|
|
|
+ s.renderForbiddenPage(w, r, err.Error())
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ if err = dataprovider.AddEventRule(&rule, claims.Username, ipAddr); err != nil {
|
|
|
|
+ s.renderEventRulePage(w, r, rule, genericPageModeAdd, err.Error())
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ http.Redirect(w, r, webAdminEventRulesPath, http.StatusSeeOther)
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *httpdServer) handleWebUpdateEventRuleGet(w http.ResponseWriter, r *http.Request) {
|
|
|
|
+ r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
|
|
|
+ name := getURLParam(r, "name")
|
|
|
|
+ rule, err := dataprovider.EventRuleExists(name)
|
|
|
|
+ if err == nil {
|
|
|
|
+ s.renderEventRulePage(w, r, rule, genericPageModeUpdate, "")
|
|
|
|
+ } else if _, ok := err.(*util.RecordNotFoundError); ok {
|
|
|
|
+ s.renderNotFoundPage(w, r, err)
|
|
|
|
+ } else {
|
|
|
|
+ s.renderInternalServerErrorPage(w, r, err)
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *httpdServer) handleWebUpdateEventRulePost(w http.ResponseWriter, r *http.Request) {
|
|
|
|
+ r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
|
|
|
|
+ claims, err := getTokenClaims(r)
|
|
|
|
+ if err != nil || claims.Username == "" {
|
|
|
|
+ s.renderBadRequestPage(w, r, errors.New("invalid token claims"))
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ name := getURLParam(r, "name")
|
|
|
|
+ rule, err := dataprovider.EventRuleExists(name)
|
|
|
|
+ if _, ok := err.(*util.RecordNotFoundError); ok {
|
|
|
|
+ s.renderNotFoundPage(w, r, err)
|
|
|
|
+ return
|
|
|
|
+ } else if err != nil {
|
|
|
|
+ s.renderInternalServerErrorPage(w, r, err)
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ updatedRule, err := getEventRuleFromPostFields(r)
|
|
|
|
+ if err != nil {
|
|
|
|
+ s.renderEventRulePage(w, r, updatedRule, genericPageModeUpdate, err.Error())
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ ipAddr := util.GetIPFromRemoteAddress(r.RemoteAddr)
|
|
|
|
+ if err := verifyCSRFToken(r.Form.Get(csrfFormToken), ipAddr); err != nil {
|
|
|
|
+ s.renderForbiddenPage(w, r, err.Error())
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ updatedRule.ID = rule.ID
|
|
|
|
+ updatedRule.Name = rule.Name
|
|
|
|
+ err = dataprovider.UpdateEventRule(&updatedRule, claims.Username, ipAddr)
|
|
|
|
+ if err != nil {
|
|
|
|
+ s.renderEventRulePage(w, r, updatedRule, genericPageModeUpdate, err.Error())
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ http.Redirect(w, r, webAdminEventRulesPath, http.StatusSeeOther)
|
|
|
|
+}
|