tavern/storage/actor_id.go

126 lines
2.7 KiB
Go

package storage
import (
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
)
// type Actor interface {
// GetID() string
// GetInbox() string
// GetPublicKey() string
// GetKeyID() string
// GetDecodedPublicKey() (*rsa.PublicKey, error)
// }
type ActorID string
type LocalActor struct {
User *User
Actor *Actor
ActorID ActorID
}
func NewActorID(name, domain string) ActorID {
return ActorID(fmt.Sprintf("https://%s/users/%s", domain, name))
}
func KeyFromActor(actor Payload) (string, string, error) {
if actor == nil {
return "", "", fmt.Errorf("unable to get key from actor: actor nil")
}
publicKey, ok := JSONMap(actor, "publicKey")
if !ok {
return "", "", fmt.Errorf("unable to get key from actor: public key object missing")
}
keyID, ok := JSONString(publicKey, "id")
if !ok {
return "", "", fmt.Errorf("unable to get key from actor: public key object id invalid")
}
publicKeyPem, ok := JSONString(publicKey, "publicKeyPem")
if !ok {
return "", "", fmt.Errorf("unable to get key from actor: public key object id invalid")
}
return keyID, publicKeyPem, nil
}
func (a *Actor) GetDecodedPublicKey() (*rsa.PublicKey, error) {
if a.CurrentKey == nil {
return nil, fmt.Errorf("actor has no key")
}
return DecodePublicKey(a.CurrentKey.PEM)
}
func (a *Actor) GetID() string {
return a.ActorID
}
func (a *Actor) GetInbox() string {
return a.Inbox
}
func (a *Actor) GetKeyID() string {
if a.CurrentKey != nil {
return a.CurrentKey.KeyID
}
return ""
}
func (a *Actor) GetPublicKey() string {
if a.CurrentKey != nil {
return a.CurrentKey.PEM
}
return ""
}
func (k *Key) GetDecodedPublicKey() (*rsa.PublicKey, error) {
return DecodePublicKey(k.PEM)
}
func (ID ActorID) Followers() string {
return fmt.Sprintf("%s/followers", ID)
}
func (ID ActorID) FollowersPage(page int) string {
return fmt.Sprintf("%s/followers?page=%d", ID, page)
}
func (ID ActorID) Following() string {
return fmt.Sprintf("%s/following", ID)
}
func (ID ActorID) FollowingPage(page int) string {
return fmt.Sprintf("%s/following?page=%d", ID, page)
}
func (ID ActorID) Outbox() string {
return fmt.Sprintf("%s/outbox", ID)
}
func (ID ActorID) OutboxPage(page int) string {
return fmt.Sprintf("%s/outbox?page=%d", ID, page)
}
func (ID ActorID) Inbox() string {
return fmt.Sprintf("%s/inbox", ID)
}
func DecodePublicKey(data string) (*rsa.PublicKey, error) {
block, _ := pem.Decode([]byte(data))
if block == nil {
return nil, fmt.Errorf("invalid RSA PEM")
}
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, fmt.Errorf("invalid RSA PEM")
}
rsaPublicKey, ok := pub.(*rsa.PublicKey)
if !ok {
return nil, fmt.Errorf("invalid RSA PEM")
}
return rsaPublicKey, nil
}