Skip to content

Commit

Permalink
Refactor CLI packages (#195)
Browse files Browse the repository at this point in the history
* Resolves #194
  • Loading branch information
masomel authored Dec 15, 2017
1 parent ec6be0d commit 234bb6f
Show file tree
Hide file tree
Showing 58 changed files with 1,391 additions and 1,079 deletions.
2 changes: 1 addition & 1 deletion coniksbots/bot.go → application/bots/bot.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// Currently, this interface is used to implement a Twitter account
// verification bot.

package coniksbots
package bots

import (
"bytes"
Expand Down
52 changes: 52 additions & 0 deletions application/bots/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package bots

import (
"github.com/coniks-sys/coniks-go/application"
)

// A TwitterConfig contains the address of the named UNIX socket
// through which the bot and the CONIKS server communicate,
// the OAuth information needed to authenticate the bot with Twitter,
// and the bot's reserved Twitter handle. These values are specified
// in a configuration file, which is read at initialization time.
type TwitterConfig struct {
CONIKSAddress string `toml:"coniks_address"`
TwitterOAuth `toml:"twitter_oauth"`
Handle string `toml:"twitter_bot_handle"`
}

// A TwitterOAuth contains the four secret values needed to authenticate
// the bot with Twitter. These values are unique to each application
// that uses the Twitter API to access an account's feed and direct
// messages, and must be generated via Twitter's developer portal.
type TwitterOAuth struct {
ConsumerKey string
ConsumerSecret string
AccessToken string
AccessSecret string
}

var _ application.AppConfig = (*TwitterConfig)(nil)

// NewTwitterConfig initializes a new Twitter registration bot configuration
// with the given server address, Twitter handle, and OAuth credentials.
func NewTwitterConfig(addr, handle string, oauth TwitterOAuth) *TwitterConfig {
var conf = TwitterConfig{
CONIKSAddress: addr,
Handle: handle,
TwitterOAuth: oauth,
}

return &conf
}

// Load initializes a Twitter registration proxy configuration from the
// corresponding config file.
func (conf *TwitterConfig) Load(file string) error {
tmp, err := application.LoadConfig(file)
if err != nil {
return err
}
conf = tmp.(*TwitterConfig)
return nil
}
13 changes: 4 additions & 9 deletions coniksbots/doc.go → application/bots/doc.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Package coniksbots implements the CONIKS account verification
Package bots implements the CONIKS account verification
protocol for first-party identity providers.
Many communication services provide user identifiers for
Expand All @@ -9,11 +9,11 @@ wishing to communicate securely often opt to use a third-party
end-to-end encrypted communication service, which allows them
to connect their first-party account.
coniksbots provides such third-party secure communication services
bots provides such third-party secure communication services
that use CONIKS for key management with a mechanism for
ensuring that the first-party usernames registered with the
CONIKS key directory belong to a legitimate first-party account.
More specifically, coniksbots provides registration proxies which
More specifically, bots provides registration proxies which
verify that each first-party username belongs to a
corresponding first-party account before forwarding the new
registration to the third-party CONIKS server.
Expand All @@ -28,10 +28,5 @@ Twitter Bot
This module provides a registration proxy for Twitter accounts
that implements the CONIKS account verification Bot interface.
Cli
This subpackage provides an executable reference implementation for a CONIKS
registration proxy for Twitter accounts.
*/
package coniksbots
package bots
40 changes: 8 additions & 32 deletions coniksbots/twitterbot.go → application/bots/twitterbot.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// A registration proxy for Twitter accounts that implements the
// CONIKS account verification Bot interface.

package coniksbots
package bots

import (
"fmt"
Expand All @@ -10,8 +10,7 @@ import (
"strings"
"time"

"github.com/BurntSushi/toml"
"github.com/coniks-sys/coniks-go/coniksserver"
"github.com/coniks-sys/coniks-go/application"
"github.com/coniks-sys/coniks-go/protocol"
"github.com/dghubble/go-twitter/twitter"
"github.com/dghubble/oauth1"
Expand All @@ -34,28 +33,6 @@ type TwitterBot struct {

var _ Bot = (*TwitterBot)(nil)

// A TwitterConfig contains the address of the named UNIX socket
// through which the bot and the CONIKS server communicate,
// the OAuth information needed to authenticate the bot with Twitter,
// and the bot's reserved Twitter handle. These values are specified
// in a configuration file, which is read at initialization time.
type TwitterConfig struct {
CONIKSAddress string `toml:"coniks_address"`
TwitterOAuth `toml:"twitter_oauth"`
Handle string `toml:"twitter_bot_handle"`
}

// A TwitterOAuth contains the four secret values needed to authenticate
// the bot with Twitter. These values are unique to each application
// that uses the Twitter API to access an account's feed and direct
// messages, and must be generated via Twitter's developer portal.
type TwitterOAuth struct {
ConsumerKey string
ConsumerSecret string
AccessToken string
AccessSecret string
}

// NewTwitterBot constructs a new account verification bot for Twitter
// accounts that implements the Bot interface.
//
Expand All @@ -66,16 +43,15 @@ type TwitterOAuth struct {
// tuple. Otherwise, it returns a TwitterBot struct
// with the appropriate values obtained during the setup.
func NewTwitterBot(path string) (Bot, error) {
var conf TwitterConfig
if _, err := toml.DecodeFile(path, &conf); err != nil {
return nil, fmt.Errorf("Failed to load config: %v", err)
var conf *TwitterConfig = &TwitterConfig{}
if err := conf.Load(path); err != nil {
return nil, err
}

// Notify if the CONIKS key server is down
if _, err := os.Stat(conf.CONIKSAddress); os.IsNotExist(err) {
return nil, fmt.Errorf("CONIKS Key Server is down")
}

auth := conf.TwitterOAuth
config := oauth1.NewConfig(auth.ConsumerKey, auth.ConsumerSecret)
token := oauth1.NewToken(auth.AccessToken, auth.AccessSecret)
Expand Down Expand Up @@ -167,7 +143,7 @@ func (bot *TwitterBot) Stop() {
func (bot *TwitterBot) HandleRegistration(username string, msg []byte) string {
// validate request message
invalid := false
req, err := coniksserver.UnmarshalRequest(msg)
req, err := application.UnmarshalRequest(msg)
if err != nil {
invalid = true
} else {
Expand All @@ -180,7 +156,7 @@ func (bot *TwitterBot) HandleRegistration(username string, msg []byte) string {
}
if invalid {
log.Println("[registration bot] Malformed client request")
res, err := coniksserver.MarshalResponse(
res, err := application.MarshalResponse(
protocol.NewErrorResponse(protocol.ErrMalformedMessage))
if err != nil {
panic(err)
Expand All @@ -192,7 +168,7 @@ func (bot *TwitterBot) HandleRegistration(username string, msg []byte) string {
res, err := SendRequestToCONIKS(bot.coniksAddress, msg)
if err != nil {
log.Println("[registration bot] " + err.Error())
res, err := coniksserver.MarshalResponse(
res, err := application.MarshalResponse(
protocol.NewErrorResponse(protocol.ErrDirectory))
if err != nil {
panic(err)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package coniksbots
package bots

import (
"encoding/json"
Expand Down
47 changes: 26 additions & 21 deletions coniksclient/config.go → application/client/config.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
package coniksclient
package client

import (
"fmt"
"io/ioutil"

"github.com/BurntSushi/toml"
"github.com/coniks-sys/coniks-go/application"
"github.com/coniks-sys/coniks-go/crypto/sign"
"github.com/coniks-sys/coniks-go/utils"
)

// Config contains the client's configuration needed to send a request to a
Expand All @@ -26,27 +22,36 @@ type Config struct {
Address string `toml:"address"`
}

// LoadConfig returns a client's configuration read from the given filename.
var _ application.AppConfig = (*Config)(nil)

// NewConfig initializes a new client configuration with the given
// server signing public key path, registration address, and
// server address.
func NewConfig(signPubkeyPath, regAddr, serverAddr string) *Config {
var conf = Config{
SignPubkeyPath: signPubkeyPath,
RegAddress: regAddr,
Address: serverAddr,
}

return &conf
}

// Load initializes a client's configuration from the given file.
// It reads the signing public-key file and parses the actual key.
// If there is any parsing or IO-error it returns an error (and the returned
// config will be nil).
func LoadConfig(file string) (*Config, error) {
var conf Config
if _, err := toml.DecodeFile(file, &conf); err != nil {
return nil, fmt.Errorf("Failed to load config: %v", err)
func (conf *Config) Load(file string) error {
tmp, err := application.LoadConfig(file)
if err != nil {
return err
}
conf = tmp.(*Config)

// load signing key
signPath := utils.ResolvePath(conf.SignPubkeyPath, file)
signPubKey, err := ioutil.ReadFile(signPath)
signPubKey, err := application.LoadSigningPubKey(conf.SignPubkeyPath, file)
if err != nil {
return nil, fmt.Errorf("Cannot read signing key: %v", err)
return err
}
if len(signPubKey) != sign.PublicKeySize {
return nil, fmt.Errorf("Signing public-key must be 32 bytes (got %d)", len(signPubKey))
}

conf.SigningPubKey = signPubKey

return &conf, nil
return nil
}
25 changes: 25 additions & 0 deletions application/client/encoding.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package client

import (
"github.com/coniks-sys/coniks-go/application"
"github.com/coniks-sys/coniks-go/protocol"
)

// CreateRegistrationMsg returns a JSON encoding of
// a protocol.RegistrationRequest for the given (name, key) pair.
func CreateRegistrationMsg(name string, key []byte) ([]byte, error) {
return application.MarshalRequest(protocol.RegistrationType,
&protocol.RegistrationRequest{
Username: name,
Key: key,
})
}

// CreateKeyLookupMsg returns a JSON encoding of
// a protocol.KeyLookupRequest for the given name.
func CreateKeyLookupMsg(name string) ([]byte, error) {
return application.MarshalRequest(protocol.KeyLookupType,
&protocol.RegistrationRequest{
Username: name,
})
}
61 changes: 61 additions & 0 deletions application/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package application

import (
"bytes"
"fmt"
"io/ioutil"

"github.com/BurntSushi/toml"
"github.com/coniks-sys/coniks-go/crypto/sign"
"github.com/coniks-sys/coniks-go/utils"
)

// AppConfig is the generic type used to specify the configuration of
// any kind of CONIKS application-level executable (e.g. key server,
// client etc.).
type AppConfig interface {
Load(file string) error
}

// LoadSigningPubKey loads a public signing key at the given path
// specified in the given config file.
// If there is any parsing error or the key is malformed,
// LoadSigningPubKey() returns an error with a nil key.
func LoadSigningPubKey(path, file string) (sign.PublicKey, error) {
signPath := utils.ResolvePath(path, file)
signPubKey, err := ioutil.ReadFile(signPath)
if err != nil {
return nil, fmt.Errorf("Cannot read signing key: %v", err)
}
if len(signPubKey) != sign.PublicKeySize {
return nil, fmt.Errorf("Signing public-key must be 32 bytes (got %d)", len(signPubKey))
}
return signPubKey, nil
}

// LoadConfig loads an application configuration from the given toml-encoded
// file. If there is any decoding error, an LoadConfig() returns an error
// with a nil config.
func LoadConfig(file string) (AppConfig, error) {
var conf AppConfig
if _, err := toml.DecodeFile(file, &conf); err != nil {
return nil, fmt.Errorf("Failed to load config: %v", err)
}
return conf, nil
}

// SaveConfig stores the given configuration conf in the given
// file using toml encoding.
// If there is any encoding or IO error, SaveConfig() returns an error.
func SaveConfig(file string, conf AppConfig) error {
var confBuf bytes.Buffer

e := toml.NewEncoder(&confBuf)
if err := e.Encode(conf); err != nil {
return err
}
if err := utils.WriteFile(file, confBuf.Bytes(), 0644); err != nil {
return err
}
return nil
}
Loading

0 comments on commit 234bb6f

Please sign in to comment.