litpooh 3 vuotta sitten
vanhempi
commit
4605346b19
10 muutettua tiedostoa jossa 220 lisäystä ja 55 poistoa
  1. BIN
      .DS_Store
  2. 0 0
      README.md
  3. 3 3
      files/index.html
  4. 15 6
      files/login.html
  5. 26 5
      files/logout.html
  6. 36 0
      files/signup.html
  7. 5 1
      go.mod
  8. 4 0
      go.sum
  9. 131 40
      main.go
  10. BIN
      my.db

BIN
.DS_Store


+ 0 - 0
README.md


+ 3 - 3
files/index.html

@@ -16,10 +16,10 @@
         url: "/checklogin",
         success: function(value){
             var response = JSON.parse(value)
-            if (response.LoggedIn == true){
-                alert("Yes: User has logged in");
+            if (response.NumberLoggedIn > 0){
+                alert("Yes: "+response.NumberLoggedIn+" users has logged in!");
             }else{
-                alert("No: User has not logged in yet");
+                alert("No: User has not logged in yet: "+ response.NumberLoggedIn);
             }
         }
       });

+ 15 - 6
files/login.html

@@ -5,25 +5,34 @@
         </script>
     </head>
     <body>
-      <h1>Admin Login</h1>
-      <p>Please enter your password here</p>
+      <h1>User Login</h1>
+      <p>Username:</p>
+      <input id="username" type="text">
+      <p>Password:</p>
       <input id="password" type="password">
+      <br>
+      <br>
 
     <button onclick="handleLogin()">Login</button>
     
     <script>
     function handleLogin() {
+      var username = $("#username").val();
       var password = $("#password").val();
       $.ajax({
         url: "/login",
-        data: {password: password},
+        data: {username: username, password: password},
         success: function(value){
           var response = JSON.parse(value)
-            if (response.Matched == true){
+            if (response.Success == true){
                  alert("Sucess! You have logged in!");
-                 window.location='/logout.html' 
+                 window.location.href = '/logout.html'+'#'+username;
             }else{
-                alert("Incorrect Password!");
+              if (response.Repeat == true){
+                alert("Alert: " + username + " has already loggged in, please logged in with a different account!")
+              } else{
+                alert("Incorrect Username/Password!");
+              }
             }
         }
       });

+ 26 - 5
files/logout.html

@@ -1,9 +1,30 @@
-<!DOCTYPE html>
-<html lang="en">
+<html>
 	<head>
-		<title></title>
-	</head>
+        <title>Logout</title>
+        <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js">
+        </script>
+    </head>
 	<body>
-		<h1><a href="/logout">LOG OUT</a></h1>
+		<button onclick="handleLogout()">Click to Logout!!!!!!!!</button>
+
+		<script>
+			function handleLogout() {
+				var username = window.location.hash.substring(1);
+				alert(username+" is logging out......")
+				$.ajax({
+        			url: "/logout",
+        			data: {username: username},
+					success: function(value){
+						var response = JSON.parse(value)
+							if (response.LoggedOut == true){
+								alert(username+" logged out successfully");
+								window.location.href = '/login.html';
+							}else{
+								alert("Error: logged out failed!");
+							}
+						}
+				});
+			}
+			</script>
 	</body>
 </html>`

+ 36 - 0
files/signup.html

@@ -0,0 +1,36 @@
+<html>
+    <head>
+        <title>Login</title>
+        <script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js">
+        </script>
+    </head>
+    <body>
+      <h1>Create an account!</h1>
+      <p>Username:</p>
+      <input id="username" type="text">
+      <p>Password:</p>
+      <input id="password" type="password">
+      <br>
+      <br>
+
+    <button onclick="handleCreate()">Create</button>
+    
+    <script>
+    function handleCreate() {
+      var username = $("#username").val();
+      var password = $("#password").val();
+      $.ajax({
+        url: "/signup",
+        data: {username: username, password: password},
+        success: function(value){
+            if (value == "success"){
+                 alert("Sucess! Your account is created!");
+            }else{
+                alert("ERROR: The username has already been used!");
+            }
+        }
+      });
+    }
+    </script>
+    </body>
+</html>

+ 5 - 1
go.mod

@@ -2,4 +2,8 @@ module login_system_session
 
 go 1.16
 
-require github.com/gorilla/sessions v1.2.1
+require (
+	github.com/boltdb/bolt v1.3.1
+	github.com/gorilla/sessions v1.2.1
+	golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect
+)

+ 4 - 0
go.sum

@@ -1,4 +1,8 @@
+github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=
+github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
 github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
 github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
 github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI=
 github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
+golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
+golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

+ 131 - 40
main.go

@@ -3,56 +3,104 @@ package main
 import (
 	"encoding/json"
 	"flag"
+	"fmt"
 	"log"
 	"net/http"
+	"strconv"
 
+	"github.com/boltdb/bolt"
 	"github.com/gorilla/sessions"
 )
 
+// Functions implemented: signup, login with username and password, logout, the user cannot login again if he/she is already logged in (except admin)
+//                        cannot signup for username already used, check how many users logged in (INDEX.html)
+// User for testing: username -> hello, password -> world
+// Admin user (hard-coded): admin
+
 var store = sessions.NewCookieStore([]byte("secret-key"))
+var db *bolt.DB
+var Online_users int = 0
 
 type Status struct {
-	LoggedIn bool
+	NumberLoggedIn int
+}
+
+type LogoutCheck struct {
+	LoggedOut bool
+}
+
+type SignupNewName struct {
+	Success bool
 }
 
-type Password struct {
-	Matched bool
+type LoginCheck struct {
+	Success bool
+	Repeat  bool
 }
 
 func loginHandler(rw http.ResponseWriter, req *http.Request) {
 	if req.Method == "GET" {
+		username := req.FormValue("username")
 		password := req.FormValue("password")
+		log.Println("The typed username is:" + username)
 		log.Println("The typed password is:" + password)
-		var typed Password
 
-		if password == "admin" {
-			log.Println("Password is correct")
+		var typed LoginCheck
+		db.Update(func(tx *bolt.Tx) error {
+			users := tx.Bucket([]byte("Users"))
+			password_database_byte := users.Get([]byte(username))
+			password_database := string(password_database_byte)
+			if password_database_byte == nil {
+				log.Println("Error: The username is not valid!")
+				typed.Success = false
+				typed.Repeat = false
+			} else {
+				if password == password_database {
+					log.Println("Password is correct")
 
-			session, err := store.Get(req, "session-name")
-			if err != nil {
-				http.Error(rw, err.Error(), http.StatusInternalServerError)
-				return
-			}
-			session.Values["auth"] = true
-			err = session.Save(req, rw)
-			if err != nil {
-				http.Error(rw, err.Error(), http.StatusInternalServerError)
-				return
+					session, err := store.Get(req, username)
+					if err != nil {
+						http.Error(rw, err.Error(), http.StatusInternalServerError)
+						return nil
+					}
+
+					if session.Values["auth"] == true && username != "admin" {
+						typed.Success = false
+						typed.Repeat = true
+						log.Println("Alert: " + username + " has already loggged in, please logged in with a different account!")
+					} else {
+						session.Values["auth"] = true
+						err = session.Save(req, rw)
+						if err != nil {
+							http.Error(rw, err.Error(), http.StatusInternalServerError)
+							return nil
+						}
+
+						Online_users = Online_users + 1
+						typed.Success = true
+						typed.Repeat = false
+						log.Println("Logged in")
+					}
+
+				} else {
+					typed.Success = false
+					typed.Repeat = false
+					log.Println("WRONG password!!")
+				}
 			}
+			send_message, _ := json.Marshal(typed)
+			rw.Write(send_message)
+			return nil
+		})
 
-			typed.Matched = true
-			log.Println("Logged in")
-		} else {
-			typed.Matched = false
-			log.Println("WRONG password!!")
-		}
-		send_message, _ := json.Marshal(typed)
-		rw.Write(send_message)
 	}
 }
 
 func logoutHandler(rw http.ResponseWriter, req *http.Request) {
-	session, err := store.Get(req, "session-name")
+	log.Println("Logout button is clicked!")
+	username := req.FormValue("username")
+	log.Println(username + " wants to log out")
+	session, err := store.Get(req, username)
 	if err != nil {
 		http.Error(rw, err.Error(), http.StatusInternalServerError)
 		return
@@ -64,29 +112,49 @@ func logoutHandler(rw http.ResponseWriter, req *http.Request) {
 		return
 	}
 
-	http.Redirect(rw, req, "/login.html", http.StatusSeeOther)
+	var result LogoutCheck
+	result.LoggedOut = true
+	send_message, _ := json.Marshal(result)
+	rw.Write(send_message)
+	log.Println("Pass log-out message to html")
+
+	Online_users = Online_users - 1
 	log.Println("Logged out successfully")
 }
 
 func checkloginHandler(rw http.ResponseWriter, req *http.Request) {
 	log.Println("Check button is clicked")
-	session, err := store.Get(req, "session-name")
-	if err != nil {
-		http.Error(rw, err.Error(), http.StatusInternalServerError)
-		return
-	}
-	var result Status
-	if session.Values["auth"] == true {
-		log.Println("Checked that auth = true")
-		result.LoggedIn = true
-	} else {
-		log.Println("Checked that auth = false")
-		result.LoggedIn = false
-	}
-	send_message, _ := json.Marshal(result)
+	log.Println("Logged in users: " + strconv.Itoa(Online_users))
+
+	var status Status
+	status.NumberLoggedIn = Online_users
+	send_message, _ := json.Marshal(status)
 	rw.Write(send_message)
 }
 
+func signupHandler(rw http.ResponseWriter, req *http.Request) {
+	username := req.FormValue("username")
+	password := req.FormValue("password")
+	log.Println("Create an account that username is:" + username)
+	log.Println("Create an account that password is:" + password)
+	db.Update(func(tx *bolt.Tx) error {
+		users := tx.Bucket([]byte("Users"))
+		exist_user := users.Get([]byte(username))
+		if exist_user != nil {
+			log.Println("Error: The username has already been used!")
+			rw.Write([]byte("fail"))
+		} else {
+			err := users.Put([]byte(username), []byte(password))
+			if err != nil {
+				return fmt.Errorf("create user: %s", err)
+			}
+			rw.Write([]byte("success"))
+		}
+		return nil
+	})
+
+}
+
 func main() {
 	portPointer := flag.String("port", "8000", "An integer")
 	flag.Parse()
@@ -94,9 +162,32 @@ func main() {
 	httpFileServer := http.FileServer(http.Dir("./files"))
 	http.Handle("/", httpFileServer)
 
+	var err1 error
+	db, err1 = bolt.Open("my.db", 0600, nil)
+	if err1 != nil {
+		log.Fatal(err1)
+	} else {
+		log.Println("database opened")
+	}
+	defer db.Close()
+
+	db.Update(func(tx *bolt.Tx) error {
+		users, err2 := tx.CreateBucketIfNotExists([]byte("Users"))
+		if err2 != nil {
+			return fmt.Errorf("create bucket: %s", err2)
+		}
+		err3 := users.Put([]byte("admin"), []byte("admin"))
+
+		if err3 != nil {
+			return fmt.Errorf("create admin: %s", err3)
+		}
+		return nil
+	})
+
 	http.HandleFunc("/login", loginHandler)
 	http.HandleFunc("/logout", logoutHandler)
 	http.HandleFunc("/checklogin", checkloginHandler)
+	http.HandleFunc("/signup", signupHandler)
 
 	log.Printf("Listening http://localhost:%s\n", *portPointer)
 	if error := http.ListenAndServe(":"+*portPointer, nil); error != nil {

BIN
my.db