1// Copyright (C) 2019 Storj Labs, Inc.
2// See LICENSE for copying information.
3
4package trust
5
6import (
7	"context"
8	"os"
9
10	"github.com/zeebo/errs"
11)
12
13var (
14	// ErrFileSource is an error class for file source errors.
15	ErrFileSource = errs.Class("file source")
16)
17
18// FileSource represents a trust source contained in a file on disk.
19type FileSource struct {
20	path string
21}
22
23// NewFileSource creates a new FileSource that loads a trust list from the
24// given path.
25func NewFileSource(path string) *FileSource {
26	return &FileSource{
27		path: path,
28	}
29}
30
31// String implements the Source interface and returns the FileSource URL.
32func (source *FileSource) String() string {
33	return source.path
34}
35
36// Static implements the Source interface. It returns true.
37func (source *FileSource) Static() bool { return true }
38
39// FetchEntries implements the Source interface and returns entries from a
40// the file source on disk. The entries returned are authoritative.
41func (source *FileSource) FetchEntries(ctx context.Context) (_ []Entry, err error) {
42	urls, err := LoadSatelliteURLList(ctx, source.path)
43	if err != nil {
44		return nil, err
45	}
46
47	var entries []Entry
48	for _, url := range urls {
49		entries = append(entries, Entry{
50			SatelliteURL:  url,
51			Authoritative: true,
52		})
53	}
54	return entries, nil
55}
56
57// LoadSatelliteURLList loads a list of Satellite URLs from a path on disk.
58func LoadSatelliteURLList(ctx context.Context, path string) (_ []SatelliteURL, err error) {
59	defer mon.Task()(&ctx)(&err)
60
61	f, err := os.Open(path)
62	if err != nil {
63		return nil, ErrFileSource.Wrap(err)
64	}
65	defer func() { err = errs.Combine(err, f.Close()) }()
66
67	urls, err := ParseSatelliteURLList(ctx, f)
68	if err != nil {
69		return nil, ErrFileSource.Wrap(err)
70	}
71
72	return urls, nil
73}
74