update code

This commit is contained in:
KaySar12 2024-07-04 12:19:44 +07:00
parent dd3a9ebea4
commit 219fa12590
9 changed files with 152 additions and 103 deletions

View File

@ -7,3 +7,5 @@ LogSaveName = user-service
LogFileExt = log LogFileExt = log
DBPath = /var/lib/casaos/db DBPath = /var/lib/casaos/db
UserDataPath = /var/lib/casaos UserDataPath = /var/lib/casaos
OMVServer = http://10.0.0.4:1081/rpc.php
SecretKey = N1PCdw3M2B1TfJhoaY2mL736p2vCUc47

2
dist/metadata.json vendored
View File

@ -1 +1 @@
{"project_name":"casaos-user-service","tag":"v1.0.0","previous_tag":"","version":"1.0.1","commit":"f0d6780c126d2fd12d8c20ca59acd6759f29ce7a","date":"2024-07-03T17:38:16.266556363+07:00","runtime":{"goos":"linux","goarch":"amd64"}} {"project_name":"casaos-user-service","tag":"v1.0.0","previous_tag":"","version":"1.0.1","commit":"dd3a9ebea4fd121d6a2383881265ed85147dbeca","date":"2024-07-04T10:29:51.218513943+07:00","runtime":{"goos":"linux","goarch":"amd64"}}

View File

@ -10,6 +10,8 @@ type APPModel struct {
LogFileExt string LogFileExt string
UserDataPath string UserDataPath string
DBPath string DBPath string
OMVServer string
SecretKey string
} }
type Result struct { type Result struct {

View File

@ -23,6 +23,8 @@ var (
LogPath: constants.DefaultLogPath, LogPath: constants.DefaultLogPath,
LogSaveName: "user", LogSaveName: "user",
LogFileExt: "log", LogFileExt: "log",
OMVServer: constants.DefaultOMVServer,
SecretKey: constants.DefaultSecretKey,
} }
Cfg *ini.File Cfg *ini.File

View File

@ -10,8 +10,20 @@
package encryption package encryption
import ( import (
"crypto/aes"
"crypto/cipher"
"crypto/md5" "crypto/md5"
"crypto/rand"
"encoding/hex" "encoding/hex"
"github.com/IceWhaleTech/CasaOS-UserService/pkg/config"
)
var (
// We're using a 32 byte long secret key.
// This is probably something you generate first
// then put into and environment variable.
secretKey string = config.AppInfo.SecretKey
) )
func GetMD5ByStr(str string) string { func GetMD5ByStr(str string) string {
@ -19,3 +31,54 @@ func GetMD5ByStr(str string) string {
h.Write([]byte(str)) h.Write([]byte(str))
return hex.EncodeToString(h.Sum(nil)) return hex.EncodeToString(h.Sum(nil))
} }
func Encrypt(plaintext string) string {
aes, err := aes.NewCipher([]byte(secretKey))
if err != nil {
panic(err)
}
gcm, err := cipher.NewGCM(aes)
if err != nil {
panic(err)
}
// We need a 12-byte nonce for GCM (modifiable if you use cipher.NewGCMWithNonceSize())
// A nonce should always be randomly generated for every encryption.
nonce := make([]byte, gcm.NonceSize())
_, err = rand.Read(nonce)
if err != nil {
panic(err)
}
// ciphertext here is actually nonce+ciphertext
// So that when we decrypt, just knowing the nonce size
// is enough to separate it from the ciphertext.
ciphertext := gcm.Seal(nonce, nonce, []byte(plaintext), nil)
return string(ciphertext)
}
func Decrypt(ciphertext string) string {
aes, err := aes.NewCipher([]byte(secretKey))
if err != nil {
panic(err)
}
gcm, err := cipher.NewGCM(aes)
if err != nil {
panic(err)
}
// Since we know the ciphertext is actually nonce+ciphertext
// And len(nonce) == NonceSize(). We can separate the two.
nonceSize := gcm.NonceSize()
nonce, ciphertext := ciphertext[:nonceSize], ciphertext[nonceSize:]
plaintext, err := gcm.Open(nil, []byte(nonce), []byte(ciphertext), nil)
if err != nil {
panic(err)
}
return string(plaintext)
}

View File

@ -1,17 +1,14 @@
package v1 package v1
import ( import (
"bytes"
"context" "context"
"crypto/ecdsa" "crypto/ecdsa"
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
json2 "encoding/json" json2 "encoding/json"
"fmt"
"image" "image"
"image/png" "image/png"
"io" "io"
"io/ioutil"
"log" "log"
"net/http" "net/http"
url2 "net/url" url2 "net/url"
@ -148,9 +145,7 @@ func PostUserLogin(c *gin.Context) {
json := make(map[string]string) json := make(map[string]string)
c.ShouldBind(&json) c.ShouldBind(&json)
username := json["username"] username := json["username"]
password := json["password"] password := json["password"]
// check params is empty // check params is empty
if len(username) == 0 || len(password) == 0 { if len(username) == 0 || len(password) == 0 {
@ -206,6 +201,14 @@ func PostUserLogin(c *gin.Context) {
Data: data, Data: data,
}) })
} }
// @Summary login user to openmediavault
// @Produce application/json
// @Tags user
// @Param username password
// @Security SessionID
// @Success 200 {string} string "ok"
// @Router /users/omvLogin [post]
func PostOMVLogin(c *gin.Context) { func PostOMVLogin(c *gin.Context) {
if !limiter.Allow() { if !limiter.Allow() {
c.JSON(common_err.TOO_MANY_REQUEST, c.JSON(common_err.TOO_MANY_REQUEST,
@ -222,14 +225,13 @@ func PostOMVLogin(c *gin.Context) {
username := json["username"] username := json["username"]
password := json["password"] password := json["password"]
res := LoginSession(username, password) res := service.MyService.OMV().LoginSession(username, password)
var resData OMVLogin var resData OMVLogin
err := json2.Unmarshal([]byte(res), &resData) err := json2.Unmarshal([]byte(res), &resData)
if err != nil { if err != nil {
// Handle the error, for example, log it or return it
log.Printf("Error getting user: %v", err) log.Printf("Error getting user: %v", err)
return // or handle it in a way that fits your application's error handling strategy return
} }
if !resData.Response.Authenticated { if !resData.Response.Authenticated {
@ -238,8 +240,7 @@ func PostOMVLogin(c *gin.Context) {
return return
} }
getUser, err := GetOMVUser(username, resData.Response.SessionID) getUser, err := service.MyService.OMV().GetUser(username, resData.Response.SessionID)
if err != nil { if err != nil {
// Handle the error, for example, log it or return it // Handle the error, for example, log it or return it
log.Printf("Error getting user: %v", err) log.Printf("Error getting user: %v", err)
@ -262,14 +263,11 @@ func PostOMVLogin(c *gin.Context) {
Message: common_err.GetMsg(common_err.USER_NOT_EXIST_OR_PWD_INVALID)}) Message: common_err.GetMsg(common_err.USER_NOT_EXIST_OR_PWD_INVALID)})
return return
} }
c.SetCookie( // cookie_value, err := c.Cookie("sessionID")
"sessionID", // decrypt := encryption.Decrypt(cookie_value)
resData.Response.SessionID, // fmt.Printf(decrypt)
3600, sessionId := encryption.Encrypt(resData.Response.SessionID)
"/", c.SetCookie("sessionID", sessionId, 3600, "/", "", false, true)
"",
false,
true)
c.JSON(common_err.SUCCESS, c.JSON(common_err.SUCCESS,
model.Result{ model.Result{
Success: common_err.SUCCESS, Success: common_err.SUCCESS,
@ -287,67 +285,6 @@ func isEmpty(obj interface{}) bool {
return false return false
} }
func GetOMVUser(username string, sessionID string) (string, error) {
// Prepare the RPC request
postBody, _ := json.Marshal(map[string]interface{}{
"service": "UserMgmt",
"method": "getUser",
"params": map[string]string{
"name": username,
},
})
responseBody := bytes.NewBuffer(postBody)
// Create HTTP request and set session ID header
req, err := http.NewRequest("POST", "http://10.0.0.4:1081/rpc.php", responseBody)
if err != nil {
return "", fmt.Errorf("error creating request: %v", err)
}
req.Header.Set("X-OPENMEDIAVAULT-SESSIONID", sessionID) // Set session ID header
// Send the request
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return "", fmt.Errorf("error making request: %v", err)
}
defer resp.Body.Close() // Ensure the response body is closed
// Check for HTTP errors
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("HTTP error: %s", resp.Status)
}
// Read the response body
responseData, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("error reading response body: %v", err)
}
return string(responseData), nil
}
func LoginSession(username string, password string) string {
postBody, _ := json.Marshal(map[string]interface{}{
"service": "session",
"method": "login",
"params": map[string]string{
"username": username,
"password": password,
},
})
responseBody := bytes.NewBuffer(postBody)
response, err := http.Post("http://10.0.0.4:1081/rpc.php", "application/json", responseBody)
if err != nil {
fmt.Print(err.Error())
os.Exit(1)
}
responseData, err := ioutil.ReadAll(response.Body)
if err != nil {
log.Fatal(err)
}
return string(responseData)
}
// @Summary edit user head // @Summary edit user head
// @Produce application/json // @Produce application/json
// @Accept multipart/form-data // @Accept multipart/form-data

View File

@ -4,30 +4,26 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io"
"log" "log"
"net/http" "net/http"
"os" "os"
"github.com/IceWhaleTech/CasaOS-UserService/pkg/config"
"github.com/IceWhaleTech/CasaOS-UserService/service/model" "github.com/IceWhaleTech/CasaOS-UserService/service/model"
) )
type OMVService interface { type OMVService interface {
LoginSession(userName string, password string) string LoginSession(userName string, password string) string
Logout() Logout(sessionID string) (string, error)
GetUser(username string) string GetUser(username string, sessionID string) (string, error)
SetUser(m model.UserDBModel) model.UserDBModel SetUser(m model.UserDBModel) model.UserDBModel
ApplyChange() ApplyChange()
} }
type omvService struct { type omvService struct {
} }
// LoginSession implements OMVService. func (o *omvService) LoginSession(username string, password string) string {
func (o *omvService) LoginSession(userName string, password string) string {
panic("unimplemented")
}
func LoginSession(username string, password string) string {
postBody, _ := json.Marshal(map[string]interface{}{ postBody, _ := json.Marshal(map[string]interface{}{
"service": "session", "service": "session",
"method": "login", "method": "login",
@ -37,22 +33,51 @@ func LoginSession(username string, password string) string {
}, },
}) })
responseBody := bytes.NewBuffer(postBody) responseBody := bytes.NewBuffer(postBody)
response, err := http.Post("http://10.0.0.4:1081/rpc.php", "application/json", responseBody) response, err := http.Post(config.AppInfo.OMVServer, "application/json", responseBody)
if err != nil { if err != nil {
fmt.Print(err.Error()) fmt.Print(err.Error())
os.Exit(1) os.Exit(1)
} }
responseData, err := ioutil.ReadAll(response.Body) responseData, err := io.ReadAll(response.Body)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
return string(responseData) return string(responseData)
} }
func (o *omvService) Logout() { func (o *omvService) Logout(sessionID string) (string, error) {
// Implement logout logic here postBody, _ := json.Marshal(map[string]interface{}{
"service": "UserMgmt",
"method": "logout",
"params": nil,
})
responseBody := bytes.NewBuffer(postBody)
req, err := http.NewRequest("POST", config.AppInfo.OMVServer, responseBody)
if err != nil {
return "", fmt.Errorf("error creating request: %v", err)
}
req.Header.Set("X-OPENMEDIAVAULT-SESSIONID", sessionID) // Set session ID header
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return "", fmt.Errorf("error making request: %v", err)
}
defer resp.Body.Close() // Ensure the response body is closed
// Check for HTTP errors
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("HTTP error: %s", resp.Status)
}
// Read the response body
responseData, err := io.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("error reading response body: %v", err)
}
return string(responseData), nil
} }
func (o *omvService) GetUser(username string) string { func (o *omvService) GetUser(username string, sessionID string) (string, error) {
// Prepare the RPC request
postBody, _ := json.Marshal(map[string]interface{}{ postBody, _ := json.Marshal(map[string]interface{}{
"service": "UserMgmt", "service": "UserMgmt",
"method": "getUser", "method": "getUser",
@ -61,16 +86,34 @@ func (o *omvService) GetUser(username string) string {
}, },
}) })
responseBody := bytes.NewBuffer(postBody) responseBody := bytes.NewBuffer(postBody)
response, err := http.Post("http://10.0.0.4:1081/rpc.php", "application/json", responseBody)
// Create HTTP request and set session ID header
req, err := http.NewRequest("POST", config.AppInfo.OMVServer, responseBody)
if err != nil { if err != nil {
fmt.Print(err.Error()) return "", fmt.Errorf("error creating request: %v", err)
os.Exit(1)
} }
responseData, err := ioutil.ReadAll(response.Body) req.Header.Set("X-OPENMEDIAVAULT-SESSIONID", sessionID) // Set session ID header
// Send the request
client := &http.Client{}
resp, err := client.Do(req)
if err != nil { if err != nil {
log.Fatal(err) return "", fmt.Errorf("error making request: %v", err)
} }
return string(responseData) defer resp.Body.Close() // Ensure the response body is closed
// Check for HTTP errors
if resp.StatusCode != http.StatusOK {
return "", fmt.Errorf("HTTP error: %s", resp.Status)
}
// Read the response body
responseData, err := io.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("error reading response body: %v", err)
}
return string(responseData), nil
} }
func (o *omvService) SetUser(m model.UserDBModel) model.UserDBModel { func (o *omvService) SetUser(m model.UserDBModel) model.UserDBModel {

View File

@ -39,9 +39,6 @@ type store struct {
omv OMVService omv OMVService
} }
func (c *store) OMV() OMVService {
return c.omv
}
func (c *store) Event() EventService { func (c *store) Event() EventService {
return c.event return c.event
} }
@ -52,6 +49,9 @@ func (c *store) Gateway() external.ManagementService {
func (c *store) User() UserService { func (c *store) User() UserService {
return c.user return c.user
} }
func (c *store) OMV() OMVService {
return c.omv
}
func (c *store) MessageBus() *message_bus.ClientWithResponses { func (c *store) MessageBus() *message_bus.ClientWithResponses {
client, _ := message_bus.NewClientWithResponses("", func(c *message_bus.Client) error { client, _ := message_bus.NewClientWithResponses("", func(c *message_bus.Client) error {
// error will never be returned, as we always want to return a client, even with wrong address, // error will never be returned, as we always want to return a client, even with wrong address,