Add auth interceptor
This commit is contained in:
@@ -31,7 +31,7 @@ func (s *HTTPServer) FileHandler(w http.ResponseWriter, r *http.Request) {
|
||||
id := chi.URLParam(r, "id")
|
||||
f, err := s.store.GetFile(id)
|
||||
if err != nil {
|
||||
if err == store.ErrNoSuchFile {
|
||||
if err == store.ErrNoSuchItem {
|
||||
WriteErrorResponse(w, http.StatusNotFound, "file not found")
|
||||
return
|
||||
}
|
||||
|
55
server/interceptors/auth.go
Normal file
55
server/interceptors/auth.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package interceptors
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"gitea.benny.dog/torjus/ezshare/pb"
|
||||
"gitea.benny.dog/torjus/ezshare/store"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
"google.golang.org/grpc/peer"
|
||||
)
|
||||
|
||||
type ContextKey string
|
||||
|
||||
var ContextKeyRole ContextKey = "role"
|
||||
|
||||
func NewAuthInterceptor(s store.UserStore) grpc.UnaryServerInterceptor {
|
||||
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
|
||||
p, ok := peer.FromContext(ctx)
|
||||
if ok {
|
||||
tlsInfo, ok := p.AuthInfo.(credentials.TLSInfo)
|
||||
if ok {
|
||||
fmt.Printf("%+v\n", tlsInfo.State.PeerCertificates[0].Subject.CommonName)
|
||||
if len(tlsInfo.State.PeerCertificates) == 1 {
|
||||
cert := tlsInfo.State.PeerCertificates[0]
|
||||
|
||||
id := cert.Subject.CommonName
|
||||
|
||||
user, err := s.GetUser(id)
|
||||
if err == nil {
|
||||
newCtx := context.WithValue(ctx, ContextKeyRole, user.UserRole)
|
||||
return handler(newCtx, req)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
newCtx := context.WithValue(ctx, ContextKeyRole, pb.User_UNKNOWN)
|
||||
|
||||
return handler(newCtx, req)
|
||||
}
|
||||
}
|
||||
|
||||
func RoleFromContext(ctx context.Context) pb.User_Role {
|
||||
value := ctx.Value(ContextKeyRole)
|
||||
if value == nil {
|
||||
return pb.User_UNKNOWN
|
||||
}
|
||||
role, ok := value.(pb.User_Role)
|
||||
if ok {
|
||||
return role
|
||||
}
|
||||
return pb.User_UNKNOWN
|
||||
}
|
62
server/userservice.go
Normal file
62
server/userservice.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"gitea.benny.dog/torjus/ezshare/pb"
|
||||
"gitea.benny.dog/torjus/ezshare/store"
|
||||
"github.com/google/uuid"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
type GRPCUserServiceServer struct {
|
||||
store store.UserStore
|
||||
pb.UnimplementedUserServiceServer
|
||||
}
|
||||
|
||||
func NewGRPCUserServiceServer(store store.UserStore) *GRPCUserServiceServer {
|
||||
return &GRPCUserServiceServer{store: store}
|
||||
}
|
||||
func (s *GRPCUserServiceServer) Register(ctx context.Context, req *pb.RegisterUserRequest) (*pb.RegisterUserResponse, error) {
|
||||
// Check if user already exists
|
||||
if _, err := s.store.GetUserByUsername(req.Username); err != store.ErrNoSuchItem {
|
||||
return nil, fmt.Errorf("user already exists")
|
||||
}
|
||||
|
||||
pw, err := hashPassword(req.Password)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to hash password: %w", err)
|
||||
}
|
||||
user := &pb.User{
|
||||
Id: uuid.Must(uuid.NewRandom()).String(),
|
||||
Username: req.Username,
|
||||
HashedPassword: pw,
|
||||
UserRole: pb.User_USER,
|
||||
Active: true,
|
||||
}
|
||||
|
||||
if err := s.store.StoreUser(user); err != nil {
|
||||
return nil, status.Error(codes.Internal, fmt.Sprintf("unable to store user: %s", err))
|
||||
}
|
||||
|
||||
return &pb.RegisterUserResponse{Id: user.Id, Token: ""}, nil
|
||||
}
|
||||
|
||||
func (s *GRPCUserServiceServer) Login(_ context.Context, _ *pb.LoginUserRequest) (*pb.LoginUserResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "not yet implemented")
|
||||
}
|
||||
|
||||
func (s *GRPCUserServiceServer) List(_ context.Context, _ *pb.ListUsersRequest) (*pb.ListUsersResponse, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "not yet implemented")
|
||||
}
|
||||
|
||||
func (s *GRPCUserServiceServer) Approve(_ context.Context, _ *pb.ApproveUserRequest) (*pb.Empty, error) {
|
||||
return nil, status.Error(codes.Unimplemented, "not yet implemented")
|
||||
}
|
||||
|
||||
func hashPassword(password string) ([]byte, error) {
|
||||
return bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
}
|
Reference in New Issue
Block a user