Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactorings #27

Merged
merged 7 commits into from
May 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 15 additions & 13 deletions cmd/unmarshaler/unmarshaler_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,19 @@ import (
"github.com/mitch000001/go-hbci/generator"
)

var segmentFlag = flag.String("segment", "", "'MyAwesomeSegment'")
var segmentInterfaceFlag = flag.String("segment_interface", "Segment", "'MyAwesomeInterface'")
var segmentVersionsFlag segmentVersions
var segmentName string
var segmentInterface string
var segmentVersions segmentVersionsFlag

func init() {
flag.Var(&segmentVersionsFlag, "segment_versions", "'MyAwesomeSegmentVersion1:1,MyAwesomeSegmentVersion2:2'")
flag.StringVar(&segmentName, "segment", "", "'MyAwesomeSegment'")
flag.StringVar(&segmentInterface, "segment_interface", "Segment", "'MyAwesomeInterface'")
flag.Var(&segmentVersions, "segment_versions", "'MyAwesomeSegmentVersion1:1,MyAwesomeSegmentVersion2:2'")
}

func main() {
flag.Parse()
if *segmentFlag == "" {
if segmentName == "" {
fmt.Printf("You must provide a segment to generate the unmarshaler\n")
os.Exit(1)
}
Expand All @@ -37,12 +39,12 @@ func main() {
fmt.Println(err)
}
segment := generator.SegmentIdentifier{
Name: *segmentFlag,
InterfaceName: *segmentInterfaceFlag,
Versions: segmentVersionsFlag,
Name: segmentName,
InterfaceName: segmentInterface,
Versions: segmentVersions,
}
var generated io.Reader
if len(segmentVersionsFlag) != 0 {
if len(segmentVersions) != 0 {
segmentGenerator := generator.NewVersionedSegmentUnmarshaler(segment, packageName, fileSet, f)
generated, err = segmentGenerator.Generate()
} else {
Expand All @@ -61,7 +63,7 @@ func main() {
}
defer file.Close()
fileSet = token.NewFileSet()
newAstFile, err := parser.ParseFile(fileSet, newFileName, generated, 0)
newAstFile, err := parser.ParseFile(fileSet, newFileName, generated, parser.ParseComments)
if err != nil {
fmt.Println(err)
}
Expand All @@ -71,17 +73,17 @@ func main() {
}
}

type segmentVersions []generator.SegmentIdentifier
type segmentVersionsFlag []generator.SegmentIdentifier

func (s *segmentVersions) String() string {
func (s *segmentVersionsFlag) String() string {
var buf bytes.Buffer
for _, version := range *s {
fmt.Fprintf(&buf, "%s:%d:%s", version.Name, version.Version, version.InterfaceName)
}
return buf.String()
}

func (s *segmentVersions) Set(in string) error {
func (s *segmentVersionsFlag) Set(in string) error {
unquoted, err := strconv.Unquote(in)
if err != nil {
return fmt.Errorf("Invalid input: %q (%v)", in, err)
Expand Down
44 changes: 27 additions & 17 deletions dialog/dialog.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,13 @@ type Dialog interface {
SendMessage(message.HBCIMessage) (message.BankMessage, error)
}

const initialDialogID = "0"
const initialClientSystemID = "0"
const anonymousClientID = "9999999999"
const (
initialDialogID = "0"
initialClientSystemID = "0"
initialBankParameterDataVersion = 0
initialUserParameterDataVersion = 0
anonymousClientID = "9999999999"
)

func newDialog(
bankID domain.BankID,
Expand Down Expand Up @@ -134,7 +138,9 @@ func (d *dialog) SendMessage(clientMessage message.HBCIMessage) (message.BankMes
func (d *dialog) SyncClientSystemID() (string, error) {
syncMessage := message.NewSynchronisationMessage(d.hbciVersion)
syncMessage.Identification = segment.NewIdentificationSegment(d.BankID, d.clientID, initialClientSystemID, true)
syncMessage.ProcessingPreparation = segment.NewProcessingPreparationSegment(0, 0, 1)
syncMessage.ProcessingPreparation = segment.NewProcessingPreparationSegment(
initialBankParameterDataVersion, initialUserParameterDataVersion, domain.German,
)
syncMessage.Sync = d.hbciVersion.SynchronisationRequest(segment.SyncModeAquireClientID)
syncMessage.BasicMessage = d.newBasicMessage(syncMessage)
signedSyncMessage, err := syncMessage.Sign(d.signatureProvider)
Expand Down Expand Up @@ -207,7 +213,7 @@ func (d *dialog) SendAnonymousMessage(clientMessage message.HBCIMessage) (messag
defer func() { logErr(d.anonymousEnd()) }()
// TODO: add checks if job needs signature or not
requestMessage := d.newBasicMessage(clientMessage)
requestMessage.SetNumbers()
requestMessage.SetSegmentPositions()
bankMessage, err := d.request(requestMessage)
if err != nil {
return nil, err
Expand All @@ -233,9 +239,11 @@ func (d *dialog) anonymousInit() error {
d.messageCount = 0
initMessage := message.NewDialogInitializationClientMessage(d.hbciVersion)
initMessage.Identification = segment.NewIdentificationSegment(d.BankID, anonymousClientID, initialClientSystemID, false)
initMessage.ProcessingPreparation = segment.NewProcessingPreparationSegment(d.BankParameterDataVersion(), d.UserParameterDataVersion(), d.Language)
initMessage.ProcessingPreparation = segment.NewProcessingPreparationSegment(
d.BankParameterDataVersion(), d.UserParameterDataVersion(), d.Language,
)
initMessage.BasicMessage = d.newBasicMessage(initMessage)
initMessage.SetNumbers()
initMessage.SetSegmentPositions()
bankMessage, err := d.request(initMessage)
if err != nil {
return err
Expand All @@ -256,7 +264,7 @@ func (d *dialog) anonymousInit() error {
return err
}

bankInfoMessage := bankMessage.FindSegment("HIKIM")
bankInfoMessage := bankMessage.FindSegment(segment.BankAnnouncementID)
if bankInfoMessage != nil {
bankInfoSegment := bankInfoMessage.(*segment.BankAnnouncementSegment)
internal.Info.Printf("INFO:\n%s\n%s\n", bankInfoSegment.Subject.Val(), bankInfoSegment.Body.Val())
Expand All @@ -281,7 +289,7 @@ func (d *dialog) anonymousInit() error {
func (d *dialog) anonymousEnd() error {
dialogEnd := message.NewDialogFinishingMessage(d.hbciVersion, d.dialogID)
dialogEnd.BasicMessage = d.newBasicMessage(dialogEnd)
dialogEnd.SetNumbers()
dialogEnd.SetSegmentPositions()

decryptedMessage, err := d.request(dialogEnd)
if err != nil {
Expand Down Expand Up @@ -314,7 +322,9 @@ func (d *dialog) init() error {
d.messageCount = 0
initMessage := message.NewDialogInitializationClientMessage(d.hbciVersion)
initMessage.Identification = segment.NewIdentificationSegment(d.BankID, d.clientID, d.ClientSystemID, true)
initMessage.ProcessingPreparation = segment.NewProcessingPreparationSegment(d.BankParameterDataVersion(), d.UserParameterDataVersion(), d.Language)
initMessage.ProcessingPreparation = segment.NewProcessingPreparationSegment(
d.BankParameterDataVersion(), d.UserParameterDataVersion(), d.Language,
)
initMessage.BasicMessage = d.newBasicMessage(initMessage)
signedInitMessage, err := initMessage.Sign(d.signatureProvider)
if err != nil {
Expand Down Expand Up @@ -345,7 +355,7 @@ func (d *dialog) init() error {
return err
}

bankInfoMessage := decryptedMessage.FindSegment("HIKIM")
bankInfoMessage := decryptedMessage.FindSegment(segment.BankAnnouncementID)
if bankInfoMessage != nil {
bankInfoSegment := bankInfoMessage.(*segment.BankAnnouncementSegment)
internal.Info.Printf("INFO:\n%s\n%s\n", bankInfoSegment.Subject.Val(), bankInfoSegment.Body.Val())
Expand Down Expand Up @@ -429,12 +439,12 @@ func (d *dialog) newBasicMessage(hbciMessage message.HBCIMessage) *message.Basic
}

func (d *dialog) parseBankParameterData(bankMessage message.BankMessage) error {
bankParamData := bankMessage.FindSegment("HIBPA")
bankParamData := bankMessage.FindSegment(segment.CommonBankParameterID)
if bankParamData != nil {
paramSegment := bankParamData.(segment.CommonBankParameter)
d.BankParameterData = paramSegment.BankParameterData()
}
pinTanTransactions := bankMessage.FindSegment("DIPINS")
pinTanTransactions := bankMessage.FindSegment(segment.PinTanBusinessTransactionParamsID)
if pinTanTransactions != nil {
pinTanTransactionSegment := pinTanTransactions.(segment.PinTanBusinessTransactionParams)
pinTransactions := make(map[string]bool)
Expand All @@ -447,14 +457,14 @@ func (d *dialog) parseBankParameterData(bankMessage message.BankMessage) error {
}

func (d *dialog) parseUserParameterData(bankMessage message.BankMessage) error {
userParamData := bankMessage.FindSegment("HIUPA")
userParamData := bankMessage.FindSegment(segment.CommonUserParameterDataID)
if userParamData != nil {
paramSegment := userParamData.(segment.CommonUserParameterData)
d.UserParameterData = paramSegment.UserParameterData()
d.clientID = d.UserParameterData.UserID
}

accountData := bankMessage.FindSegments("HIUPD")
accountData := bankMessage.FindSegments(segment.AccountInformationID)
if accountData != nil {
for _, acc := range accountData {
infoSegment := acc.(segment.AccountInformation)
Expand Down Expand Up @@ -517,7 +527,7 @@ func (d *dialog) request(clientMessage message.ClientMessage) (message.BankMessa
}

func (d *dialog) extractEncryptedMessage(response *transport.Response) (*message.EncryptedMessage, error) {
messageHeader := response.FindSegment("HNHBK")
messageHeader := response.FindSegment(segment.MessageHeaderID)
if messageHeader == nil {
return nil, fmt.Errorf("Malformed response: missing Message Header")
}
Expand Down Expand Up @@ -546,7 +556,7 @@ func (d *dialog) extractEncryptedMessage(response *transport.Response) (*message
}

func extractUnencryptedMessage(response *transport.Response) (message.BankMessage, error) {
messageHeader := response.FindSegment("HNHBK")
messageHeader := response.FindSegment(segment.MessageHeaderID)
if messageHeader == nil {
return nil, fmt.Errorf("Malformed response: missing Message Header")
}
Expand Down
12 changes: 6 additions & 6 deletions dialog/pin_tan_dialog.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ type Config struct {

// NewPinTanDialog creates a new dialog to use for pin/tan transport
func NewPinTanDialog(config Config) *PinTanDialog {
pinKey := domain.NewPinKey("", domain.NewPinTanKeyName(config.BankID, config.UserID, "S"))
signatureProvider := message.NewPinTanSignatureProvider(pinKey, "0")
pinKey = domain.NewPinKey("", domain.NewPinTanKeyName(config.BankID, config.UserID, "V"))
cryptoProvider := message.NewPinTanCryptoProvider(pinKey, "0")
pinKey := domain.NewPinKey("", domain.NewPinTanKeyName(config.BankID, config.UserID, domain.KeyTypeSigning))
signatureProvider := message.NewPinTanSignatureProvider(pinKey, initialClientSystemID)
pinKey = domain.NewPinKey("", domain.NewPinTanKeyName(config.BankID, config.UserID, domain.KeyTypeEncryption))
cryptoProvider := message.NewPinTanCryptoProvider(pinKey, initialClientSystemID)
d := &PinTanDialog{
dialog: newDialog(
config.BankID,
Expand Down Expand Up @@ -57,8 +57,8 @@ type PinTanDialog struct {

// SetPin lets the user reset the pin after creation
func (d *PinTanDialog) SetPin(pin string) {
pinKey := domain.NewPinKey(pin, domain.NewPinTanKeyName(d.BankID, d.UserID, "S"))
pinKey := domain.NewPinKey(pin, domain.NewPinTanKeyName(d.BankID, d.UserID, domain.KeyTypeSigning))
d.signatureProvider = message.NewPinTanSignatureProvider(pinKey, d.ClientSystemID)
pinKey = domain.NewPinKey(pin, domain.NewPinTanKeyName(d.BankID, d.UserID, "V"))
pinKey = domain.NewPinKey(pin, domain.NewPinTanKeyName(d.BankID, d.UserID, domain.KeyTypeEncryption))
d.cryptoProvider = message.NewPinTanCryptoProvider(pinKey, d.ClientSystemID)
}
2 changes: 1 addition & 1 deletion domain/acknowledgement.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ type Acknowledgement struct {
ReferenceDataElement string
Text string
Params []string
ReferencingMessage ReferencingMessage
ReferencingMessage MessageReference
ReferencingSegmentNumber int
}

Expand Down
27 changes: 18 additions & 9 deletions domain/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,19 @@ type Key interface {
CanEncrypt() bool
}

const initialKeyVersion = 999
const (
initialKeyNumber = 999
initialKeyVersion = 999
KeyTypeSigning = KeyType("S")
KeyTypeEncryption = KeyType("V")
)

type KeyType string

func (k KeyType) String() string { return string(k) }

// NewPinTanKeyName returns a new KeyName for the pin/tan flow
func NewPinTanKeyName(bankID BankID, userID string, keyType string) *KeyName {
func NewPinTanKeyName(bankID BankID, userID string, keyType KeyType) *KeyName {
return &KeyName{
BankID: bankID,
UserID: userID,
Expand All @@ -38,34 +47,34 @@ func NewPinTanKeyName(bankID BankID, userID string, keyType string) *KeyName {
}

// NewInitialKeyName represents a KeyName ready to use for initial communication
func NewInitialKeyName(countryCode int, bankID, userID string, keyType string) *KeyName {
func NewInitialKeyName(countryCode int, bankID, userID string, keyType KeyType) *KeyName {
return &KeyName{
BankID: BankID{CountryCode: countryCode, ID: bankID},
UserID: userID,
KeyType: keyType,
KeyNumber: 999,
KeyVersion: 999,
KeyNumber: initialKeyNumber,
KeyVersion: initialKeyVersion,
}
}

// KeyName provides data about a given key
type KeyName struct {
BankID BankID
UserID string
KeyType string
KeyType KeyType
KeyNumber int
KeyVersion int
}

// IsInitial returns true if the KeyName represents an initial KeyName, false otherwise
func (k *KeyName) IsInitial() bool {
return k.KeyNumber == 999 && k.KeyVersion == 999
return k.KeyNumber == initialKeyNumber && k.KeyVersion == initialKeyVersion
}

// SetInitial resets the KeyName to reflect an initial KeyName
func (k *KeyName) SetInitial() {
k.KeyNumber = 999
k.KeyVersion = 999
k.KeyNumber = initialKeyNumber
k.KeyVersion = initialKeyVersion
}

// NewPinKey returns a new PinKey
Expand Down
4 changes: 2 additions & 2 deletions domain/message.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package domain

// ReferencingMessage represents a reference to another message within a given
// MessageReference represents a reference to another message within a given
// dialog
type ReferencingMessage struct {
type MessageReference struct {
DialogID string
MessageNumber int
}
24 changes: 12 additions & 12 deletions element/acknowledgement.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,26 +31,26 @@ func NewAcknowledgement(acknowledgement domain.Acknowledgement) *Acknowledgement
// transmit information from the bank institute to the client.
type AcknowledgementDataElement struct {
DataElement
Code *DigitDataElement
ReferenceDataElement *AlphaNumericDataElement
Text *AlphaNumericDataElement
Params *ParamsDataElement
referencingMessage domain.ReferencingMessage
referencingSegmentNumber int
typ string
Code *DigitDataElement
ReferenceDataElement *AlphaNumericDataElement
Text *AlphaNumericDataElement
Params *ParamsDataElement
referencingMessage domain.MessageReference
referencingSegmentPosition int
typ string
}

// SetReferencingMessage is used by MessageAcknowledgements to set the reference
// to the previously sent message. This is needed to identify the message within
// an ongoing dialog.
func (a *AcknowledgementDataElement) SetReferencingMessage(reference domain.ReferencingMessage) {
func (a *AcknowledgementDataElement) SetReferencingMessage(reference domain.MessageReference) {
a.referencingMessage = reference
}

// SetReferencingSegmentNumber is a setter for setting the Segment number this
// SetReferencingSegmentPosition is a setter for setting the Segment position this
// Acknowledgement is referring to.
func (a *AcknowledgementDataElement) SetReferencingSegmentNumber(number int) {
a.referencingSegmentNumber = number
func (a *AcknowledgementDataElement) SetReferencingSegmentPosition(position int) {
a.referencingSegmentPosition = position
}

// SetType sets the type of the Acknowledgement. There are only two types of
Expand All @@ -71,7 +71,7 @@ func (a *AcknowledgementDataElement) Val() domain.Acknowledgement {
Params: a.Params.Val(),
Type: a.typ,
ReferencingMessage: a.referencingMessage,
ReferencingSegmentNumber: a.referencingSegmentNumber,
ReferencingSegmentNumber: a.referencingSegmentPosition,
}
}

Expand Down
4 changes: 2 additions & 2 deletions element/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ type ReferencingMessageDataElement struct {
}

// Val returns the value of r as domain.ReferencingMessage
func (r *ReferencingMessageDataElement) Val() domain.ReferencingMessage {
return domain.ReferencingMessage{
func (r *ReferencingMessageDataElement) Val() domain.MessageReference {
return domain.MessageReference{
DialogID: r.DialogID.Val(),
MessageNumber: r.MessageNumber.Val(),
}
Expand Down
Loading