update: better CSS border colors

This commit is contained in:
ngn 2024-08-13 22:25:36 +03:00
parent b24a970962
commit 4641faefc2
21 changed files with 873 additions and 445 deletions

2
.gitignore vendored
View File

@ -1,2 +1,4 @@
docker-compose.yml
compose.yml
security
db/

9
Makefile Normal file
View File

@ -0,0 +1,9 @@
all: security
security: */*.go *.go
go build -o $@
format:
gofmt -s -w .
.PHONY: format

View File

@ -1,12 +1,26 @@
# security | MatterLinux Security Tracker
# security | MatterLinux security tracker
Soruce code of MatterLinux's security tracker, located at
[security.matterlinux.xyz](https://security.matterlinux.xyz)
### Deployment
Web server can be built and deployed with docker:
Web server can be built and deployed with docker compose, here is an
example configuration:
```yaml
version: "3"
services:
security:
image: mattersecurity
restart: unless-stopped
build:
context: ./
ports:
- "127.0.0.1:9876:9876"
volumes:
- "./db:/app/db"
```
After saving the configuration file, you can build and run the docker container:
```bash
docker build --tag mattersecurity .
mkdir -pv db
docker-compose up -d
```

View File

@ -1,12 +0,0 @@
version: "3"
services:
security:
image: mattersecurity
restart: unless-stopped
build:
context: ./
ports:
- "127.0.0.1:9876:9876"
volumes:
- "./db:/app/db"

View File

@ -64,5 +64,3 @@ func LoadDatabase() error {
return nil
}

33
lib/lib/config.go Normal file
View File

@ -0,0 +1,33 @@
package lib
import (
"encoding/json"
"os"
)
type Config struct {
Pools []Pool `json:"pools"`
}
func (c *Config) Load(list *[]Package, file string) error {
var (
content []byte
err error
)
if content, err = os.ReadFile(file); err != nil {
return err
}
if err = json.Unmarshal(content, c); err != nil {
return err
}
for _, p := range c.Pools {
if err = p.Load(list); err != nil {
return err
}
}
return nil
}

135
lib/lib/package.go Normal file
View File

@ -0,0 +1,135 @@
package lib
import (
"archive/tar"
"bufio"
"compress/gzip"
"fmt"
"io"
"net/url"
"os"
"path"
"strings"
"git.matterlinux.xyz/matter/tracker/log"
"github.com/bigkevmcd/go-configparser"
)
type Package struct {
Name string `json:"name"`
Pool *Pool `json:"-"`
Version string `json:"version"`
Depends []string `json:"depends"`
Size string `json:"size"`
Desc string `json:"desc"`
Archive string `json:"archive"`
}
func (p *Package) Files() []string {
var (
gzip_reader io.Reader
header *tar.Header
result []string
file *os.File
err error
)
if file, err = os.Open(p.Archive); err != nil {
log.Error("Failed to open %s", p.Archive)
return result
}
defer file.Close()
if gzip_reader, err = gzip.NewReader(bufio.NewReader(file)); err != nil {
log.Error("Failed to create reader for %s", p.Archive)
return result
}
reader := tar.NewReader(gzip_reader)
for header, err = reader.Next(); err == nil; header, err = reader.Next() {
if header.Typeflag != tar.TypeReg {
continue
}
if path.Base(header.Name) != "files.tar.gz" {
continue
}
if result, err = GetFiles(reader); err == nil {
break
}
log.Error("Failed to get file list for %s: %s", p.Archive, err.Error())
return []string{}
}
return result
}
func (p *Package) URL() string {
if nil == p.Pool {
return ""
}
url, _ := url.JoinPath(p.Pool.Source, "src/branch/"+p.Pool.Branch+"/src", p.Name)
return url
}
func (p *Package) DependsToStr() string {
var depends string = ""
for _, d := range p.Depends {
depends += fmt.Sprintf("%s ", d)
}
return depends
}
func (p *Package) Load(r io.Reader) error {
var (
err error
size int64
depends string = ""
section string = "DEFAULT"
)
parser := configparser.New()
if err = parser.ParseReader(r); err != nil {
return err
}
for _, s := range parser.Sections() {
if s == "DEFAULT" {
continue
}
section = s
break
}
if section == "DEFAULT" {
return fmt.Errorf("DATA does not contain any sections")
}
p.Name = section
if p.Version, err = parser.Get(section, "version"); err != nil {
return err
}
if size, err = parser.GetInt64(section, "size"); err != nil {
return err
}
p.Size = SizeFromBytes(size)
if p.Desc, err = parser.Get(section, "desc"); err != nil {
return err
}
depends, _ = parser.Get(section, "depends")
if depends == "" {
p.Depends = []string{}
} else {
p.Depends = strings.Split(depends, ",")
}
return nil
}

145
lib/lib/pool.go Normal file
View File

@ -0,0 +1,145 @@
package lib
import (
"archive/tar"
"bufio"
"compress/gzip"
"fmt"
"io"
"os"
"path"
"github.com/bigkevmcd/go-configparser"
)
type Pool struct {
Maintainer string `json:"-"`
Pubkey string `json:"-"`
Size string `json:"-"`
Display string `json:"display"`
Branch string `json:"branch"`
Source string `json:"source"`
Name string `json:"name"`
URL string `json:"url"`
Dir string `json:"dir"`
}
func (p *Pool) Load(list *[]Package) error {
var err error
if p.Dir == "" {
return fmt.Errorf("pool directory is not specified")
}
if err = p.LoadInfo(); err != nil {
return err
}
if err = p.LoadList(list); err != nil {
return err
}
return nil
}
func (p *Pool) LoadList(list *[]Package) error {
var (
list_path string
list_file *os.File
gzip_reader io.Reader
header *tar.Header
err error
)
list_path = path.Join(p.Dir, "LIST")
if list_file, err = os.Open(list_path); err != nil {
return err
}
defer list_file.Close()
if gzip_reader, err = gzip.NewReader(bufio.NewReader(list_file)); err != nil {
return err
}
reader := tar.NewReader(gzip_reader)
for header, err = reader.Next(); err == nil; header, err = reader.Next() {
if header.Typeflag != tar.TypeReg {
continue
}
if path.Base(header.Name) != "DATA" {
return fmt.Errorf("LIST archive contains an unknown file")
}
var pkg Package
if err = pkg.Load(reader); err != nil {
return err
}
pkg.Archive = path.Join(p.Dir, fmt.Sprintf("%s_%s.mpf", pkg.Name, pkg.Version))
pkg.Pool = p
*list = append(*list, pkg)
}
return nil
}
func (p *Pool) LoadInfo() error {
var (
info_path string
info_file *os.File
section string
size int64
err error
)
info_path = path.Join(p.Dir, "INFO")
if info_file, err = os.Open(info_path); err != nil {
return err
}
parser := configparser.New()
if err = parser.ParseReader(bufio.NewReader(info_file)); err != nil {
return err
}
section = "DEFAULT"
for _, s := range parser.Sections() {
if s == "DEFAULT" {
continue
}
section = s
break
}
if section == "DEFAULT" {
return fmt.Errorf("DATA does not contain any sections")
}
if p.Name != section {
return fmt.Errorf("pool name (\"%s\") doesn't match with \"%s\"", p.Name, section)
}
if p.Maintainer, err = parser.Get(p.Name, "maintainer"); err != nil {
return err
}
if size, err = parser.GetInt64(section, "size"); err != nil {
return err
}
p.Size = SizeFromBytes(size)
if p.Pubkey, err = parser.Get(section, "pubkey"); err != nil {
return err
}
return nil
}

104
lib/lib/util.go Normal file
View File

@ -0,0 +1,104 @@
package lib
import (
"archive/tar"
"compress/gzip"
"fmt"
"io"
"strings"
"time"
"github.com/gofiber/fiber/v2"
)
func GetFiles(r io.Reader) ([]string, error) {
var (
gzip_reader io.Reader
header *tar.Header
result []string
err error
)
if gzip_reader, err = gzip.NewReader(r); err != nil {
return result, err
}
reader := tar.NewReader(gzip_reader)
for header, err = reader.Next(); err == nil; header, err = reader.Next() {
if header.Typeflag != tar.TypeReg {
continue
}
result = append(result, header.Name)
}
return result, nil
}
func ListToStr(l []string) string {
res := ""
for _, e := range l {
res += e + " "
}
return res
}
func RenderError(c *fiber.Ctx, code int) error {
var msg string = "Server Error"
c.Status(code)
switch code {
case 404:
msg = "Not Found"
}
return c.Render("error", fiber.Map{
"msg": msg,
})
}
func SizeFromBytes(size int64) string {
if size > 1024*1024*1024 {
return fmt.Sprintf("%dGB", (size / 1024 / 1024 / 1024))
} else if size > 1024*1024 {
return fmt.Sprintf("%dMB", (size / 1024 / 1024))
} else if size > 1024 {
return fmt.Sprintf("%dKB", (size / 1024))
}
return fmt.Sprintf("%dB", size)
}
func TimePassed(t time.Time) string {
diff := time.Since(t)
res := fmt.Sprintf(
"%ds ago",
int(diff.Seconds()),
)
if diff.Minutes() > 1 {
res = fmt.Sprintf(
"%dm and %ds ago",
int(diff.Minutes()), int(diff.Seconds())-(int(diff.Minutes())*60),
)
}
if diff.Hours() > 1 {
res = fmt.Sprintf("%dh and %dm ago",
int(diff.Hours()),
int(diff.Minutes())-(int(diff.Hours())*60),
)
}
return res
}
func SanitizeXSS(s string) string {
var bad []string = []string{"~", "'", "\"", "/", "<", ">", "?", "=", "#", "(", ")", "{", "}", "*", "!", "`", "[", "]"}
for _, c := range bad {
s = strings.ReplaceAll(s, c, "")
}
return s
}

View File

@ -1,7 +1,7 @@
.vuln {
padding: 30px;
background: var(--dark-second);
border: solid 1px var(--bright-main);
border: solid 1px var(--bright-second);
color: var(--bright-second);
}
@ -113,7 +113,7 @@
gap: 10px;
background: var(--dark-second);
border: solid 1px var(--bright-main);
border: solid 1px var(--bright-second);
}
.search-header {

View File

@ -1,7 +1,7 @@
form {
background: var(--dark-second);
padding: 30px;
border: solid 1px var(--bright-main);
border: solid 1px var(--bright-second);
display: flex;
flex-direction: column;

View File

@ -3,7 +3,7 @@ main a {
flex-direction: column;
font-size: 15px;
color: var(--bright-main);
color: var(--bright-second);
text-align: right;
margin-bottom: 10px;
}
@ -15,7 +15,7 @@ main a:hover {
form {
background: var(--dark-second);
padding: 30px;
border: solid 1px var(--bright-main);
border: solid 1px var(--bright-second);
display: flex;
flex-direction: column;