Compare commits
	
		
			3 Commits
		
	
	
		
			v0.1.3
			...
			06dc50682c
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 06dc50682c | |||
| ccd77cdbdc | |||
| 6b43c2fd2c | 
							
								
								
									
										4
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								go.mod
									
									
									
									
									
								
							@@ -3,10 +3,11 @@ module git.t-juice.club/microfilm/users
 | 
				
			|||||||
go 1.21.3
 | 
					go 1.21.3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require (
 | 
					require (
 | 
				
			||||||
	git.t-juice.club/microfilm/auth v0.1.1
 | 
						git.t-juice.club/microfilm/auth v0.1.5
 | 
				
			||||||
	github.com/go-chi/chi/v5 v5.0.10
 | 
						github.com/go-chi/chi/v5 v5.0.10
 | 
				
			||||||
	github.com/google/uuid v1.3.1
 | 
						github.com/google/uuid v1.3.1
 | 
				
			||||||
	github.com/nats-io/nats.go v1.31.0
 | 
						github.com/nats-io/nats.go v1.31.0
 | 
				
			||||||
 | 
						github.com/nats-io/nkeys v0.4.5
 | 
				
			||||||
	github.com/pelletier/go-toml/v2 v2.1.0
 | 
						github.com/pelletier/go-toml/v2 v2.1.0
 | 
				
			||||||
	go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0
 | 
						go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.45.0
 | 
				
			||||||
	go.opentelemetry.io/otel v1.19.0
 | 
						go.opentelemetry.io/otel v1.19.0
 | 
				
			||||||
@@ -24,7 +25,6 @@ require (
 | 
				
			|||||||
	github.com/golang/protobuf v1.5.3 // indirect
 | 
						github.com/golang/protobuf v1.5.3 // indirect
 | 
				
			||||||
	github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect
 | 
						github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect
 | 
				
			||||||
	github.com/klauspost/compress v1.17.0 // indirect
 | 
						github.com/klauspost/compress v1.17.0 // indirect
 | 
				
			||||||
	github.com/nats-io/nkeys v0.4.5 // indirect
 | 
					 | 
				
			||||||
	github.com/nats-io/nuid v1.0.1 // indirect
 | 
						github.com/nats-io/nuid v1.0.1 // indirect
 | 
				
			||||||
	go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 // indirect
 | 
						go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 // indirect
 | 
				
			||||||
	go.opentelemetry.io/otel/metric v1.19.0 // indirect
 | 
						go.opentelemetry.io/otel/metric v1.19.0 // indirect
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										4
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								go.sum
									
									
									
									
									
								
							@@ -1,5 +1,5 @@
 | 
				
			|||||||
git.t-juice.club/microfilm/auth v0.1.1 h1:usg48CEd94Ha2rkEdCU+mhczJvLwwxVouOl478YdZFE=
 | 
					git.t-juice.club/microfilm/auth v0.1.5 h1:F3FZ4FDx8DLapRtDQf2jguw3ZPNw70mo6GNeLqLhWzs=
 | 
				
			||||||
git.t-juice.club/microfilm/auth v0.1.1/go.mod h1:sfgaIWxnNgERWyx611596OtEBc3cF4g3FSqKd073Te4=
 | 
					git.t-juice.club/microfilm/auth v0.1.5/go.mod h1:2ZEYgFNLSMPQO3KdlhEXzsbXLOWlPkrAsgxyZ5I68v4=
 | 
				
			||||||
github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
 | 
					github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM=
 | 
				
			||||||
github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
 | 
					github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
 | 
				
			||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
					github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,6 @@
 | 
				
			|||||||
ListenAddr = ":8080"
 | 
					ListenAddr = ":8080"
 | 
				
			||||||
NATSAddr = "nats:4222"
 | 
					[NATS]
 | 
				
			||||||
NATSSubject = "microfilm.users.v1"
 | 
					Enabled = true
 | 
				
			||||||
 | 
					Addr = "nats://nats1:4222,nats://nats2:4222,nats://nats3:4222"
 | 
				
			||||||
 | 
					NKeySeed = "SUAOUHJPINF4CK6TSNZMRR5G4DKGW5S76XRNIYURPEISNMWXJIXSVWIO7Y"
 | 
				
			||||||
 | 
					Subject = "microfilm.users.v1"
 | 
				
			||||||
@@ -8,8 +8,14 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type Config struct {
 | 
					type Config struct {
 | 
				
			||||||
	ListenAddr string      `toml:"ListenAddr"`
 | 
						ListenAddr string      `toml:"ListenAddr"`
 | 
				
			||||||
	NATSAddr    string `toml:"NATSAddr"`
 | 
						NATS       *NATSConfig `toml:"NATS"`
 | 
				
			||||||
	NATSSubject string `toml:"NATSSubject"`
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type NATSConfig struct {
 | 
				
			||||||
 | 
						Enabled  bool   `toml:"Enabled"`
 | 
				
			||||||
 | 
						NKeySeed string `toml:"NKeySeed"`
 | 
				
			||||||
 | 
						Addr     string `toml:"Addr"`
 | 
				
			||||||
 | 
						Subject  string `toml:"Subject"`
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func ConfigFromReader(r io.Reader) (*Config, error) {
 | 
					func ConfigFromReader(r io.Reader) (*Config, error) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,6 +17,7 @@ import (
 | 
				
			|||||||
	"github.com/go-chi/chi/v5"
 | 
						"github.com/go-chi/chi/v5"
 | 
				
			||||||
	"github.com/google/uuid"
 | 
						"github.com/google/uuid"
 | 
				
			||||||
	"github.com/nats-io/nats.go"
 | 
						"github.com/nats-io/nats.go"
 | 
				
			||||||
 | 
						"github.com/nats-io/nkeys"
 | 
				
			||||||
	"go.opentelemetry.io/otel"
 | 
						"go.opentelemetry.io/otel"
 | 
				
			||||||
	"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
 | 
						"go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp"
 | 
				
			||||||
	"go.opentelemetry.io/otel/propagation"
 | 
						"go.opentelemetry.io/otel/propagation"
 | 
				
			||||||
@@ -71,18 +72,37 @@ func NewServer(config *Config) (*UserServer, error) {
 | 
				
			|||||||
		Username: "admin",
 | 
							Username: "admin",
 | 
				
			||||||
		Role:     "admin",
 | 
							Role:     "admin",
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	password := uuid.Must(uuid.NewRandom()).String()
 | 
						// TODO: Use random pw
 | 
				
			||||||
 | 
						// password := uuid.Must(uuid.NewRandom()).String()
 | 
				
			||||||
 | 
						password := "admin"
 | 
				
			||||||
	_ = u.SetPassword(password)
 | 
						_ = u.SetPassword(password)
 | 
				
			||||||
	_ = srv.store.AddUser(u)
 | 
						_ = srv.store.AddUser(u)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	srv.Logger.Warn("Initial admin-user created.", "username", u.Username, "password", password)
 | 
						srv.Logger.Warn("Initial admin-user created.", "username", u.Username, "password", password)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	conn, err := nats.Connect(config.NATSAddr)
 | 
						if config.NATS.Enabled {
 | 
				
			||||||
 | 
							var opts []nats.Option
 | 
				
			||||||
 | 
							if config.NATS.NKeySeed != "" {
 | 
				
			||||||
 | 
								keys, err := nkeys.FromSeed([]byte(config.NATS.NKeySeed))
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return nil, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								pubkey, err := keys.PublicKey()
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return nil, err
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								srv.Logger.Debug("NATS enabled with NKeys", "pubkey", pubkey)
 | 
				
			||||||
 | 
								creds := nats.Nkey(pubkey, keys.Sign)
 | 
				
			||||||
 | 
								opts = append(opts, creds)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							conn, err := nats.Connect(config.NATS.Addr, opts...)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return nil, err
 | 
								return nil, err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		srv.nats = conn
 | 
							srv.nats = conn
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return srv, nil
 | 
						return srv, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -162,7 +182,7 @@ func (s *UserServer) CreateUserHandler(w http.ResponseWriter, r *http.Request) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Message
 | 
						// Message
 | 
				
			||||||
	sub := fmt.Sprintf("%s.%s", s.config.NATSSubject, "create")
 | 
						sub := fmt.Sprintf("%s.%s", s.config.NATS.Subject, "create")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var buf bytes.Buffer
 | 
						var buf bytes.Buffer
 | 
				
			||||||
	msg := &users.MsgUserCreate{
 | 
						msg := &users.MsgUserCreate{
 | 
				
			||||||
@@ -267,7 +287,7 @@ func (s *UserServer) SetPasswordHandler(w http.ResponseWriter, r *http.Request)
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	sub := fmt.Sprintf("%s.%s", s.config.NATSSubject, "update")
 | 
						sub := fmt.Sprintf("%s.%s", s.config.NATS.Subject, "update")
 | 
				
			||||||
	var buf bytes.Buffer
 | 
						var buf bytes.Buffer
 | 
				
			||||||
	encoder := json.NewEncoder(&buf)
 | 
						encoder := json.NewEncoder(&buf)
 | 
				
			||||||
	_ = encoder.Encode(&users.MsgUserUpdate{Message: "Password updated", ID: u.ID})
 | 
						_ = encoder.Encode(&users.MsgUserUpdate{Message: "Password updated", ID: u.ID})
 | 
				
			||||||
@@ -279,11 +299,15 @@ func (s *UserServer) SetPasswordHandler(w http.ResponseWriter, r *http.Request)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (s *UserServer) VerifyHandler(w http.ResponseWriter, r *http.Request) {
 | 
					func (s *UserServer) VerifyHandler(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
						_, span := otel.GetTracerProvider().Tracer("").Start(r.Context(), "Verify password")
 | 
				
			||||||
 | 
						defer span.End()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	decoder := json.NewDecoder(r.Body)
 | 
						decoder := json.NewDecoder(r.Body)
 | 
				
			||||||
	defer r.Body.Close()
 | 
						defer r.Body.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var request users.VerifyRequest
 | 
						var request users.VerifyRequest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						span.AddEvent("Start decoding request")
 | 
				
			||||||
	if err := decoder.Decode(&request); err != nil {
 | 
						if err := decoder.Decode(&request); err != nil {
 | 
				
			||||||
		WriteError(w, users.ErrorResponse{
 | 
							WriteError(w, users.ErrorResponse{
 | 
				
			||||||
			Status:  http.StatusBadRequest,
 | 
								Status:  http.StatusBadRequest,
 | 
				
			||||||
@@ -301,6 +325,7 @@ func (s *UserServer) VerifyHandler(w http.ResponseWriter, r *http.Request) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						span.AddEvent("Fetch user")
 | 
				
			||||||
	u, err := s.store.GetUser(id)
 | 
						u, err := s.store.GetUser(id)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		msg := fmt.Sprintf("Server error: %s", err)
 | 
							msg := fmt.Sprintf("Server error: %s", err)
 | 
				
			||||||
@@ -319,6 +344,7 @@ func (s *UserServer) VerifyHandler(w http.ResponseWriter, r *http.Request) {
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						span.AddEvent("Verify password")
 | 
				
			||||||
	err = u.ComparePassword(request.Password)
 | 
						err = u.ComparePassword(request.Password)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		WriteError(w, users.ErrorResponse{
 | 
							WriteError(w, users.ErrorResponse{
 | 
				
			||||||
@@ -327,5 +353,6 @@ func (s *UserServer) VerifyHandler(w http.ResponseWriter, r *http.Request) {
 | 
				
			|||||||
		})
 | 
							})
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						span.AddEvent("Write response")
 | 
				
			||||||
	w.WriteHeader(http.StatusOK)
 | 
						w.WriteHeader(http.StatusOK)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user