Skip to content

Commit

Permalink
Enhnace the AOL msg validation (#68)
Browse files Browse the repository at this point in the history
  • Loading branch information
Youngjoon Lee authored Oct 16, 2020
1 parent 5a8f061 commit 3fbac4f
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 19 deletions.
17 changes: 17 additions & 0 deletions .gitbook/specifications/aol.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ type MsgCreateTopic struct {

A `MsgCreateTopic` is constructed to facilitate the AOL topic. Message sender can set a topic and description. The writer can add record after receiving the appropriate privileges.

Each field has limit. See the [Limits](#limits) section.

#### Add Writer

```go
Expand All @@ -32,6 +34,8 @@ type MsgAddWriter struct {

The owner of the exist topics can manage writer privileges. Writer who received privileges from the topic owner can add record to the topic. This means that the owner authenticate the writer. This `MsgAddWriter` performs a function similar to issuing a certificate.

Each field has limit. See the [Limits](#limits) section.

#### Delete Writer

```go
Expand All @@ -45,6 +49,8 @@ type MsgDeleteWriter struct {

This `MsgDeleteWriter` removes writer from the topic. It is impossible to add record to the topic after being deprived of authority.

Each field has limit. See the [Limits](#limits) section.

#### Add Record

```go
Expand All @@ -61,3 +67,14 @@ type MsgAddRecord struct {

This `MsgAddRecord` add record or any data to the topic. If `FeePayerAddress` is provided, node charges fee to FeePayer.

Each field has limit. See the [Limits](#limits) section.

### Limits

|Field|Min Length|Max Length|Charset|
|-----|----------|----------|-------|
|`TopicName`|1|70|`a-z`, `A-Z`, `0-9`, `.`, `_` and `-`|
|`Moniker`|0|70|`a-z`, `A-Z`, `0-9`, `.`, `_` and `-`|
|`Description`|0|5,000|Any|
|`Key`|0|70|Any|
|`Value`|0|5,000|Any|
10 changes: 10 additions & 0 deletions x/aol/types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ const (
CodeWriterExists sdk.CodeType = 104
CodeWriterNotFound sdk.CodeType = 104
CodeWriterNotAuthorized sdk.CodeType = 105
CodeInvalidTopic sdk.CodeType = 106
CodeInvalidMoniker sdk.CodeType = 107
)

func ErrMessageTooLarge(descriptor string, got, max int) sdk.Error {
Expand All @@ -41,3 +43,11 @@ func ErrWriterNotFound(writer sdk.AccAddress) sdk.Error {
func ErrWriterNotAuthorized(writer sdk.AccAddress) sdk.Error {
return sdk.NewError(DefaultCodespace, CodeWriterNotAuthorized, "writer %v not authorized", writer)
}

func ErrInvalidTopic(topic string) sdk.Error {
return sdk.NewError(DefaultCodespace, CodeInvalidTopic, "invalid topic %v", topic)
}

func ErrInvalidMoniker(moniker string) sdk.Error {
return sdk.NewError(DefaultCodespace, CodeInvalidMoniker, "invalid moniker %v", moniker)
}
86 changes: 67 additions & 19 deletions x/aol/types/msgs.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package types

import (
"regexp"

sdk "github.com/cosmos/cosmos-sdk/types"
)

Expand Down Expand Up @@ -31,11 +33,11 @@ func (msg MsgCreateTopic) Route() string { return RouterKey }
func (msg MsgCreateTopic) Type() string { return "create_topic" }

func (msg MsgCreateTopic) ValidateBasic() sdk.Error {
if len(msg.TopicName) > MaxTopicLength {
return ErrMessageTooLarge("topic_name", len(msg.TopicName), MaxTopicLength)
if err := validateTopic(msg.TopicName); err != nil {
return err
}
if len(msg.Description) > MaxDescriptionLength {
return ErrMessageTooLarge("description", len(msg.Description), MaxDescriptionLength)
if err := validateDescription(msg.Description); err != nil {
return err
}
if msg.OwnerAddress.Empty() {
return sdk.ErrInvalidAddress(msg.OwnerAddress.String())
Expand Down Expand Up @@ -66,14 +68,14 @@ func (msg MsgAddWriter) Route() string { return RouterKey }
func (msg MsgAddWriter) Type() string { return "add_writer" }

func (msg MsgAddWriter) ValidateBasic() sdk.Error {
if len(msg.TopicName) > MaxTopicLength {
return ErrMessageTooLarge("topic_name", len(msg.TopicName), MaxTopicLength)
if err := validateTopic(msg.TopicName); err != nil {
return err
}
if len(msg.Moniker) > MaxMonikerLength {
return ErrMessageTooLarge("moniker", len(msg.Moniker), MaxMonikerLength)
if err := validateMoniker(msg.Moniker); err != nil {
return err
}
if len(msg.Description) > MaxDescriptionLength {
return ErrMessageTooLarge("description", len(msg.Description), MaxDescriptionLength)
if err := validateDescription(msg.Description); err != nil {
return err
}
if msg.WriterAddress.Empty() {
return sdk.ErrInvalidAddress(msg.WriterAddress.String())
Expand Down Expand Up @@ -105,9 +107,8 @@ func (msg MsgDeleteWriter) Route() string { return RouterKey }
func (msg MsgDeleteWriter) Type() string { return "delete_writer" }

func (msg MsgDeleteWriter) ValidateBasic() sdk.Error {
// TODO Empty Topic error
if len(msg.TopicName) > MaxTopicLength {
return ErrMessageTooLarge("topic_name", len(msg.TopicName), MaxTopicLength)
if err := validateTopic(msg.TopicName); err != nil {
return err
}
if msg.WriterAddress.Empty() {
// TODO Error Message
Expand Down Expand Up @@ -143,14 +144,14 @@ func (msg MsgAddRecord) Route() string { return RouterKey }
func (msg MsgAddRecord) Type() string { return "add_record" }

func (msg MsgAddRecord) ValidateBasic() sdk.Error {
if len(msg.TopicName) > MaxTopicLength {
return ErrMessageTooLarge("topic", len(msg.TopicName), MaxTopicLength)
if err := validateTopic(msg.TopicName); err != nil {
return err
}
if len(msg.Key) > MaxRecordKeyLength {
return ErrMessageTooLarge("key", len(msg.Key), MaxRecordKeyLength)
if err := validateRecordKey(msg.Key); err != nil {
return err
}
if len(msg.Value) > MaxRecordValueLength {
return ErrMessageTooLarge("value", len(msg.Value), MaxRecordValueLength)
if err := validateRecordValue(msg.Value); err != nil {
return err
}
if msg.WriterAddress.Empty() {
return sdk.ErrInvalidAddress(msg.WriterAddress.String())
Expand All @@ -172,3 +173,50 @@ func (msg MsgAddRecord) GetSigners() []sdk.AccAddress {
}
return []sdk.AccAddress{msg.FeePayerAddress, msg.WriterAddress}
}

func validateTopic(topic string) sdk.Error {
if len(topic) > MaxTopicLength {
return ErrMessageTooLarge("topic", len(topic), MaxTopicLength)
}

// cannot be an empty string
if !regexp.MustCompile("^[A-Za-z0-9._-]+$").MatchString(topic) {
return ErrInvalidTopic(topic)
}

return nil
}

func validateMoniker(moniker string) sdk.Error {
if len(moniker) > MaxMonikerLength {
return ErrMessageTooLarge("moniker", len(moniker), MaxMonikerLength)
}

// can be an empty string
if !regexp.MustCompile("^[A-Za-z0-9._-]*$").MatchString(moniker) {
return ErrInvalidMoniker(moniker)
}

return nil
}

func validateDescription(description string) sdk.Error {
if len(description) > MaxDescriptionLength {
return ErrMessageTooLarge("description", len(description), MaxDescriptionLength)
}
return nil
}

func validateRecordKey(key []byte) sdk.Error {
if len(key) > MaxRecordKeyLength {
return ErrMessageTooLarge("key", len(key), MaxRecordKeyLength)
}
return nil
}

func validateRecordValue(value []byte) sdk.Error {
if len(value) > MaxRecordValueLength {
return ErrMessageTooLarge("value", len(value), MaxRecordValueLength)
}
return nil
}
73 changes: 73 additions & 0 deletions x/aol/types/msgs_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package types

import (
"bytes"
"testing"

"github.com/stretchr/testify/assert"
)

func TestValidateTopic(t *testing.T) {
assert.Nil(t, validateTopic("a.B_c-D123"))

assert.Equal(t, ErrInvalidTopic(""), validateTopic(""))
assert.Equal(t, ErrInvalidTopic("a$"), validateTopic("a$"))
assert.Equal(t, ErrInvalidTopic("a b"), validateTopic("a b"))
assert.Equal(t, ErrInvalidTopic(" ab"), validateTopic(" ab"))
assert.Equal(t, ErrInvalidTopic("ab "), validateTopic("ab "))

var buf bytes.Buffer
for i := 0; i < MaxTopicLength+1; i++ {
buf.WriteByte('a')
}
assert.Equal(t, ErrMessageTooLarge("topic", MaxTopicLength+1, MaxTopicLength), validateTopic(buf.String()))
}

func TestValidateMoniker(t *testing.T) {
assert.Nil(t, validateMoniker("a.B_c-D123"))
assert.Nil(t, validateMoniker(""))

assert.Equal(t, ErrInvalidMoniker("a$"), validateMoniker("a$"))
assert.Equal(t, ErrInvalidMoniker("a b"), validateMoniker("a b"))
assert.Equal(t, ErrInvalidMoniker(" ab"), validateMoniker(" ab"))
assert.Equal(t, ErrInvalidMoniker("ab "), validateMoniker("ab "))

var buf bytes.Buffer
for i := 0; i < MaxMonikerLength+1; i++ {
buf.WriteByte('a')
}
assert.Equal(t, ErrMessageTooLarge("moniker", MaxMonikerLength+1, MaxMonikerLength), validateMoniker(buf.String()))
}

func TestValidateDescription(t *testing.T) {
assert.Nil(t, validateDescription(""))
assert.Nil(t, validateDescription("abc"))

var buf bytes.Buffer
for i := 0; i < MaxDescriptionLength+1; i++ {
buf.WriteByte('a')
}
assert.Equal(t, ErrMessageTooLarge("description", MaxDescriptionLength+1, MaxDescriptionLength), validateDescription(buf.String()))
}

func TestValidateRecordKey(t *testing.T) {
assert.Nil(t, validateRecordKey([]byte{}))
assert.Nil(t, validateRecordKey([]byte("abc")))

var buf bytes.Buffer
for i := 0; i < MaxRecordKeyLength+1; i++ {
buf.WriteByte('a')
}
assert.Equal(t, ErrMessageTooLarge("key", MaxRecordKeyLength+1, MaxRecordKeyLength), validateRecordKey(buf.Bytes()))
}

func TestValidateRecordValue(t *testing.T) {
assert.Nil(t, validateRecordValue([]byte{}))
assert.Nil(t, validateRecordValue([]byte("abc")))

var buf bytes.Buffer
for i := 0; i < MaxRecordValueLength+1; i++ {
buf.WriteByte('a')
}
assert.Equal(t, ErrMessageTooLarge("value", MaxRecordValueLength+1, MaxRecordValueLength), validateRecordValue(buf.Bytes()))
}

0 comments on commit 3fbac4f

Please sign in to comment.