github.com/anycable/anycable-go@v1.5.1/identity/identity.go (about)

     1  package identity
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/anycable/anycable-go/common"
     7  	"github.com/anycable/anycable-go/node"
     8  )
     9  
    10  const (
    11  	actionCableWelcomeMessageTemplate        = "{\"type\":\"welcome\",\"sid\":\"%s\"}"
    12  	actionCableDisconnectUnauthorizedMessage = "{\"type\":\"disconnect\",\"reason\":\"unauthorized\",\"reconnect\":false}"
    13  )
    14  
    15  //go:generate mockery --name Identifier --output "../mocks" --outpkg mocks
    16  type Identifier interface {
    17  	Identify(sid string, env *common.SessionEnv) (*common.ConnectResult, error)
    18  }
    19  
    20  type IdentifierPipeline struct {
    21  	identifiers []Identifier
    22  }
    23  
    24  var _ Identifier = (*IdentifierPipeline)(nil)
    25  
    26  func NewIdentifierPipeline(identifiers ...Identifier) *IdentifierPipeline {
    27  	return &IdentifierPipeline{identifiers}
    28  }
    29  
    30  func (p *IdentifierPipeline) Identify(sid string, env *common.SessionEnv) (*common.ConnectResult, error) {
    31  	for _, i := range p.identifiers {
    32  		res, err := i.Identify(sid, env)
    33  
    34  		if err != nil || res != nil {
    35  			return res, err
    36  		}
    37  	}
    38  
    39  	return nil, nil
    40  }
    41  
    42  type IdentifiableController struct {
    43  	controller node.Controller
    44  	identifier Identifier
    45  }
    46  
    47  var _ node.Controller = (*IdentifiableController)(nil)
    48  
    49  func NewIdentifiableController(c node.Controller, i Identifier) *IdentifiableController {
    50  	return &IdentifiableController{c, i}
    51  }
    52  
    53  func (c *IdentifiableController) Start() error {
    54  	return c.controller.Start()
    55  }
    56  
    57  func (c *IdentifiableController) Shutdown() error {
    58  	return c.controller.Shutdown()
    59  }
    60  
    61  func (c *IdentifiableController) Authenticate(sid string, env *common.SessionEnv) (*common.ConnectResult, error) {
    62  	res, err := c.identifier.Identify(sid, env)
    63  
    64  	if err != nil {
    65  		return nil, err
    66  	}
    67  
    68  	// Passthrough
    69  	if res == nil {
    70  		return c.controller.Authenticate(sid, env)
    71  	}
    72  
    73  	if res.CState == nil {
    74  		res.CState = make(map[string]string)
    75  	}
    76  
    77  	res.DisconnectInterest = -1
    78  
    79  	return res, err
    80  }
    81  
    82  func (c *IdentifiableController) Subscribe(sid string, env *common.SessionEnv, id string, channel string) (*common.CommandResult, error) {
    83  	return c.controller.Subscribe(sid, env, id, channel)
    84  }
    85  
    86  func (c *IdentifiableController) Unsubscribe(sid string, env *common.SessionEnv, id string, channel string) (*common.CommandResult, error) {
    87  	return c.controller.Unsubscribe(sid, env, id, channel)
    88  }
    89  
    90  func (c *IdentifiableController) Perform(sid string, env *common.SessionEnv, id string, channel string, data string) (*common.CommandResult, error) {
    91  	return c.controller.Perform(sid, env, id, channel, data)
    92  }
    93  func (c *IdentifiableController) Disconnect(sid string, env *common.SessionEnv, id string, subscriptions []string) error {
    94  	return c.controller.Disconnect(sid, env, id, subscriptions)
    95  }
    96  
    97  func actionCableWelcomeMessage(sid string) string {
    98  	return fmt.Sprintf(actionCableWelcomeMessageTemplate, sid)
    99  }