aroz 1 жил өмнө
parent
commit
a53d721cec

+ 78 - 10
mod/fileservers/servers/samba/handlers.go

@@ -3,6 +3,8 @@ package samba
 import (
 	"encoding/json"
 	"net/http"
+	"path/filepath"
+	"strings"
 
 	"imuslab.com/arozos/mod/utils"
 )
@@ -44,8 +46,6 @@ func (s *ShareManager) SmbdStates(w http.ResponseWriter, r *http.Request) {
 	}
 
 	utils.SendErrorResponse(w, "not support set state: "+set+". Only support enable /disable")
-	return
-
 }
 
 // List all the samba shares
@@ -65,20 +65,88 @@ func (s *ShareManager) ListSambaShares(w http.ResponseWriter, r *http.Request) {
 
 // Add a samba share
 func (s *ShareManager) AddSambaShare(w http.ResponseWriter, r *http.Request) {
-	shareName, err := utils.GetPara(r, "name")
+	shareName, err := utils.PostPara(r, "name")
 	if err != nil {
 		utils.SendErrorResponse(w, "share name not given")
 		return
 	}
 
-	//TODO: Move hardcode to paramters
+	shareName = strings.TrimSpace(shareName)
+
+	//Check if this share name already been used
+	shareNameExists, err := s.ShareNameExists(shareName)
+	if err != nil {
+		utils.SendErrorResponse(w, err.Error())
+		return
+	}
+	if shareNameExists {
+		utils.SendErrorResponse(w, "share with identical name already exists")
+		return
+	}
+
+	sharePath, err := utils.PostPara(r, "path")
+	if err != nil {
+		utils.SendErrorResponse(w, "share path not given")
+		return
+	}
+
+	//Parse the path to absolute path
+	absoluteSharePath, err := filepath.Abs(sharePath)
+	if err != nil {
+		utils.SendErrorResponse(w, err.Error())
+		return
+	}
+
+	//Check if path exists
+	if !utils.FileExists(absoluteSharePath) {
+		utils.SendErrorResponse(w, "target path not exists")
+		return
+	}
+
+	//Check if target path is a folder
+	if !utils.IsDir(absoluteSharePath) {
+		utils.SendErrorResponse(w, "target path is not a directory")
+		return
+	}
+
+	validUsersJSON, err := utils.PostPara(r, "users")
+	if err != nil {
+		utils.SendErrorResponse(w, "no valid user givens")
+		return
+	}
+
+	//Parse valid users into string slice
+	validUsers := []string{}
+	err = json.Unmarshal([]byte(validUsersJSON), &validUsers)
+	if err != nil {
+		utils.SendErrorResponse(w, "unable to parse JSON for valid users")
+		return
+	}
+
+	//Check if all the users exists in the host OS
+
+	readOnly, err := utils.PostBool(r, "readonly")
+	if err != nil {
+		readOnly = false
+	}
+
+	browseable, err := utils.PostBool(r, "browseable")
+	if err != nil {
+		browseable = true
+	}
+
+	allowGuest, err := utils.PostBool(r, "guestok")
+	if err != nil {
+		allowGuest = false
+	}
+
 	shareToCreate := ShareConfig{
 		Name:       shareName,
-		Path:       "/home/aroz/test/",
-		ValidUsers: []string{"aroz"},
-		ReadOnly:   false,
-		Browseable: true,
-		GuestOk:    false,
+		Path:       absoluteSharePath,
+		ValidUsers: validUsers,
+		ReadOnly:   readOnly,
+		Browseable: browseable,
+		GuestOk:    allowGuest,
 	}
 
 	//Add the new share to smb.conf
@@ -100,7 +168,7 @@ func (s *ShareManager) AddSambaShare(w http.ResponseWriter, r *http.Request) {
 
 // Remove a samba share by name
 func (s *ShareManager) DelSambaShare(w http.ResponseWriter, r *http.Request) {
-	shareName, err := utils.GetPara(r, "name")
+	shareName, err := utils.PostPara(r, "name")
 	if err != nil {
 		utils.SendErrorResponse(w, "share name not given")
 		return

+ 16 - 0
mod/fileservers/servers/samba/samba.go

@@ -115,6 +115,22 @@ func (s *ShareManager) ReadSambaShares() ([]ShareConfig, error) {
 	return shares, nil
 }
 
+// Check if a share name is already used
+func (s *ShareManager) ShareNameExists(sharename string) (bool, error) {
+	allShares, err := s.ReadSambaShares()
+	if err != nil {
+		return false, err
+	}
+
+	for _, share := range allShares {
+		if strings.EqualFold(share.Name, sharename) {
+			return true, nil
+		}
+	}
+
+	return false, nil
+}
+
 // A basic filter to remove system created smb shares entry in the list
 func (s *ShareManager) FilterSystemCreatedShares(shares []ShareConfig) []ShareConfig {
 	namesToRemove := []string{"global", "homes", "printers", "print$"}

+ 92 - 7
web/SystemAO/disk/samba.html

@@ -5,16 +5,79 @@
     <label>Enable smbd (Samba Sharing Service)</label>
 </div>
 
-<h3>Samba Share Lists</h3>
+<h3><i class="ui green share alternate icon"></i> Samba Share Lists</h3>
 <p>A list of SMB shares currently written into smb.conf</p>
 <div id="sharelist">
 
 </div>
 <div class="ui divider"></div>
-<h3>Add Samba Share</h3>
+<h3><i class="ui green circle add icon"></i> Add Samba Share</h3>
 <p>Create a new SMB share folder from local disk</p>
+<form class="ui form" id="shareForm">
+    <div class="field">
+        <label for="shareName">Share Name</label>
+        <input type="text" id="shareName" placeholder="Share Name">
+    </div>
+    <div class="field">
+        <label for="sharePath">Share Path</label>
+        <input type="text" id="sharePath" placeholder="/home/user/myshare">
+        <small><i class="ui yellow exclamation triangle icon"></i> The folder path must be an absolute full path exists on your local disk. e.g. /home/user/myshare/ </small>
+    </div>
+    <div class="field">
+        <label for="validUsers">Valid Users</label>
+        <select multiple="" class="ui search dropdown" id="validUsers">
+            <option value="user1">User 1</option>
+            <option value="user2">User 2</option>
+            <option value="user3">User 3</option>
+            <!-- Add options for all users in the system -->
+        </select>
+    </div>
+    <div class="field">
+        <div class="ui checkbox">
+            <input type="checkbox" id="readOnly">
+            <label for="readOnly">Read Only<br>
+            <small>Set all files in this share to READ ONLY mode</small></label>
+        </div>
+    </div>
+    <div class="field">
+        <div class="ui checkbox">
+            <input type="checkbox" id="browseable" checked>
+            <label for="browseable">Browseable <br>
+            <small>Make this share discoverable</small></label>
+        </div>
+    </div>
+    <div class="field">
+        <div class="ui checkbox">
+            <input type="checkbox" id="allowGuest">
+            <label for="allowGuest">Allow Guest<br>
+            <small>Enable guest account on this share</small></label>
+        </div>
+    </div>
+    <button type="button" class="ui small basic button" onclick="submitForm()"><i class="ui green circle add icon"></i> Create Share</button>
+</form>
+</div>
+
 <script>
+    $("#validUsers").dropdown();
+    $("#shareForm").find("checkbox").checkbox();
+
+    //Load all the users in the samba database
+    function initSambaUserList(){
+        $.get("../../system/storage/samba/listUsers", function(data){
+            if (data.error == undefined){
+                $("#validUsers").html("");
+                if (data.length == 0){
+                    return;
+                }
+                data.forEach(function(userinfo){
+                    $("#validUsers").append(`<option value="${userinfo.UnixUsername}">${userinfo.UnixUsername}</option>`);
+                })
+            }
+        })
+    }
+    initSambaUserList();
 
+    //List the current shares in smb.conf
     function initShareListTable(){
         $.get("../../system/storage/samba/list", function(data){
             if (data.error){
@@ -26,6 +89,7 @@
      }
      initShareListTable();
 
+     //Load current smbd state
      function initSmbdState(){
         $.get("../../system/storage/samba/status", function(data){
             if (data.error != undefined){
@@ -71,8 +135,8 @@
                 <table class="ui basic celled unstackable table">
                     <thead>
                         <tr>
-                            <th>Name</th>
-                            <th>Path</th>
+                            <th><i class="ui yellow folder icon"></i> Name</th>
+                            <th><i class="ui grey hdd icon"></i> Path</th>
                             <th>Valid Users</th>
                             <th>Read Only</th>
                             <th>Browseable</th>
@@ -87,13 +151,13 @@
             data.forEach(item => {
                 table += `
                     <tr>
-                        <td><i class="ui yellow folder icon"></i> ${item.Name}</td>
-                        <td><i class="ui grey hdd icon"></i> ${item.Path}</td>
+                        <td>${item.Name}</td>
+                        <td>${item.Path}</td>
                         <td>${item.ValidUsers.join(", ")}</td>
                         <td>${item.ReadOnly?'<i class="ui green check icon"></i>':'<i class="ui red times icon"></i>'}</td>
                         <td>${item.Browseable?'<i class="ui green check icon"></i>':'<i class="ui red times icon"></i>'}</td>
                         <td>${item.GuestOk?'<i class="ui green check icon"></i>':'<i class="ui red times icon"></i>'}</td>
-                        <td><button class="ui basic circular mini red icon button"><i class="ui trash icon"></i> Remove</button></td>
+                        <td><button class="ui basic circular mini red icon button" onclick="deleteSMBShare('${item.Name}');"><i class="ui trash icon"></i> Remove</button></td>
                     </tr>
                 `;
             });
@@ -107,4 +171,25 @@
             // Insert the table into the div
             $("#sharelist").html(table);
         }
+
+        //Delete the given smb share name
+        function deleteSMBShare(smbShareName){
+            if (confirm("Confirm remove share " + smbShareName + " ?")){
+                $.ajax({
+                    url: "../../system/storage/samba/remove",
+                    method: "POST",
+                    data:{
+                        "name": smbShareName,
+                    },
+                    success: function(data){
+                        if (data.error != undefined){
+                            msgbox(data.error, false);
+                        }else{
+                            msgbox("SMB share removed");
+                            initShareListTable();
+                        }
+                    }
+                })
+            }
+        }
 </script>