Add global setting form
This commit is contained in:
		
							parent
							
								
									6f8e5cdbca
								
							
						
					
					
						commit
						e99a5ba92b
					
				|  | @ -209,3 +209,53 @@ func WireGuardServerKeyPair() echo.HandlerFunc { | |||
| 		return c.JSON(http.StatusOK, serverKeyPair) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // GlobalSettings handler
 | ||||
| func GlobalSettings() echo.HandlerFunc { | ||||
| 	return func(c echo.Context) error { | ||||
| 		// initialize database directory
 | ||||
| 		dir := "./db" | ||||
| 		db, err := scribble.New(dir, nil) | ||||
| 		if err != nil { | ||||
| 			log.Error("Cannot initialize the database: ", err) | ||||
| 		} | ||||
| 
 | ||||
| 		globalSettings := model.GlobalSetting{} | ||||
| 		if err := db.Read("server", "global_settings", &globalSettings); err != nil { | ||||
| 			log.Error("Cannot fetch global settings from database: ", err) | ||||
| 		} | ||||
| 
 | ||||
| 		return c.Render(http.StatusOK, "global_settings.html", map[string]interface{}{ | ||||
| 			"name":           "Khanh", | ||||
| 			"globalSettings": globalSettings, | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // GlobalSettingSubmit handler to update the global settings
 | ||||
| func GlobalSettingSubmit() echo.HandlerFunc { | ||||
| 	return func(c echo.Context) error { | ||||
| 		globalSettings := new(model.GlobalSetting) | ||||
| 		c.Bind(globalSettings) | ||||
| 
 | ||||
| 		// validate the input dns server list
 | ||||
| 		if util.ValidateIPAddressList(globalSettings.DNSServers) == false { | ||||
| 			log.Warnf("Invalid DNS server list input from user: %v", globalSettings.DNSServers) | ||||
| 			return c.JSON(http.StatusBadRequest, jsonHTTPResponse{false, "Invalid DNS server address"}) | ||||
| 		} | ||||
| 
 | ||||
| 		globalSettings.UpdatedAt = time.Now().UTC() | ||||
| 
 | ||||
| 		// write config to the database
 | ||||
| 		dir := "./db" | ||||
| 		db, err := scribble.New(dir, nil) | ||||
| 		if err != nil { | ||||
| 			log.Error("Cannot initialize the database: ", err) | ||||
| 			return c.JSON(http.StatusInternalServerError, jsonHTTPResponse{false, "Cannot access database"}) | ||||
| 		} | ||||
| 		db.Write("server", "global_settings", globalSettings) | ||||
| 		log.Infof("Updated global settings: %v", globalSettings) | ||||
| 
 | ||||
| 		return c.JSON(http.StatusOK, jsonHTTPResponse{true, "Updated global settings successfully"}) | ||||
| 	} | ||||
| } | ||||
|  |  | |||
							
								
								
									
										2
									
								
								main.go
								
								
								
								
							
							
						
						
									
										2
									
								
								main.go
								
								
								
								
							|  | @ -14,5 +14,7 @@ func main() { | |||
| 	app.GET("/wg-server", handler.WireGuardServer()) | ||||
| 	app.POST("wg-server/interfaces", handler.WireGuardServerInterfaces()) | ||||
| 	app.POST("wg-server/keypair", handler.WireGuardServerKeyPair()) | ||||
| 	app.GET("/global-settings", handler.GlobalSettings()) | ||||
| 	app.POST("/global-settings", handler.GlobalSettingSubmit()) | ||||
| 	app.Logger.Fatal(app.Start("127.0.0.1:5000")) | ||||
| } | ||||
|  |  | |||
|  | @ -0,0 +1,14 @@ | |||
| package model | ||||
| 
 | ||||
| import ( | ||||
| 	"time" | ||||
| ) | ||||
| 
 | ||||
| // GlobalSetting model
 | ||||
| type GlobalSetting struct { | ||||
| 	EndpointAddress     string    `json:"endpoint_address"` | ||||
| 	DNSServers          []string  `json:"dns_servers"` | ||||
| 	MTU                 int       `json:"mtu,string"` | ||||
| 	PersistentKeepalive int       `json:"persistent_keepalive,string"` | ||||
| 	UpdatedAt           time.Time `json:"updated_at"` | ||||
| } | ||||
|  | @ -31,6 +31,7 @@ func New() *echo.Echo { | |||
| 	templates := make(map[string]*template.Template) | ||||
| 	templates["clients.html"] = template.Must(template.ParseFiles("templates/clients.html", "templates/base.html")) | ||||
| 	templates["server.html"] = template.Must(template.ParseFiles("templates/server.html", "templates/base.html")) | ||||
| 	templates["global_settings.html"] = template.Must(template.ParseFiles("templates/global_settings.html", "templates/base.html")) | ||||
| 
 | ||||
| 	e.Logger.SetLevel(log.DEBUG) | ||||
| 	e.Pre(middleware.RemoveTrailingSlash()) | ||||
|  |  | |||
|  | @ -102,7 +102,7 @@ | |||
|                             </a> | ||||
|                         </li> | ||||
|                         <li class="nav-item"> | ||||
|                             <a href="/golbal-settings" class="nav-link"> | ||||
|                             <a href="/global-settings" class="nav-link"> | ||||
|                                 <i class="nav-icon fas fa-cog"></i> | ||||
|                                 <p> | ||||
|                                     Global Settings | ||||
|  |  | |||
|  | @ -0,0 +1,154 @@ | |||
| {{define "title"}} | ||||
| Global Settings | ||||
| {{end}} | ||||
| 
 | ||||
| {{define "username"}} | ||||
| {{index . "name"}} | ||||
| {{end}} | ||||
| 
 | ||||
| {{define "page_title"}} | ||||
| Global Settings | ||||
| {{end}} | ||||
| 
 | ||||
| {{define "page_content"}} | ||||
| <section class="content"> | ||||
|     <div class="container-fluid"> | ||||
|         <!-- <h5 class="mt-4 mb-2">Global Settings</h5> --> | ||||
|         <div class="row"> | ||||
|             <!-- left column --> | ||||
|             <div class="col-md-6"> | ||||
|                 <div class="card card-success"> | ||||
|                     <div class="card-header"> | ||||
|                         <h3 class="card-title">Wireguard Global Settings</h3> | ||||
|                     </div> | ||||
|                     <!-- /.card-header --> | ||||
|                     <!-- form start --> | ||||
|                     <form role="form" id="frm_global_settings" name="frm_global_settings"> | ||||
|                         <div class="card-body"> | ||||
|                             <div class="form-group"> | ||||
|                                 <label for="endpoint_address">Endpoint Address</label> | ||||
|                                 <input type="text" class="form-control" id="endpoint_address" name="endpoint_address" placeholder="Endpoint Address" | ||||
|                                     value="{{ .globalSettings.EndpointAddress }}"> | ||||
|                             </div> | ||||
|                             <div class="form-group"> | ||||
|                                 <label for="dns_servers" class="control-label">DNS Servers</label> | ||||
|                                 <input type="text" data-role="tagsinput" class="form-control" id="dns_servers" value=""> | ||||
|                             </div> | ||||
|                             <div class="form-group"> | ||||
|                                 <label for="mtu">MTU</label> | ||||
|                                 <input type="text" class="form-control" id="mtu" name="mtu" placeholder="MTU" | ||||
|                                     value="{{ .globalSettings.MTU }}"> | ||||
|                             </div> | ||||
|                             <div class="form-group"> | ||||
|                                 <label for="persistent_keepalive">Persistent Keepalive</label> | ||||
|                                 <input type="text" class="form-control" id="persistent_keepalive" | ||||
|                                     name="persistent_keepalive" placeholder="Persistent Keepalive" | ||||
|                                     value="{{ .globalSettings.PersistentKeepalive }}"> | ||||
|                             </div> | ||||
|                         </div> | ||||
|                         <!-- /.card-body --> | ||||
| 
 | ||||
|                         <div class="card-footer"> | ||||
|                             <button type="submit" class="btn btn-success">Save</button> | ||||
|                         </div> | ||||
|                     </form> | ||||
|                 </div> | ||||
|                 <!-- /.card --> | ||||
|             </div> | ||||
|         </div> | ||||
|         <!-- /.row --> | ||||
|     </div> | ||||
| </section> | ||||
| 
 | ||||
| {{end}} | ||||
| 
 | ||||
| {{define "bottom_js"}} | ||||
|     <script> | ||||
|         function submitGlobalSettings() { | ||||
|             var endpoint_address = $("#endpoint_address").val(); | ||||
|             var dns_servers = $("#dns_servers").val().split(","); | ||||
|             var mtu = $("#mtu").val(); | ||||
|             var persistent_keepalive = $("#persistent_keepalive").val(); | ||||
|             var data = {"endpoint_address": endpoint_address, "dns_servers": dns_servers, "mtu": mtu, "persistent_keepalive": persistent_keepalive}; | ||||
| 
 | ||||
|             $.ajax({ | ||||
|                 cache: false, | ||||
|                 method: 'POST', | ||||
|                 url: '/global-settings', | ||||
|                 dataType: 'json', | ||||
|                 contentType: "application/json", | ||||
|                 data: JSON.stringify(data), | ||||
|                 success: function(data) { | ||||
|                     $('#modal_new_client').modal('hide'); | ||||
|                     toastr.success('Update global settings successfully'); | ||||
|                 }, | ||||
|                 error: function(jqXHR, exception) { | ||||
|                     var responseJson = jQuery.parseJSON(jqXHR.responseText); | ||||
|                     toastr.error(responseJson['message']); | ||||
|                 } | ||||
|             }); | ||||
|         } | ||||
|     </script> | ||||
|     <script> | ||||
|         // Wireguard Interface DNS server tag input | ||||
|         $('#dns_servers').tagsInput({ | ||||
|             'width': '100%', | ||||
|             'height': '75%', | ||||
|             'interactive': true, | ||||
|             'defaultText': 'Add More', | ||||
|             'removeWithBackspace': true, | ||||
|             'minChars': 0, | ||||
|             'maxChars': 18, | ||||
|             'placeholderColor': '#666666' | ||||
|         }); | ||||
| 
 | ||||
|         // Load DNS server to the form | ||||
|         {{range .globalSettings.DNSServers}} | ||||
|         $('#dns_servers').addTag('{{.}}'); | ||||
|         {{end}} | ||||
| 
 | ||||
|         // Global setting form validation | ||||
|         $(document).ready(function () { | ||||
|             $.validator.setDefaults({ | ||||
|                 submitHandler: function () { | ||||
|                     submitGlobalSettings(); | ||||
|                 } | ||||
|             }); | ||||
|             $('#frm_global_settings').validate({ | ||||
|                 rules: { | ||||
|                     mtu: { | ||||
|                         required: true, | ||||
|                         digits: true, | ||||
|                         range: [68, 65535] | ||||
|                     }, | ||||
|                     persistent_keepalive: { | ||||
|                         required: true, | ||||
|                         digits: true | ||||
|                     } | ||||
|                 }, | ||||
|                 messages: { | ||||
|                     mtu: { | ||||
|                         required: "Please enter a MTU value", | ||||
|                         digits: "MTU must be an integer", | ||||
|                         range: "MTU must be in range 68..65535" | ||||
|                     }, | ||||
|                     persistent_keepalive: { | ||||
|                         required: "Please enter a Persistent Keepalive value", | ||||
|                         digits: "Persistent keepalive must be an integer" | ||||
|                     } | ||||
|                 }, | ||||
|                 errorElement: 'span', | ||||
|                 errorPlacement: function (error, element) { | ||||
|                     error.addClass('invalid-feedback'); | ||||
|                     element.closest('.form-group').append(error); | ||||
|                 }, | ||||
|                 highlight: function (element, errorClass, validClass) { | ||||
|                     $(element).addClass('is-invalid'); | ||||
|                 }, | ||||
|                 unhighlight: function (element, errorClass, validClass) { | ||||
|                     $(element).removeClass('is-invalid'); | ||||
|                 } | ||||
|             }); | ||||
|         }); | ||||
|     </script> | ||||
| {{end}} | ||||
							
								
								
									
										18
									
								
								util/util.go
								
								
								
								
							
							
						
						
									
										18
									
								
								util/util.go
								
								
								
								
							|  | @ -74,3 +74,21 @@ func ValidateServerAddresses(cidrs []string) bool { | |||
| 	} | ||||
| 	return true | ||||
| } | ||||
| 
 | ||||
| // ValidateIPAddress to validate the IPv4 and IPv6 address
 | ||||
| func ValidateIPAddress(ip string) bool { | ||||
| 	if net.ParseIP(ip) == nil { | ||||
| 		return false | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
| 
 | ||||
| // ValidateIPAddressList to validate a list of IPv4 and IPv6 addresses
 | ||||
| func ValidateIPAddressList(ips []string) bool { | ||||
| 	for _, ip := range ips { | ||||
| 		if ValidateIPAddress(ip) == false { | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue