Skip to content

Commit

Permalink
Auto generate users.json on start and fix nits
Browse files Browse the repository at this point in the history
  • Loading branch information
retrixe committed Jul 20, 2024
1 parent 37a2a66 commit 927132f
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 18 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ Used to configure the apps Octyne should start, Redis-based authentication for a

### users.json

Contains users who can log into Octyne. Use a secure method to hash your passwords as Octyne does not handle account management at the moment.
Contains users who can log into Octyne. This file is automatically generated on first start with an `admin` user and a generated secure password which is logged to terminal. You can perform account management via Ecthelion, octynectl or other such tools.

```json
{
Expand Down
8 changes: 3 additions & 5 deletions auth/authenticator.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ package auth

import (
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"fmt"
"net/http"
"sync"

Expand Down Expand Up @@ -92,10 +90,10 @@ func isValidToken(token string) bool {

func checkValidLoginAndGenerateToken(auth Authenticator, username string, password string) string {
// Hash the password.
sha256sum := fmt.Sprintf("%x", sha256.Sum256([]byte(password)))
hash := HashPassword(password)
// Check whether this user exists.
hashedPassword, exists := auth.GetUsers().Load(username)
if !exists || hashedPassword != sha256sum {
actualHash, exists := auth.GetUsers().Load(username)
if !exists || actualHash != hash {
return ""
}
// Generate a token and return it.
Expand Down
26 changes: 25 additions & 1 deletion auth/users.go
Original file line number Diff line number Diff line change
@@ -1,15 +1,39 @@
package auth

import (
"bytes"
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"fmt"
"log"
"os"
"time"

"github.com/puzpuzpuz/xsync/v3"
)

func HashPassword(password string) string {
return fmt.Sprintf("%x", sha256.Sum256([]byte(password)))
}

func CreateUserStore(usersJsonPath string) *xsync.MapOf[string, string] {
// Create default users.json file
_, err := os.Stat(usersJsonPath)
if os.IsNotExist(err) {
passwordBytes := make([]byte, 12)
rand.Read(passwordBytes) // Tolerate errors here, an error here is incredibly unlikely: skipcq GSC-G104
password := base64.RawStdEncoding.EncodeToString(passwordBytes)
hash := HashPassword(password)
err = os.WriteFile(usersJsonPath, []byte("{\n \"admin\": \""+hash+"\"\n}"), 0644)
if err != nil {
log.Println("An error occurred while creating " + usersJsonPath + "! " + err.Error())
}
log.Println("The file " + usersJsonPath +
" has been generated with the default user 'admin' and password '" + password + "'.")
}

var users = xsync.NewMapOf[string, string]()
initialFile, updates, err := readAndWatchFile(usersJsonPath)
if err != nil {
Expand Down Expand Up @@ -67,7 +91,7 @@ func readAndWatchFile(filePath string) ([]byte, chan []byte, error) {
log.Println("An error occurred while reading " + filePath + "! " + err.Error())
continue
}
if string(newFile) != string(file) {
if !bytes.Equal(newFile, file) {
file = newFile
channel <- newFile
}
Expand Down
4 changes: 2 additions & 2 deletions connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -206,11 +206,11 @@ func (connector *Connector) AddProcess(proc *Process) {
})()
}

func httpError(w http.ResponseWriter, error string, code int) {
func httpError(w http.ResponseWriter, errMsg string, code int) {
w.Header().Set("content-type", "application/json")
errorJson, err := json.Marshal(struct {
Error string `json:"error"`
}{Error: error})
}{Error: errMsg})
if err == nil {
http.Error(w, string(errorJson), code)
} else {
Expand Down
14 changes: 6 additions & 8 deletions endpoints_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ package main
import (
"bytes"
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"fmt"
"log"
"net/http"
"os"
Expand Down Expand Up @@ -224,9 +222,9 @@ func accountsEndpointPost(connector *Connector, w http.ResponseWriter, r *http.R
httpError(w, "User already exists!", http.StatusConflict)
return false
}
sha256sum := fmt.Sprintf("%x", sha256.Sum256([]byte(body.Password)))
hash := auth.HashPassword(body.Password)
connector.Info("accounts.create", "ip", GetIP(r), "user", user, "newUser", body.Username)
users[body.Username] = sha256sum
users[body.Username] = hash
return true
}

Expand Down Expand Up @@ -258,19 +256,19 @@ func accountsEndpointPatch(connector *Connector, w http.ResponseWriter, r *http.
httpError(w, "User already exists!", http.StatusConflict)
return false
}
sha256sum := users[username]
hash := users[username]
if body.Password != "" {
sha256sum = fmt.Sprintf("%x", sha256.Sum256([]byte(body.Password)))
hash = auth.HashPassword(body.Password)
}
if toUpdateUsername {
connector.Info("accounts.update", "ip", GetIP(r), "user", user,
"updatedUser", body.Username, "oldUsername", username, "changedPassword", body.Password != "")
delete(users, username)
users[body.Username] = sha256sum
users[body.Username] = hash
} else {
connector.Info("accounts.update", "ip", GetIP(r), "user", user,
"updatedUser", username, "changedPassword", true)
users[username] = sha256sum
users[username] = hash
}
return true
}
Expand Down
2 changes: 1 addition & 1 deletion endpoints_files.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ func fileEndpointPatch(connector *Connector, w http.ResponseWriter, r *http.Requ
} else if err == nil {
httpError(w, "This file already exists!", http.StatusMethodNotAllowed)
return
} else if err != nil && !os.IsNotExist(err) {
} else if !os.IsNotExist(err) {
log.Println("An error occurred in mv/cp API when checking for "+newpath, "("+process.Name+")", err)
httpError(w, "Internal Server Error!", http.StatusInternalServerError)
return
Expand Down

0 comments on commit 927132f

Please sign in to comment.