Skip to content

Commit ea96265

Browse files
authored
feat(iam): Users, orgs, policy groups (#29)
1 parent 00c55ef commit ea96265

26 files changed

+2577
-784
lines changed

.golangci.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ linters:
2424
extra-words:
2525
- typo: "platfrom"
2626
correction: "platform"
27+
- typo: "organisaion"
28+
correction: "organisation"
29+
- type: "organasiation"
30+
correction: "organisation"
31+
- typo: "organisaiton"
32+
correction: "organisation"
33+
- typo: "organization"
34+
correction: "organisation"
2735
wsl_v5:
2836
default: all
2937
allow-whole-block: true

Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,8 @@ gen.proto.openapi: install.protoc
136136

137137
# --- LOCAL RUNNING TARGETS --------------------------------------------------------------------- #
138138

139-
.PHONY: run # Run the Data Platform GRPC API
139+
.PHONY: run # Run the Data Platform GRPC API.
140+
# Set DATABASE_URL="postgresql://postgres:postgres@localhost:5400/postgres" in env to connect to instance spawned with `make run.db`
140141
run:
141142
DATABASE_URL=${DATABASE_URL} LOGLEVEL=DEBUG go run cmd/main.go
142143

cmd/main.go

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,53 @@ func main() {
3030

3131
zerolog.SetGlobalLevel(logLevel)
3232

33+
// Open a listener on port 50051
34+
lis, err := net.Listen("tcp", ":50051")
35+
if err != nil {
36+
log.Fatal().Err(err).Msg("net.Listen({tcp: 500051})")
37+
}
38+
39+
// Create a validator to use with protovalidate interceptor
40+
validator, err := protovalidate.New()
41+
if err != nil {
42+
log.Fatal().Err(err).Msg("Failed to create validator")
43+
}
44+
3345
// Choose the server implementation based on the environment
3446
databaseUrl := os.Getenv("DATABASE_URL")
3547

36-
var dpServerImpl pb.DataPlatformServiceServer
48+
var (
49+
dataServerImpl pb.DataPlatformDataServiceServer
50+
adminServerImpl pb.DataPlatformAdministrationServiceServer
51+
s *grpc.Server
52+
)
3753

3854
if slices.Contains([]string{"", "dummy", "fake"}, strings.ToLower(databaseUrl)) {
3955
log.Warn().Msg("Running in test mode with fake data. Not for production use")
4056

41-
dpServerImpl = dbdy.NewDummyDataPlatformServerImpl()
57+
dataServerImpl = dbdy.NewDataPlatformDataServerImpl()
58+
adminServerImpl = dbdy.NewDataPlatformAdministrationServiceServerImpl()
59+
60+
// For a dummy-backed server, just validate requests
61+
s = grpc.NewServer(
62+
grpc.ChainUnaryInterceptor(
63+
grpc.UnaryServerInterceptor(middleware.UnaryServerInterceptor(validator)),
64+
),
65+
)
4266
} else if strings.HasPrefix(databaseUrl, "postgres") && strings.Contains(databaseUrl, "://") {
4367
log.Info().Str("type", "postgresql").Msg("Connecting to database backend")
4468

45-
dpServerImpl = dbpg.NewPostgresDataPlatformServerImpl(databaseUrl)
69+
txInjector := dbpg.NewTransactionInjector(databaseUrl)
70+
dataServerImpl = dbpg.NewDataPlatformDataServiceServerImpl()
71+
adminServerImpl = dbpg.NewDataPlatformAdministrationServiceServerImpl()
72+
73+
// For a postgres-backed server, validate requests and manage database transactions
74+
s = grpc.NewServer(
75+
grpc.ChainUnaryInterceptor(
76+
grpc.UnaryServerInterceptor(middleware.UnaryServerInterceptor(validator)),
77+
grpc.UnaryServerInterceptor(txInjector.UnaryServerInterceptor),
78+
),
79+
)
4680
} else {
4781
log.Fatal().Str("url", databaseUrl).Msg("Unsupported DATABASE_URL format")
4882
}
@@ -51,23 +85,11 @@ func main() {
5185
// * Add an interceptor for request validation
5286
log.Info().Int("port", 50051).Msg("Starting GRPC server")
5387

54-
lis, err := net.Listen("tcp", ":50051")
55-
if err != nil {
56-
log.Fatal().Err(err).Msg("Failed to listen")
57-
}
58-
59-
validator, err := protovalidate.New()
60-
if err != nil {
61-
log.Fatal().Err(err).Msg("Failed to create validator")
62-
}
63-
64-
s := grpc.NewServer(
65-
grpc.UnaryInterceptor(middleware.UnaryServerInterceptor(validator)),
66-
)
67-
pb.RegisterDataPlatformServiceServer(s, dpServerImpl)
88+
pb.RegisterDataPlatformDataServiceServer(s, dataServerImpl)
89+
pb.RegisterDataPlatformAdministrationServiceServer(s, adminServerImpl)
6890
grpc_health_v1.RegisterHealthServer(s, health.NewServer())
6991
reflection.Register(s)
70-
log.Info().Msg("Listening on :50051")
7192

93+
log.Info().Msg("Listening on :50051")
7294
_ = s.Serve(lis) // If this errors, we want it to panic! It's fundamental
7395
}
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
// Package postgres defines a server implementation for the DataPlatformServiceServer.
2+
// This implementation is backed by a PostgreSQL database.
3+
//
4+
// Functions and structs for connecting to the database are generated from SQL using
5+
// the sqlc library, whilst the Server interface that is being implemented comes from
6+
// the top-level proto definitions.
7+
package dummy
8+
9+
import (
10+
"context"
11+
12+
"github.com/google/uuid"
13+
14+
pb "github.com/openclimatefix/data-platform/internal/gen/ocf/dp"
15+
)
16+
17+
// --- Server Implementation ----------------------------------------------------------------------
18+
19+
func NewDataPlatformAdministrationServiceServerImpl() *DataPlatformAdministrationServiceServerImpl {
20+
return &DataPlatformAdministrationServiceServerImpl{}
21+
}
22+
23+
type DataPlatformAdministrationServiceServerImpl struct{}
24+
25+
func (d *DataPlatformAdministrationServiceServerImpl) CreateLocationPolicyGroup(
26+
ctx context.Context,
27+
req *pb.CreateLocationPolicyGroupRequest,
28+
) (*pb.CreateLocationPolicyGroupResponse, error) {
29+
return &pb.CreateLocationPolicyGroupResponse{
30+
LocationPolicyGroupId: uuid.New().String(),
31+
Name: req.Name,
32+
}, nil
33+
}
34+
35+
// CreateOrganisation implements dp.DataPlatformAdministrationServiceServer.
36+
func (d *DataPlatformAdministrationServiceServerImpl) CreateOrganisation(
37+
ctx context.Context,
38+
req *pb.CreateOrganisationRequest,
39+
) (*pb.CreateOrganisationResponse, error) {
40+
return &pb.CreateOrganisationResponse{
41+
OrgId: uuid.New().String(),
42+
OrgName: req.OrgName,
43+
}, nil
44+
}
45+
46+
// CreateUser implements dp.DataPlatformAdministrationServiceServer.
47+
func (d *DataPlatformAdministrationServiceServerImpl) CreateUser(
48+
context.Context,
49+
*pb.CreateUserRequest,
50+
) (*pb.CreateUserResponse, error) {
51+
return &pb.CreateUserResponse{
52+
UserId: uuid.New().String(),
53+
}, nil
54+
}
55+
56+
// DeleteLocationPolicyGroup implements dp.DataPlatformAdministrationServiceServer.
57+
func (d *DataPlatformAdministrationServiceServerImpl) DeleteLocationPolicyGroup(
58+
context.Context,
59+
*pb.DeleteLocationPolicyGroupRequest,
60+
) (*pb.DeleteLocationPolicyGroupResponse, error) {
61+
return &pb.DeleteLocationPolicyGroupResponse{}, nil
62+
}
63+
64+
// DeleteOrganisation implements dp.DataPlatformAdministrationServiceServer.
65+
func (d *DataPlatformAdministrationServiceServerImpl) DeleteOrganisation(
66+
context.Context,
67+
*pb.DeleteOrganisationRequest,
68+
) (*pb.DeleteOrganisationResponse, error) {
69+
return &pb.DeleteOrganisationResponse{}, nil
70+
}
71+
72+
// DeleteUser implements dp.DataPlatformAdministrationServiceServer.
73+
func (d *DataPlatformAdministrationServiceServerImpl) DeleteUser(
74+
context.Context,
75+
*pb.DeleteUserRequest,
76+
) (*pb.DeleteUserResponse, error) {
77+
return &pb.DeleteUserResponse{}, nil
78+
}
79+
80+
// GetLocationPolicyGroup implements dp.DataPlatformAdministrationServiceServer.
81+
func (d *DataPlatformAdministrationServiceServerImpl) GetLocationPolicyGroup(
82+
context.Context,
83+
*pb.GetLocationPolicyGroupRequest,
84+
) (*pb.GetLocationPolicyGroupResponse, error) {
85+
panic("unimplemented")
86+
}
87+
88+
// GetOrganisation implements dp.DataPlatformAdministrationServiceServer.
89+
func (d *DataPlatformAdministrationServiceServerImpl) GetOrganisation(
90+
context.Context,
91+
*pb.GetOrganisationRequest,
92+
) (*pb.GetOrganisationResponse, error) {
93+
panic("unimplemented")
94+
}
95+
96+
// GetUser implements dp.DataPlatformAdministrationServiceServer.
97+
func (d *DataPlatformAdministrationServiceServerImpl) GetUser(
98+
context.Context,
99+
*pb.GetUserRequest,
100+
) (*pb.GetUserResponse, error) {
101+
panic("unimplemented")
102+
}
103+
104+
// UpdateLocationPolicyGroup implements dp.DataPlatformAdministrationServiceServer.
105+
func (d *DataPlatformAdministrationServiceServerImpl) UpdateLocationPolicyGroup(
106+
context.Context,
107+
*pb.UpdateLocationPolicyGroupRequest,
108+
) (*pb.UpdateLocationPolicyGroupResponse, error) {
109+
panic("unimplemented")
110+
}
111+
112+
// UpdateOrganisation implements dp.DataPlatformAdministrationServiceServer.
113+
func (d *DataPlatformAdministrationServiceServerImpl) UpdateOrganisation(
114+
context.Context,
115+
*pb.UpdateOrganisationRequest,
116+
) (*pb.UpdateOrganisationResponse, error) {
117+
panic("unimplemented")
118+
}
119+
120+
// Compile-time check to ensure the interface is implemented fully.
121+
var _ pb.DataPlatformAdministrationServiceServer = (*DataPlatformAdministrationServiceServerImpl)(
122+
nil,
123+
)

0 commit comments

Comments
 (0)