Skip to content

Commit edd2c36

Browse files
committed
finished validation logic and static module
1 parent e9142dc commit edd2c36

File tree

13 files changed

+331
-97
lines changed

13 files changed

+331
-97
lines changed

main.go

+10-18
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/spaceuptech/space-cloud/config"
1414
"github.com/spaceuptech/space-cloud/utils"
1515
"github.com/spaceuptech/space-cloud/utils/server"
16+
"github.com/spaceuptech/space-cloud/utils/validate"
1617
)
1718

1819
func main() {
@@ -48,16 +49,10 @@ func main() {
4849
Usage: "Start nats on port `NATS_PORT`",
4950
},
5051
cli.StringFlag{
51-
Name: "db",
52-
Value: "mongo",
53-
Usage: "Load space cloud config from `DB`",
54-
EnvVar: "DB",
55-
},
56-
cli.StringFlag{
57-
Name: "conn",
58-
Value: "mongodb://localhost:27017",
59-
Usage: "The connection string to connect to config db",
60-
EnvVar: "CONN",
52+
Name: "secret",
53+
Value: "none",
54+
Usage: "The secret to use for authentication",
55+
EnvVar: "SECRET",
6156
},
6257
cli.StringFlag{
6358
Name: "account",
@@ -105,8 +100,7 @@ func actionRun(c *cli.Context) error {
105100
// Load cli flags
106101
port := c.String("port")
107102
grpcPort := c.String("grpc-port")
108-
conn := c.String("conn")
109-
db := c.String("db")
103+
secret := c.String("secret")
110104
account := c.String("account")
111105
natsPort := c.Int("nats-port")
112106
clusterPort := c.Int("cluster-port")
@@ -115,7 +109,7 @@ func actionRun(c *cli.Context) error {
115109
disableNats := c.Bool("disable-nats")
116110
seeds := c.String("seeds")
117111

118-
if account == "none" {
112+
if account == "none" || secret == "none" {
119113
return errors.New("Cannot start space-cloud with no account")
120114
}
121115

@@ -144,16 +138,14 @@ func actionRun(c *cli.Context) error {
144138
fmt.Println("Started NATS server on port ", server.DefaultNatsOptions.Port)
145139
}
146140

147-
err := s.Projects().LoadConfigFromDB(account, db, conn)
148-
if err != nil {
149-
return err
150-
}
151-
152141
// Anonymously collect usage metrics if not explicitly disabled
153142
if !disableMetrics {
154143
go s.RoutineMetrics()
155144
}
156145

146+
// Start the validation process
147+
validate.New(s.GetProjects()).Start(s.GetID(), account, secret)
148+
157149
s.Routes()
158150
return s.Start(port, grpcPort)
159151
}

model/validate.go

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package model
2+
3+
// RegisterRequest is the struct which carries the space cloud register payload
4+
type RegisterRequest struct {
5+
ID string `json:"id"` // This is the space cloud id
6+
Secret string `json:"secret"`
7+
Account string `json:"account"`
8+
}
9+
10+
// RegisterResponse is the response to the register request
11+
type RegisterResponse struct {
12+
Ack bool `json:"ack"`
13+
Error string `json:"error"`
14+
}
15+
16+
// ProjectFeed is the body sent to push a project config
17+
type ProjectFeed struct {
18+
Config interface{} `json:"config"`
19+
Project string `json:"project"`
20+
}

utils/constants.go

+8
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,11 @@ const (
143143
// GRPCService for Service implementation.
144144
GRPCService RealTimeProtocol = "GRPC-Service"
145145
)
146+
147+
const (
148+
// TypeRegisterRequest is the space cloud register request
149+
TypeRegisterRequest string = "register"
150+
151+
// TypeProjectFeed is the config push event to space cloud
152+
TypeProjectFeed string = "project-feed"
153+
)

utils/handlers/static.go

+45-38
Original file line numberDiff line numberDiff line change
@@ -5,58 +5,65 @@ import (
55
"net/http"
66
"strings"
77

8-
"github.com/spaceuptech/space-cloud/modules/static"
8+
"github.com/spaceuptech/space-cloud/utils/projects"
99
)
1010

1111
// HandleStaticRequest creates a static request endpoint
12-
func HandleStaticRequest(static *static.Module) http.HandlerFunc {
12+
func HandleStaticRequest(p *projects.Projects) http.HandlerFunc {
1313
return func(w http.ResponseWriter, r *http.Request) {
1414
url := r.URL.Path
1515
host := strings.Split(r.Host, ":")[0]
1616

17-
route, ok := static.SelectRoute(host, url)
18-
if !ok {
19-
http.Error(w, "Path not found", http.StatusNotFound)
20-
return
21-
}
22-
23-
path := strings.TrimPrefix(url, route.URLPrefix)
24-
if !strings.HasPrefix(path, "/") {
25-
path = "/" + path
26-
}
27-
path = route.Path + path
28-
29-
// Its a proxy request
30-
if route.Proxy != "" {
31-
addr := route.Proxy + path
32-
req, err := http.NewRequest(r.Method, addr, r.Body)
33-
if err != nil {
34-
http.Error(w, err.Error(), http.StatusNotFound)
35-
return
17+
completed := p.Iter(func(project string, state *projects.ProjectState) bool {
18+
static := state.Static
19+
route, ok := static.SelectRoute(host, url)
20+
if !ok {
21+
return true
3622
}
3723

38-
// Set the http headers
39-
req.Header = make(http.Header)
40-
if contentType, p := r.Header["Content-Type"]; p {
41-
req.Header["Content-Type"] = contentType
24+
path := strings.TrimPrefix(url, route.URLPrefix)
25+
if !strings.HasPrefix(path, "/") {
26+
path = "/" + path
4227
}
28+
path = route.Path + path
29+
30+
// Its a proxy request
31+
if route.Proxy != "" {
32+
addr := route.Proxy + path
33+
req, err := http.NewRequest(r.Method, addr, r.Body)
34+
if err != nil {
35+
http.Error(w, err.Error(), http.StatusNotFound)
36+
return false
37+
}
4338

44-
// Make the http client request
45-
res, err := http.DefaultClient.Do(req)
46-
if err != nil {
47-
http.Error(w, err.Error(), http.StatusNotFound)
48-
return
39+
// Set the http headers
40+
req.Header = make(http.Header)
41+
if contentType, p := r.Header["Content-Type"]; p {
42+
req.Header["Content-Type"] = contentType
43+
}
44+
45+
// Make the http client request
46+
res, err := http.DefaultClient.Do(req)
47+
if err != nil {
48+
http.Error(w, err.Error(), http.StatusNotFound)
49+
return false
50+
}
51+
defer res.Body.Close()
52+
53+
reader := bufio.NewReader(res.Body)
54+
55+
w.Header().Set("Content-Type", res.Header.Get("Content-Type"))
56+
w.WriteHeader(res.StatusCode)
57+
reader.WriteTo(w)
58+
return false
4959
}
50-
defer res.Body.Close()
5160

52-
reader := bufio.NewReader(res.Body)
61+
http.ServeFile(w, r, path)
62+
return false
63+
})
5364

54-
w.Header().Set("Content-Type", res.Header.Get("Content-Type"))
55-
w.WriteHeader(res.StatusCode)
56-
reader.WriteTo(w)
57-
return
65+
if !completed {
66+
http.Error(w, "Path not found", http.StatusNotFound)
5867
}
59-
60-
http.ServeFile(w, r, path)
6168
}
6269
}

utils/projects/load.go

+2-30
Original file line numberDiff line numberDiff line change
@@ -75,40 +75,12 @@ func (p *Projects) setConfig(action, project string, data string) error {
7575
return nil
7676
}
7777

78-
// Get the project. Create if not exists
79-
state, err := p.LoadProject(project)
80-
if err != nil {
81-
state = p.NewProject(project)
82-
}
83-
8478
// Parse the config string to a type config.Project
8579
config := new(config.Project)
86-
err = json.Unmarshal([]byte(data), config)
80+
err := json.Unmarshal([]byte(data), config)
8781
if err != nil {
8882
return err
8983
}
9084

91-
// Set the configuration for the auth module
92-
state.Auth.SetConfig(config.ID, config.Secret, config.Modules.Crud, config.Modules.FileStore, config.Modules.Functions)
93-
94-
// Set the configuration for the user management module
95-
state.UserManagement.SetConfig(config.Modules.Auth)
96-
97-
// Set the configuration for the file storage module
98-
if err := state.FileStore.SetConfig(config.Modules.FileStore); err != nil {
99-
return err
100-
}
101-
102-
// Set the configuration for the functions module
103-
if err := state.Functions.SetConfig(config.Modules.Functions); err != nil {
104-
return err
105-
}
106-
107-
// Set the configuration for the Realtime module
108-
if err := state.Realtime.SetConfig(project, config.Modules.Realtime); err != nil {
109-
return err
110-
}
111-
112-
// Set the configuration for the crud module
113-
return state.Crud.SetConfig(config.Modules.Crud)
85+
return p.StoreProject(project, config)
11486
}

utils/projects/projects.go

+22-4
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,20 @@ import (
99
"github.com/spaceuptech/space-cloud/modules/filestore"
1010
"github.com/spaceuptech/space-cloud/modules/functions"
1111
"github.com/spaceuptech/space-cloud/modules/realtime"
12+
"github.com/spaceuptech/space-cloud/modules/static"
1213
"github.com/spaceuptech/space-cloud/modules/userman"
1314
)
1415

1516
// ProjectState holds the module state of a project
1617
type ProjectState struct {
18+
//Config *config.Project
1719
Auth *auth.Module
1820
Crud *crud.Module
1921
UserManagement *userman.Module
2022
FileStore *filestore.Module
21-
//Config *config.Project
22-
Functions *functions.Module
23-
Realtime *realtime.Module
23+
Static *static.Module
24+
Functions *functions.Module
25+
Realtime *realtime.Module
2426
}
2527

2628
// Projects is the stub to manage the state of the various modules
@@ -54,6 +56,21 @@ func (p *Projects) DeleteProject(project string) {
5456
delete(p.projects, project)
5557
}
5658

59+
// Iter iterates over all the projects and passes it in the provided function.
60+
// Iteration stops if the function returns false
61+
func (p *Projects) Iter(fn func(string, *ProjectState) bool) bool {
62+
p.lock.RLock()
63+
defer p.lock.RUnlock()
64+
65+
for project, state := range p.projects {
66+
if !fn(project, state) {
67+
return false
68+
}
69+
}
70+
71+
return true
72+
}
73+
5774
// NewProject creates a new project with all modules in the default state.
5875
// It will overwrite the existing project if any
5976
func (p *Projects) NewProject(project string) *ProjectState {
@@ -66,8 +83,9 @@ func (p *Projects) NewProject(project string) *ProjectState {
6683
u := userman.Init(c, a)
6784
file := filestore.Init()
6885
r := realtime.Init(c)
86+
s := static.Init()
6987

70-
state := &ProjectState{Crud: c, Functions: f, Auth: a, UserManagement: u, FileStore: file, Realtime: r}
88+
state := &ProjectState{Crud: c, Functions: f, Auth: a, UserManagement: u, FileStore: file, Realtime: r, Static: s}
7189
p.projects[project] = state
7290

7391
return state

utils/projects/store.go

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package projects
2+
3+
import "github.com/spaceuptech/space-cloud/config"
4+
5+
// StoreProject stores the provided project config
6+
func (p *Projects) StoreProject(project string, config *config.Project) error {
7+
// Get the project. Create if not exists
8+
state, err := p.LoadProject(project)
9+
if err != nil {
10+
state = p.NewProject(project)
11+
}
12+
13+
// Set the configuration for the auth module
14+
state.Auth.SetConfig(config.ID, config.Secret, config.Modules.Crud, config.Modules.FileStore, config.Modules.Functions)
15+
16+
// Set the configuration for the user management module
17+
state.UserManagement.SetConfig(config.Modules.Auth)
18+
19+
if err := state.Static.SetConfig(config.Modules.Static); err != nil {
20+
return err
21+
}
22+
23+
// Set the configuration for the file storage module
24+
if err := state.FileStore.SetConfig(config.Modules.FileStore); err != nil {
25+
return err
26+
}
27+
28+
// Set the configuration for the functions module
29+
if err := state.Functions.SetConfig(config.Modules.Functions); err != nil {
30+
return err
31+
}
32+
33+
// Set the configuration for the Realtime module
34+
if err := state.Realtime.SetConfig(project, config.Modules.Realtime); err != nil {
35+
return err
36+
}
37+
38+
// Set the configuration for the crud module
39+
return state.Crud.SetConfig(config.Modules.Crud)
40+
}

utils/server/metrics.go

+1
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ func newTransport(host, port string, sslEnabled bool) (*transport, error) {
8080
return &transport{conn, stub}, nil
8181
}
8282

83+
// RoutineMetrics collects some metrics from SC
8384
func (s *Server) RoutineMetrics() {
8485
// TODO
8586
// ticker := time.NewTicker(time.Minute * 5)

utils/server/nats.go

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
nats "github.com/nats-io/nats-server/server"
88
)
99

10+
// DefaultNatsOptions are the default options to be used
1011
var DefaultNatsOptions = &nats.Options{
1112
Host: "0.0.0.0",
1213
Port: 4222,
@@ -18,6 +19,7 @@ var DefaultNatsOptions = &nats.Options{
1819
},
1920
}
2021

22+
// RunNatsServer starts the nats server in a separate goroutine
2123
func (s *Server) RunNatsServer(opts *nats.Options) {
2224
s.nats = nats.New(opts)
2325
go s.nats.Start()

utils/server/routes.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"github.com/spaceuptech/space-cloud/utils/handlers"
55
)
66

7+
// Routes initialises the http endpoints
78
func (s *Server) Routes() {
89
// Initialize the routes for config management
910
//s.router.Methods("POST").Path("/v1/api/config").HandlerFunc(config.HandleConfig(s.isProd, s.loadConfig))
@@ -38,5 +39,5 @@ func (s *Server) Routes() {
3839
s.router.Methods("DELETE").PathPrefix("/v1/api/{project}/files").HandlerFunc(handlers.HandleDelete(s.projects))
3940

4041
// Initialize the route for handling static files
41-
s.router.PathPrefix("/").HandlerFunc(handlers.HandleStaticRequest(s.static))
42+
s.router.PathPrefix("/").HandlerFunc(handlers.HandleStaticRequest(s.projects))
4243
}

0 commit comments

Comments
 (0)