-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Refactor CI workflow to match version tags without wildcard * Refactor captcha handling and storage * Send captcha * Add captcha verification * Refactor captcha handling and storage, and add captcha verification * Refactor captcha deletion and logging * Refactor package structure for server-related files * Refactor captcha.go file * Refactor linter configuration and remove unused linters * Refactor test files: Remove unused imports and commented code * Add warning
- Loading branch information
Showing
17 changed files
with
757 additions
and
300 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,7 +29,7 @@ on: | |
branches: | ||
- master | ||
tags: | ||
- "v[0-9]+.[0-9]+.[0-9]+*" | ||
- "v[0-9]+.[0-9]+.[0-9]+" | ||
|
||
jobs: | ||
test: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -182,4 +182,7 @@ config.yml | |
# SQLite database file | ||
*.sqlite | ||
*.sqlite3 | ||
*.db | ||
*.db | ||
|
||
# Linter | ||
lint-reports |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
package model | ||
|
||
import ( | ||
"fmt" | ||
"io" | ||
"strconv" | ||
"strings" | ||
"time" | ||
|
||
"github.com/dchest/captcha" | ||
"github.com/plugfox/foxy-gram-server/internal/global" | ||
"github.com/plugfox/foxy-gram-server/internal/utility" | ||
) | ||
|
||
// idLength is the length of the captcha id to be used in generators. | ||
const idLength = 20 | ||
|
||
// Captcha - represents a captcha with an image and expiration time. | ||
type Captcha struct { | ||
ID int64 `gorm:"PrimaryKey" hash:"x" json:"id"` // Captcha ID. | ||
|
||
UserID int64 `gorm:"index" hash:"x" json:"user_id"` // Identifier for the user. | ||
|
||
ChatID int64 `gorm:"index" hash:"x" json:"chat_id"` // Identifier for the chat. | ||
|
||
MessageID int64 `gorm:"index" hash:"x" json:"message_id"` // Identifier for the message. | ||
|
||
Digits string `hash:"x" json:"digits"` // Digits of the captcha. | ||
|
||
Input string `hash:"x" json:"input"` // User input for the captcha. | ||
|
||
Length int `hash:"x" json:"length"` // Length of the captcha. | ||
|
||
Width int `hash:"x" json:"width"` // Width of the captcha. | ||
|
||
Height int `hash:"x" json:"height"` // Height of the captcha. | ||
|
||
Expiration time.Duration `hash:"x" json:"expiration"` // Expiration time of the captcha. | ||
|
||
ExpiresAt time.Time `hash:"x" json:"expires_at"` // Time when the captcha expires. | ||
|
||
// Meta fields | ||
UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"` // Time when the captcha was last updated. | ||
} | ||
|
||
// TableName - set the table name. | ||
func (Captcha) TableName() string { | ||
return "captchas" | ||
} | ||
|
||
// GetID - get the captcha ID. | ||
func (obj *Captcha) GetID() int64 { | ||
return obj.ID | ||
} | ||
|
||
// Hash - calculate the hash of the object. | ||
func (obj *Captcha) Hash() (string, error) { | ||
return utility.Hash(obj) | ||
} | ||
|
||
// Expired - checks if the captcha has expired. | ||
func (obj *Captcha) Expired() bool { | ||
return obj.ExpiresAt.Before(time.Now()) | ||
} | ||
|
||
// Validate - checks if the captcha input is correct. | ||
func (obj *Captcha) Validate() bool { | ||
return obj.Digits == obj.Input && !obj.Expired() | ||
} | ||
|
||
// Caption - returns the caption for the captcha. | ||
func (obj *Captcha) Caption(username string) string { | ||
var caption string | ||
if username != "" { | ||
caption = fmt.Sprintf("@%s, please solve the captcha.", username) | ||
} else { | ||
caption = "Please solve the captcha." | ||
} | ||
|
||
if obj.Input != "" { | ||
numbersEmojis := map[rune]string{ | ||
'0': "0️⃣", | ||
'1': "1️⃣", | ||
'2': "2️⃣", | ||
'3': "3️⃣", | ||
'4': "4️⃣", | ||
'5': "5️⃣", | ||
'6': "6️⃣", | ||
'7': "7️⃣", | ||
'8': "8️⃣", | ||
'9': "9️⃣", | ||
} | ||
|
||
var strNumbers []string | ||
for _, b := range obj.Input { | ||
strNumbers = append(strNumbers, numbersEmojis[b]) | ||
} | ||
|
||
caption += "\n\n" + strings.Join(strNumbers, " ") | ||
} | ||
|
||
return caption | ||
} | ||
|
||
// Generates a new captcha with the given configuration. | ||
func GenerateCaptcha(writer io.Writer) (*Captcha, error) { | ||
config := global.Config.Captcha | ||
randomDigits := captcha.RandomDigits(config.Length) | ||
|
||
id := string(captcha.RandomDigits(idLength)) | ||
image := captcha.NewImage(id, randomDigits, config.Width, config.Height) | ||
if _, err := image.WriteTo(writer); err != nil { | ||
return nil, err | ||
} | ||
|
||
strNumbers := make([]string, 0, len(randomDigits)) | ||
for _, b := range randomDigits { | ||
strNumbers = append(strNumbers, strconv.Itoa(int(b))) | ||
} | ||
|
||
digits := strings.Join(strNumbers, "") | ||
|
||
return &Captcha{ | ||
Digits: digits, | ||
Length: config.Length, | ||
Width: config.Width, | ||
Height: config.Height, | ||
Expiration: config.Expiration, | ||
ExpiresAt: time.Now().Add(config.Expiration), | ||
}, nil | ||
} | ||
|
||
func (obj *Captcha) Refresh(writer io.Writer) error { | ||
newCaptcha, err := GenerateCaptcha(writer) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
obj.Digits = newCaptcha.Digits | ||
obj.Length = newCaptcha.Length | ||
obj.Width = newCaptcha.Width | ||
obj.Height = newCaptcha.Height | ||
obj.Expiration = newCaptcha.Expiration | ||
obj.ExpiresAt = newCaptcha.ExpiresAt | ||
obj.Input = "" | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
package model | ||
|
||
import ( | ||
"io" | ||
"strconv" | ||
"strings" | ||
"testing" | ||
"time" | ||
|
||
"github.com/plugfox/foxy-gram-server/internal/config" | ||
"github.com/plugfox/foxy-gram-server/internal/global" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestCaptchaHash(t *testing.T) { | ||
testcases := []struct { | ||
Name string | ||
Captcha *Captcha | ||
ExpectedHash string | ||
}{ | ||
{ | ||
Name: "Captcha with all fields", | ||
Captcha: &Captcha{ | ||
ID: 1, | ||
Digits: "123456", | ||
Input: "123456", | ||
Length: 6, | ||
Width: 200, | ||
Height: 100, | ||
Expiration: 10, | ||
UserID: 1, | ||
ChatID: 1, | ||
MessageID: 1, | ||
ExpiresAt: time.Time{}, | ||
UpdatedAt: time.Time{}, | ||
}, | ||
ExpectedHash: "66025f011be311b43ef54f423ccf39c1e96a1105004a382f394d6b79e95df4cc", | ||
}, | ||
{ | ||
Name: "Captcha with missing fields", | ||
Captcha: &Captcha{ | ||
ID: 1, | ||
}, | ||
ExpectedHash: "7bd1ebf0a92a85b609177346c8a3e87104ebb62bab3ade021e3ee5456b5403e0", | ||
}, | ||
} | ||
|
||
InitHashFunction() | ||
|
||
for _, testcase := range testcases { | ||
t.Run(testcase.Name, func(t *testing.T) { | ||
hash, err := testcase.Captcha.Hash() | ||
require.NoError(t, err) | ||
require.NotEmpty(t, hash) | ||
|
||
hash2, _ := testcase.Captcha.Hash() | ||
require.Equal(t, hash, hash2) | ||
require.Equal(t, testcase.ExpectedHash, hash) | ||
}) | ||
} | ||
} | ||
|
||
func TestBytesToString(t *testing.T) { | ||
bytes := []byte{1, 2, 3, 4, 5} | ||
|
||
strNumbers := make([]string, 0, len(bytes)) | ||
for _, b := range bytes { | ||
strNumbers = append(strNumbers, strconv.Itoa(int(b))) | ||
} | ||
|
||
str := strings.Join(strNumbers, "") | ||
|
||
require.NotEmpty(t, str) | ||
require.Equal(t, "12345", str) | ||
} | ||
|
||
func TestGenerateNewCaptcha(t *testing.T) { | ||
global.Config = &config.Config{ | ||
Captcha: config.CaptchaConfig{ | ||
Length: 6, | ||
Width: 200, | ||
Height: 100, | ||
Expiration: 10, | ||
}, | ||
} | ||
|
||
captcha, err := GenerateCaptcha(io.Discard) | ||
require.NoError(t, err) | ||
require.NotNil(t, captcha) | ||
require.NotEmpty(t, captcha.Digits) | ||
require.NotEmpty(t, captcha.ExpiresAt) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
package api | ||
package server | ||
|
||
import ( | ||
"encoding/json" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.