-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
347 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
{ | ||
"name": "Account Manager", | ||
"description": "Service that manage Elabox account and account related authentications.", | ||
"packageId": "ela.account", | ||
"build": 1, | ||
"version": "0.1.0", | ||
"program": "ela.account", | ||
"programArgs": null, | ||
"activityGroup": { | ||
"customLink": "", | ||
"customPort": 0, | ||
"activities": null | ||
}, | ||
"permissions": [], | ||
"exportService": true, | ||
"location": "system", | ||
"nodejs": false, | ||
"packagerVersion": "0.1.0" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"cwd": "", | ||
"config": "info.json", | ||
"binDir": "", | ||
"bin": "./bin/ela.account", | ||
"packages": [], | ||
"customInstaller": "" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package main | ||
|
||
type Account struct { | ||
Address string `json:"address"` | ||
} | ||
|
||
func RetrievePrimaryAccountDetails() map[string]interface{} { | ||
result := make(map[string]interface{}) | ||
wallet, _ := LoadWalletAddr() | ||
result["wallet"] = wallet | ||
return result | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package main | ||
|
||
import ( | ||
"crypto/sha256" | ||
"errors" | ||
"os" | ||
"os/exec" | ||
"strings" | ||
|
||
"github.com/cansulting/elabox-system-tools/foundation/perm" | ||
"github.com/cansulting/elabox-system-tools/foundation/system" | ||
) | ||
|
||
const SHADOW_FILE = "/etc/shadow" | ||
|
||
// check authorization for specific DID, return true if DID is authorized | ||
func AuthenticateDid(did string) bool { | ||
deviceSerial := system.GetDeviceInfo().Serial | ||
hash := sha256.Sum256([]byte(did + deviceSerial)) | ||
// step: load the currently saved did hash | ||
savedHash, err := os.ReadFile(DID_HASH_PATH) | ||
if err != nil { | ||
return false | ||
} | ||
if string(hash[:]) != string(savedHash) { | ||
return false | ||
} | ||
return true | ||
} | ||
|
||
func IsDidSetup() bool { | ||
if _, err := os.Stat(DID_HASH_PATH); err != nil { | ||
return false | ||
} | ||
return true | ||
} | ||
|
||
// use to authenticate specific password | ||
func AuthenticateSystemAccount(username string, password string) (error, bool) { | ||
contents, err := os.ReadFile(SHADOW_FILE) | ||
if err != nil { | ||
return err, false | ||
} | ||
hashContent := Grep(username, string(contents)) | ||
// unable to find specific user account | ||
if hashContent == "" { | ||
return nil, false | ||
} | ||
creds := strings.Split(hashContent, "$") | ||
salt := creds[2] | ||
savedHash := strings.Split(hashContent, ":")[1] | ||
encryptType := creds[1] | ||
// generate hash | ||
cmd := exec.Command( | ||
"/usr/bin/openssl", | ||
"passwd", "-"+encryptType, | ||
"-salt", salt, | ||
password, | ||
) | ||
hash, err := cmd.CombinedOutput() | ||
if err != nil { | ||
return err, false | ||
} | ||
// password is correct | ||
strHash := string(hash) | ||
strHash = strings.TrimRight(strHash, "\n") | ||
if savedHash == strHash { | ||
return nil, true | ||
} | ||
return nil, false | ||
} | ||
|
||
// set the current device did | ||
func SetDeviceDid(presentation map[string]interface{}) error { | ||
// step: validate presentation | ||
if presentation["holder"] == nil { | ||
return errors.New("no holder provider in presentation") | ||
} | ||
// step: create hash | ||
did := presentation["holder"].(string) | ||
deviceSerial := system.GetDeviceInfo().Serial | ||
hash := sha256.Sum256([]byte(did + deviceSerial)) | ||
// step: save to file | ||
if err := os.MkdirAll(DID_DATA_DIR, perm.PUBLIC_WRITE); err != nil { | ||
return err | ||
} | ||
if err := os.WriteFile(DID_HASH_PATH, hash[:], perm.PUBLIC_VIEW); err != nil { | ||
return err | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package main | ||
|
||
import "github.com/cansulting/elabox-system-tools/foundation/app" | ||
|
||
// actions | ||
const AC_AUTH_DID = "account.actions.AUTH_DID" // use to authenticaticate specific did | ||
const AC_SETUP_CHECK = "account.actions.DID_SETUP_CHECK" // use to check if theres an existing did setup | ||
const AC_SETUP_DID = "account.actions.DID_SETUP" // use to setup did | ||
|
||
const PACKAGE_ID = "ela.account" | ||
const HOME_DIR = "/home/elabox" | ||
const DID_DATA_DIR = HOME_DIR + "/data/" + PACKAGE_ID | ||
const DID_HASH_PATH = DID_DATA_DIR + "/did.dat" | ||
const KEYSTORE_PATH = "/home/elabox/documents/ela.mainchain/keystore.dat" | ||
|
||
var Controller *app.Controller |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package main | ||
|
||
import "github.com/cansulting/elabox-system-tools/foundation/app" | ||
|
||
func main() { | ||
con, err := app.NewController(nil, &MyService{}) | ||
if err != nil { | ||
panic(err) | ||
} | ||
Controller = con | ||
app.RunApp(con) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package main | ||
|
||
import "testing" | ||
|
||
const SAMPLE_DID = "HELLO_DID_USER" | ||
const SAMPLE_USERNAME = "elabox" | ||
const SAMPLE_PASSWORD = "elabox" | ||
|
||
// use to test device did | ||
func Test_SetDeviceDid(t *testing.T) { | ||
presentation := make(map[string]interface{}) | ||
presentation["holder"] = SAMPLE_DID | ||
if err := SetDeviceDid(presentation); err != nil { | ||
t.Error(err) | ||
} | ||
} | ||
|
||
func Test_AuthenticationDid(t *testing.T) { | ||
if !AuthenticateDid(SAMPLE_DID) { | ||
t.Error("failed to authenticate did") | ||
} | ||
} | ||
|
||
func Test_AuthenticateSystemAccount(t *testing.T) { | ||
err, success := AuthenticateSystemAccount(SAMPLE_USERNAME, SAMPLE_PASSWORD) | ||
if err != nil { | ||
t.Error(err) | ||
return | ||
} | ||
t.Log("Authenticate", success) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package main | ||
|
||
import ( | ||
"github.com/cansulting/elabox-system-tools/foundation/app/rpc" | ||
"github.com/cansulting/elabox-system-tools/foundation/event/data" | ||
"github.com/cansulting/elabox-system-tools/foundation/event/protocol" | ||
) | ||
|
||
type MyService struct { | ||
} | ||
|
||
func (instance *MyService) IsRunning() bool { | ||
return true | ||
} | ||
|
||
func (instance *MyService) OnStart() error { | ||
Controller.RPC.OnRecieved(AC_AUTH_DID, instance.onAuthDidAction) | ||
Controller.RPC.OnRecieved(AC_SETUP_CHECK, instance.onCheckSetup) | ||
Controller.RPC.OnRecieved(AC_SETUP_DID, instance.onSetupDid) | ||
return nil | ||
} | ||
|
||
func (instance *MyService) OnEnd() error { | ||
return nil | ||
} | ||
|
||
// authorize user given the did presentation, upon success returns JWT token | ||
func (instance *MyService) onAuthDidAction(client protocol.ClientInterface, action data.Action) string { | ||
presentation, err := action.DataToMap() | ||
// step: validate presentation | ||
if err != nil { | ||
return rpc.CreateResponse(rpc.INVALID_CODE, "invalid did presentation provided, "+err.Error()) | ||
} | ||
if presentation["holder"] == nil { | ||
return rpc.CreateResponse(rpc.INVALID_CODE, "no holder was provided") | ||
} | ||
// step: compare with the existing hash | ||
did := presentation["holder"].(string) | ||
if AuthenticateDid(did) { | ||
acc := RetrievePrimaryAccountDetails() | ||
return rpc.CreateJsonResponse(rpc.SUCCESS_CODE, acc) | ||
} else { | ||
return rpc.CreateResponse(rpc.INVALID_CODE, "incorrect did credentials") | ||
} | ||
} | ||
|
||
// use to check whether the elabox was setup already. return "setup" if already setup | ||
func (instance *MyService) onCheckSetup(client protocol.ClientInterface, action data.Action) string { | ||
if IsDidSetup() { | ||
return rpc.CreateSuccessResponse("setup") | ||
} else { | ||
return rpc.CreateSuccessResponse("not_setup") | ||
} | ||
} | ||
|
||
// use to setup did, requires did presentation, username and password | ||
func (instance *MyService) onSetupDid(client protocol.ClientInterface, action data.Action) string { | ||
acData, err := action.DataToMap() | ||
// step: validate inputs | ||
if err != nil { | ||
return rpc.CreateResponse(rpc.INVALID_PARAMETER_PROVIDED, "invalid parameters provided, "+err.Error()) | ||
} | ||
if acData["presentation"] == nil { | ||
return rpc.CreateResponse(rpc.INVALID_PARAMETER_PROVIDED, "no presentation provided") | ||
} | ||
|
||
// step: authenticate for existing did setup | ||
if IsDidSetup() { | ||
if acData["username"] == nil || acData["password"] == nil { | ||
return rpc.CreateResponse(rpc.INVALID_PARAMETER_PROVIDED, "username and password is required") | ||
} | ||
pass := acData["password"].(string) | ||
username := acData["username"].(string) | ||
err, success := AuthenticateSystemAccount(username, pass) | ||
if err != nil { | ||
return rpc.CreateResponse(rpc.SYSTEMERR_CODE, err.Error()) | ||
} | ||
if !success { | ||
return rpc.CreateResponse(rpc.INVALID_PARAMETER_PROVIDED, "password or username is incorrect") | ||
} | ||
} | ||
presentation := acData["presentation"].(map[string]interface{}) | ||
if err := SetDeviceDid(presentation); err != nil { | ||
return rpc.CreateResponse(rpc.SYSTEMERR_CODE, "failed to setup did, "+err.Error()) | ||
} | ||
return rpc.CreateSuccessResponse("success") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package main | ||
|
||
import ( | ||
"encoding/json" | ||
"os" | ||
"strings" | ||
) | ||
|
||
type Address struct { | ||
Address string `json:"Address"` | ||
ProgramHash string `json:"ProgramHash"` | ||
} | ||
|
||
type KeyStore struct { | ||
Account []Address `json:"Account"` | ||
} | ||
|
||
func Grep(keyword string, src string) string { | ||
splits := strings.Split(src, "\n") | ||
keywordbt := []byte(keyword) | ||
for _, line := range splits { | ||
if len(line) >= len(keywordbt) { | ||
found := true | ||
for i, keywordC := range keywordbt { | ||
if keywordC != line[i] { | ||
found = false | ||
break | ||
} | ||
} | ||
if found { | ||
return line | ||
} | ||
} | ||
} | ||
// nothing was found | ||
return "" | ||
} | ||
|
||
// use to retrieve wallet address from keystore path | ||
func LoadWalletAddr() (string, error) { | ||
dat, err := os.ReadFile(KEYSTORE_PATH) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
var keyStore KeyStore | ||
_ = json.Unmarshal(dat, &keyStore) | ||
return keyStore.Account[0].Address, nil | ||
} |
Oops, something went wrong.