Skip to content

Commit

Permalink
Rename session.SessionCallbacks interface
Browse files Browse the repository at this point in the history
This renaming is more involved that other ones. Interfaces are hard.

First of all, introduce a new interface with identifiers that do not
offend golint:

  - use "Callbacks" instead of "SessionCallbacks" to avoid stuttering
    when importing (it will be called "session.Callbacks" in user code)

  - use "GetPublicKeyID" method name instead of "GetPublicKeyId"

Then update all existing code to use the new interface. Secure Session
itself should call the new method, accept and store Callbacks instance.
Users of Secure Session should implement the new GetPublicKeyID method.

However, in order to maintain backwards compatibility we have to allow
the old code to continue using the old SessionCallbacks interface with
GetPublicKeyId method. We implement this using an adapter struct that
translates new method calls into the old ones. Since Go does not have
method overloading we have to accept an "interface {}" instance and
check its type dynamically. These compatibility shims can be removed
when we drop the old interface.
  • Loading branch information
ilammy committed Mar 12, 2019
1 parent 5ab8a68 commit 3266977
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 8 deletions.
2 changes: 1 addition & 1 deletion docs/examples/Themis-server/go/ssession_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type clientTransportCallback struct {
serverID []byte
}

func (clb *clientTransportCallback) GetPublicKeyForId(ss *session.SecureSession, id []byte) *keys.PublicKey {
func (clb *clientTransportCallback) GetPublicKeyForID(ss *session.SecureSession, id []byte) *keys.PublicKey {
if bytes.Equal(id, clb.serverID) {
return &keys.PublicKey{Value: clb.serverPublic}
}
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/go/secure_session_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
type callbacks struct {
}

func (clb *callbacks) GetPublicKeyForId(ss *session.SecureSession, id []byte) *keys.PublicKey {
func (clb *callbacks) GetPublicKeyForID(ss *session.SecureSession, id []byte) *keys.PublicKey {
decodedID, err := base64.StdEncoding.DecodeString(string(id[:]))
if nil != err {
return nil
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/go/secure_session_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
type callbacks struct {
}

func (clb *callbacks) GetPublicKeyForId(ss *session.SecureSession, id []byte) *keys.PublicKey {
func (clb *callbacks) GetPublicKeyForID(ss *session.SecureSession, id []byte) *keys.PublicKey {
decodedID, err := base64.StdEncoding.DecodeString(string(id[:]))
if nil != err {
return nil
Expand Down
38 changes: 34 additions & 4 deletions gothemis/session/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,38 @@ const (
STATE_ESTABLISHED = StateEstablished
)

// Callbacks implements a delegate for SecureSession.
type Callbacks interface {
GetPublicKeyForID(ss *SecureSession, id []byte) *keys.PublicKey
StateChanged(ss *SecureSession, state int)
}

// SessionCallbacks implements a delegate for SecureSession.
//
// Deprecated: Since 0.11. Use "session.Callbacks" instead.
type SessionCallbacks interface {
GetPublicKeyForId(ss *SecureSession, id []byte) *keys.PublicKey
StateChanged(ss *SecureSession, state int)
}

type sessionCallbacksAdapter struct {
inner SessionCallbacks
}

func (adapter *sessionCallbacksAdapter) GetPublicKeyForID(ss *SecureSession, id []byte) *keys.PublicKey {
return adapter.inner.GetPublicKeyForId(ss, id)
}

func (adapter *sessionCallbacksAdapter) StateChanged(ss *SecureSession, state int) {
adapter.inner.StateChanged(ss, state)
}

// SecureSession is a lightweight mechanism for securing any kind of network communication
// (both private and public networks, including the Internet). It is protocol-agnostic and
// operates on the 5th layer of the network OSI model (the session layer).
type SecureSession struct {
ctx *C.struct_session_with_callbacks_type
clb SessionCallbacks
clb Callbacks
state int
}

Expand All @@ -54,8 +74,18 @@ func finalize(ss *SecureSession) {
}

// New makes a new Secure Session with provided peer ID, private key, and callbacks.
func New(id []byte, signKey *keys.PrivateKey, callbacks SessionCallbacks) (*SecureSession, error) {
ss := &SecureSession{clb: callbacks}
func New(id []byte, signKey *keys.PrivateKey, callbacks interface{}) (*SecureSession, error) {
// TODO: remove these dynamic type checks together with SessionCallbacks
realCallbacks, newInterface := callbacks.(Callbacks)
if !newInterface {
oldCallbacks, oldInterface := callbacks.(SessionCallbacks)
if oldInterface {
realCallbacks = &sessionCallbacksAdapter{inner: oldCallbacks}
} else {
return nil, errors.New("Invalid callback interface")
}
}
ss := &SecureSession{clb: realCallbacks}

if nil == id || 0 == len(id) {
return nil, errors.New("Failed to creating secure session object with empty id")
Expand Down Expand Up @@ -98,7 +128,7 @@ func onPublicKeyForId(ssCtx unsafe.Pointer, idPtr unsafe.Pointer, idLen C.size_t
id := C.GoBytes(idPtr, C.int(idLen))
ss = (*SecureSession)(unsafe.Pointer(uintptr(ssCtx) - unsafe.Offsetof(ss.ctx)))

pub := ss.clb.GetPublicKeyForId(ss, id)
pub := ss.clb.GetPublicKeyForID(ss, id)
if nil == pub {
return int(C.GOTHEMIS_INVALID_PARAMETER)
}
Expand Down
2 changes: 1 addition & 1 deletion gothemis/session/session_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type testCallbacks struct {
var clientID = []byte("client a")
var serverID = []byte("client b")

func (clb *testCallbacks) GetPublicKeyForId(ss *SecureSession, id []byte) *keys.PublicKey {
func (clb *testCallbacks) GetPublicKeyForID(ss *SecureSession, id []byte) *keys.PublicKey {
if bytes.Equal(clientID, id) {
return clb.a.Public
} else if bytes.Equal(serverID, id) {
Expand Down

0 comments on commit 3266977

Please sign in to comment.