-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* SentFile: use db.OrderByID() * Fix search db reinstantiation and mirror bucket creation failure (#253) * Security: App tokens (#246) * App token flow ready. Tests WIP. * Remove comment * Add tests * Fix github actions set-env deprecation Co-authored-by: maurycy <[email protected]>
- Loading branch information
Showing
20 changed files
with
1,693 additions
and
419 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package keychain | ||
|
||
import ( | ||
"errors" | ||
|
||
"github.com/99designs/keyring" | ||
"github.com/FleekHQ/space-daemon/core/permissions" | ||
) | ||
|
||
const AppTokenStoreKey = "appToken" | ||
const MasterAppTokenStoreKey = "masterAppToken" | ||
|
||
var ErrMasterTokenAlreadyExists = errors.New("master app token already exists") | ||
|
||
func (kc *keychain) StoreAppToken(tok *permissions.AppToken) error { | ||
ring, err := kc.getKeyRing() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Prevent overriding existing master key | ||
key, _ := kc.st.Get([]byte(getMasterTokenStKey())) | ||
if key != nil && tok.IsMaster { | ||
return ErrMasterTokenAlreadyExists | ||
} | ||
|
||
// Prevents overriding even if user logged out and logged back in (which clears the store) | ||
_, err = ring.Get(getMasterTokenStKey()) | ||
if err == nil && tok.IsMaster { | ||
return ErrMasterTokenAlreadyExists | ||
} | ||
|
||
marshalled, err := permissions.MarshalToken(tok) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
err = ring.Set(keyring.Item{ | ||
Key: AppTokenStoreKey + "_" + tok.Key, | ||
Data: marshalled, | ||
Label: "Space App - App Token", | ||
}) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if tok.IsMaster { | ||
if err := kc.st.Set([]byte(getMasterTokenStKey()), []byte(tok.Key)); err != nil { | ||
return err | ||
} | ||
|
||
if err := ring.Set(keyring.Item{ | ||
Key: getMasterTokenStKey(), | ||
Data: marshalled, | ||
Label: "Space App - Master App Token", | ||
}); err != nil { | ||
return err | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func (kc *keychain) GetAppToken(key string) (*permissions.AppToken, error) { | ||
ring, err := kc.getKeyRing() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
token, err := ring.Get(AppTokenStoreKey + "_" + key) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return permissions.UnmarshalToken(token.Data) | ||
} | ||
|
||
func getMasterTokenStKey() string { | ||
return AppTokenStoreKey + "_" + MasterAppTokenStoreKey | ||
} |
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,78 @@ | ||
package permissions | ||
|
||
import ( | ||
"crypto/rand" | ||
"encoding/base64" | ||
"encoding/json" | ||
"errors" | ||
"strings" | ||
) | ||
|
||
var invalidAppTokenErr = errors.New("app token is invalid") | ||
|
||
const tokenKeyLength = 20 | ||
const tokenSecretLength = 30 | ||
|
||
type AppToken struct { | ||
Key string `json:"key"` | ||
Secret string `json:"secret"` | ||
IsMaster bool `json:"isMaster"` | ||
Permissions []string `json:"permissions"` | ||
} | ||
|
||
func UnmarshalToken(marshalledToken []byte) (*AppToken, error) { | ||
var result AppToken | ||
err := json.Unmarshal(marshalledToken, &result) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &result, nil | ||
} | ||
|
||
func MarshalToken(tok *AppToken) ([]byte, error) { | ||
jsonData, err := json.Marshal(tok) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return jsonData, nil | ||
|
||
} | ||
|
||
func GenerateRandomToken(isMaster bool, permissions []string) (*AppToken, error) { | ||
k := make([]byte, tokenKeyLength) | ||
_, err := rand.Read(k) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
s := make([]byte, tokenSecretLength) | ||
_, err = rand.Read(s) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &AppToken{ | ||
Key: base64.RawURLEncoding.EncodeToString(k), | ||
Secret: base64.RawURLEncoding.EncodeToString(s), | ||
IsMaster: isMaster, | ||
Permissions: permissions, | ||
}, nil | ||
} | ||
|
||
func (a *AppToken) GetAccessToken() string { | ||
return a.Key + "." + a.Secret | ||
} | ||
|
||
func GetKeyAndSecretFromAccessToken(accessToken string) (key string, secret string, err error) { | ||
tp := strings.Split(accessToken, ".") | ||
if len(tp) < 2 { | ||
return "", "", errors.New("invalid token format") | ||
} | ||
|
||
key = tp[0] | ||
secret = tp[1] | ||
|
||
return | ||
} |
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,32 @@ | ||
package permissions_test | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/FleekHQ/space-daemon/core/permissions" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestPermissions_AppToken_Generation(t *testing.T) { | ||
tok, err := permissions.GenerateRandomToken(true, []string{}) | ||
assert.NoError(t, err) | ||
|
||
marshalled, err := permissions.MarshalToken(tok) | ||
assert.NoError(t, err) | ||
unmarshalled, err := permissions.UnmarshalToken(marshalled) | ||
assert.NoError(t, err) | ||
|
||
assert.Equal(t, tok, unmarshalled) | ||
} | ||
|
||
func TestPermissions_AppToken_GenerationWithPerms(t *testing.T) { | ||
tok, err := permissions.GenerateRandomToken(false, []string{"OpenFile", "ListDirectories"}) | ||
assert.NoError(t, err) | ||
|
||
marshalled, err := permissions.MarshalToken(tok) | ||
assert.NoError(t, err) | ||
unmarshalled, err := permissions.UnmarshalToken(marshalled) | ||
assert.NoError(t, err) | ||
|
||
assert.Equal(t, tok, unmarshalled) | ||
} |
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 services | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/FleekHQ/space-daemon/core/permissions" | ||
) | ||
|
||
func (s *Space) InitializeMasterAppToken(ctx context.Context) (*permissions.AppToken, error) { | ||
newAppToken, err := permissions.GenerateRandomToken(true, []string{}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return newAppToken, s.keychain.StoreAppToken(newAppToken) | ||
} |
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
Oops, something went wrong.