Move non-standard security modules back
This commit is contained in:
parent
2c6c508643
commit
38032520fa
@ -1,106 +0,0 @@
|
|||||||
package authentication
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/rand"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"somehole.com/common/security/identity"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
RetryCreateSessionToken = 3
|
|
||||||
MaxSessionAge = 1 * time.Hour
|
|
||||||
)
|
|
||||||
|
|
||||||
type SessionToken [8]byte
|
|
||||||
|
|
||||||
func NewSessionToken() (st SessionToken) {
|
|
||||||
var stBytes = make([]byte, 8)
|
|
||||||
rand.Read(stBytes)
|
|
||||||
st = SessionToken(stBytes)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type NextToken [4]byte
|
|
||||||
|
|
||||||
func NewNextToken() (nt NextToken) {
|
|
||||||
var ntBytes = make([]byte, 4)
|
|
||||||
rand.Read(ntBytes)
|
|
||||||
nt = NextToken(ntBytes)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type Session struct {
|
|
||||||
identity.Identity
|
|
||||||
nextTokens []NextToken
|
|
||||||
expiration time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewSession(identity identity.Identity) (s *Session) {
|
|
||||||
s = &Session{
|
|
||||||
Identity: identity,
|
|
||||||
nextTokens: make([]NextToken, 0),
|
|
||||||
expiration: time.Now().Add(MaxSessionAge),
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Session) Active() (ok bool) {
|
|
||||||
ok = time.Now().Before(s.expiration)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Session) NewNextToken() (nt NextToken) {
|
|
||||||
nt = NewNextToken()
|
|
||||||
s.nextTokens = append(s.nextTokens, nt)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Session) NextTokenIsCurrent(nt NextToken) (ok bool) {
|
|
||||||
ok = s.nextTokens[len(s.nextTokens)-1] == nt
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type SessionService struct {
|
|
||||||
sessions map[SessionToken]*Session
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewSessionService() (srv *SessionService) {
|
|
||||||
srv = &SessionService{
|
|
||||||
sessions: make(map[SessionToken]*Session),
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (srv *SessionService) NewSessionToken() (st SessionToken, err error) {
|
|
||||||
for i := 0; i < RetryCreateSessionToken; i++ {
|
|
||||||
st = NewSessionToken()
|
|
||||||
if _, exists := srv.sessions[st]; exists {
|
|
||||||
err = fmt.Errorf("could only creat colliding session tokens in %d tries", RetryCreateSessionToken)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
err = nil
|
|
||||||
break
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (srv *SessionService) AddSession(st SessionToken, session *Session) (err error) {
|
|
||||||
if _, exists := srv.sessions[st]; exists {
|
|
||||||
err = fmt.Errorf("session already exists")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
srv.sessions[st] = session
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (srv *SessionService) GetSession(sessionToken SessionToken) (session *Session, err error) {
|
|
||||||
var exists bool
|
|
||||||
session, exists = srv.sessions[sessionToken]
|
|
||||||
if !exists {
|
|
||||||
err = fmt.Errorf("session not found")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
package authorization
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"somehole.com/common/security/identity"
|
|
||||||
)
|
|
||||||
|
|
||||||
type record struct {
|
|
||||||
Verb
|
|
||||||
Noun
|
|
||||||
time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
type AuditService struct {
|
|
||||||
records map[identity.Id][]record
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewAuditService() (srv *AuditService) {
|
|
||||||
srv = &AuditService{}
|
|
||||||
return
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
package authorization
|
|
||||||
|
|
||||||
import "somehole.com/common/security/identity"
|
|
||||||
|
|
||||||
type Verb int
|
|
||||||
|
|
||||||
const (
|
|
||||||
_ Verb = iota
|
|
||||||
Create
|
|
||||||
Read
|
|
||||||
Watch
|
|
||||||
Update
|
|
||||||
Patch
|
|
||||||
Delete
|
|
||||||
)
|
|
||||||
|
|
||||||
type Noun int
|
|
||||||
|
|
||||||
const (
|
|
||||||
_ Noun = iota
|
|
||||||
Identity
|
|
||||||
Command
|
|
||||||
Log
|
|
||||||
)
|
|
||||||
|
|
||||||
type AuthorizationService struct {
|
|
||||||
*AuditService
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewAuthorizationService(auditService *AuditService) (srv *AuthorizationService) {
|
|
||||||
if auditService == nil {
|
|
||||||
auditService = NewAuditService()
|
|
||||||
}
|
|
||||||
srv = &AuthorizationService{
|
|
||||||
AuditService: auditService,
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (srv *AuthorizationService) Authorized(identity identity.Identity, verb Verb, noun Noun) (authorized bool, err error) {
|
|
||||||
authorized = true
|
|
||||||
return
|
|
||||||
}
|
|
@ -1,120 +0,0 @@
|
|||||||
package identity
|
|
||||||
|
|
||||||
import (
|
|
||||||
"crypto/rand"
|
|
||||||
"encoding/base64"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"somehole.com/common/security/signature"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
RetryCreateId = 3
|
|
||||||
)
|
|
||||||
|
|
||||||
type identity interface {
|
|
||||||
GetId() []byte
|
|
||||||
GetPublicKey() []byte
|
|
||||||
GetPublicKeySignature() []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
type Id [8]byte
|
|
||||||
|
|
||||||
func (i Id) String() (out string) {
|
|
||||||
out = base64.StdEncoding.EncodeToString(i[:])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type Identity struct {
|
|
||||||
Id Id
|
|
||||||
PublicKey signature.PublicKey
|
|
||||||
PublicKeySignature signature.Signature
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewIdentity(ident identity) (i Identity, err error) {
|
|
||||||
id := ident.GetId()
|
|
||||||
if len(id) != 8 {
|
|
||||||
err = errors.New("wrong size id")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
pubKey := ident.GetPublicKey()
|
|
||||||
if len(pubKey) != 96 {
|
|
||||||
err = errors.New("wrong size public key")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
pubKeySig := ident.GetPublicKeySignature()
|
|
||||||
if len(pubKeySig) != 48 {
|
|
||||||
err = errors.New("wrong size public key signature")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
i = Identity{
|
|
||||||
Id: Id(id),
|
|
||||||
PublicKey: signature.PublicKey(pubKey),
|
|
||||||
PublicKeySignature: signature.Signature(pubKeySig),
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i Identity) String() (out string) {
|
|
||||||
b := make([]byte, 0)
|
|
||||||
b = append(b, i.Id[:]...)
|
|
||||||
b = append(b, i.PublicKey[:]...)
|
|
||||||
b = append(b, i.PublicKeySignature[:]...)
|
|
||||||
out = base64.StdEncoding.EncodeToString(b)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func ParseIdentityString(in string) (i Identity, err error) {
|
|
||||||
var b []byte
|
|
||||||
b, err = base64.StdEncoding.DecodeString(in)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if len(b) != 8+96+48 {
|
|
||||||
err = errors.New("wrong for size identity data in string")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
i = Identity{
|
|
||||||
Id: Id(b[0:8]),
|
|
||||||
PublicKey: signature.PublicKey(b[8:104]),
|
|
||||||
PublicKeySignature: signature.Signature(b[104:152]),
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type IdentityService struct {
|
|
||||||
identities map[Id]Identity
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewIdentityService() (srv *IdentityService) {
|
|
||||||
srv = &IdentityService{
|
|
||||||
identities: make(map[Id]Identity),
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (srv *IdentityService) NewId() (id Id, err error) {
|
|
||||||
var idBytes = make([]byte, 8)
|
|
||||||
for i := 0; i < RetryCreateId; i++ {
|
|
||||||
rand.Read(idBytes)
|
|
||||||
if _, exists := srv.identities[id]; exists {
|
|
||||||
err = fmt.Errorf("could only creat colliding ids in %d tries", RetryCreateId)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
id = Id(idBytes)
|
|
||||||
err = nil
|
|
||||||
break
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (srv *IdentityService) AddIdentity(id Id, identity Identity) (err error) {
|
|
||||||
_, exists := srv.identities[id]
|
|
||||||
if exists {
|
|
||||||
err = fmt.Errorf("failed to add identity")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
srv.identities[id] = identity
|
|
||||||
return
|
|
||||||
}
|
|
45
security.go
45
security.go
@ -1,45 +0,0 @@
|
|||||||
package security
|
|
||||||
|
|
||||||
import (
|
|
||||||
"somehole.com/common/security/authentication"
|
|
||||||
"somehole.com/common/security/authorization"
|
|
||||||
"somehole.com/common/security/identity"
|
|
||||||
"somehole.com/common/security/signature"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Config struct {
|
|
||||||
Signer signature.Keypair
|
|
||||||
}
|
|
||||||
|
|
||||||
type SecurityService struct {
|
|
||||||
config Config
|
|
||||||
*authentication.SessionService
|
|
||||||
*authorization.AuditService
|
|
||||||
*authorization.AuthorizationService
|
|
||||||
*identity.IdentityService
|
|
||||||
*signature.SignatureService
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewSecurityService(config ...Config) (srv *SecurityService) {
|
|
||||||
cfg := Config{}
|
|
||||||
if len(config) == 1 {
|
|
||||||
cfg = config[0]
|
|
||||||
}
|
|
||||||
signatureService, err := signature.NewSignatureService(&cfg.Signer)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
identityService := identity.NewIdentityService()
|
|
||||||
sessionService := authentication.NewSessionService()
|
|
||||||
auditService := authorization.NewAuditService()
|
|
||||||
authorizationService := authorization.NewAuthorizationService(auditService)
|
|
||||||
srv = &SecurityService{
|
|
||||||
config: cfg,
|
|
||||||
SessionService: sessionService,
|
|
||||||
AuditService: auditService,
|
|
||||||
AuthorizationService: authorizationService,
|
|
||||||
IdentityService: identityService,
|
|
||||||
SignatureService: signatureService,
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user