Add query to api

This commit is contained in:
2021-04-13 07:30:07 +02:00
parent 6c20033bcc
commit 946bdd2a6a
5 changed files with 108 additions and 1 deletions

View File

@@ -3,6 +3,7 @@ package store
import (
"fmt"
"sort"
"strings"
"sync"
"github.uio.no/torjus/apiary/models"
@@ -116,6 +117,31 @@ func (ms *MemoryStore) statTotals() ([]StatsResult, error) {
return stats, nil
}
func (ms *MemoryStore) Query(query AttemptQuery) ([]models.LoginAttempt, error) {
var results []models.LoginAttempt
ms.lock.Lock()
defer ms.lock.Unlock()
for _, la := range ms.attempts {
switch query.QueryType {
case AttemptQueryTypeIP:
if la.RemoteIP.String() == query.Query {
results = append(results, la)
}
case AttemptQueryTypePassword:
if strings.Contains(la.Password, query.Query) {
results = append(results, la)
}
case AttemptQueryTypeUsername:
if strings.Contains(la.Username, query.Query) {
results = append(results, la)
}
}
}
return results, nil
}
func toResults(m map[string]int) []StatsResult {
var results []StatsResult

View File

@@ -158,3 +158,39 @@ func (s *PostgresStore) statsTotal(limit int) ([]StatsResult, error) {
{Name: "TotalLoginAttempts", Count: attemptsCount},
}, nil
}
func (s *PostgresStore) Query(query AttemptQuery) ([]models.LoginAttempt, error) {
var stmt string
switch query.QueryType {
case AttemptQueryTypeIP:
stmt = `SELECT id, date, remote_ip, username, password, client_version, connection_uuid, country
FROM login_attempts WHERE remote_ip = $1`
case AttemptQueryTypePassword:
stmt = `SELECT id, date, remote_ip, username, password, client_version, connection_uuid, country
FROM login_attempts WHERE password like '%$1%'`
case AttemptQueryTypeUsername:
stmt = `SELECT id, date, remote_ip, username, password, client_version, connection_uuid, country
FROM login_attempts WHERE username like '%$1%'`
default:
return nil, fmt.Errorf("Invalid query type")
}
rows, err := s.db.Query(stmt, query.Query)
if err != nil {
return nil, fmt.Errorf("Unable to query database: %w", err)
}
defer rows.Close()
var results []models.LoginAttempt
for rows.Next() {
var la models.LoginAttempt
if err := rows.Scan(&la.ID, &la.Date, &la.RemoteIP, &la.Username, &la.Password, &la.SSHClientVersion, &la.ConnectionUUID, &la.Country); err != nil {
return nil, fmt.Errorf("Unable to unmarshal data from database: %w", err)
}
results = append(results, la)
}
return results, nil
}

View File

@@ -13,13 +13,26 @@ const (
LoginStatsTotals LoginStats = "total"
)
type AttemptQueryType string
const (
AttemptQueryTypeUsername AttemptQueryType = "username"
AttemptQueryTypePassword AttemptQueryType = "password"
AttemptQueryTypeIP AttemptQueryType = "ip"
)
type StatsResult struct {
Name string `json:"name"`
Count int `json:"count"`
}
type AttemptQuery struct {
QueryType AttemptQueryType
Query string
}
type LoginAttemptStore interface {
AddAttempt(l *models.LoginAttempt) error
All() ([]models.LoginAttempt, error)
Stats(statType LoginStats, limit int) ([]StatsResult, error)
Query(query AttemptQuery) ([]models.LoginAttempt, error)
}