Skip to content
Snippets Groups Projects
auth.go 2.72 KiB
Newer Older
  • Learn to ignore specific revisions
  • package server
    
    import (
    	"context"
    	"time"
    
    	apb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/rbac"
    	"code.fbi.h-da.de/danet/gosdn/controller/metrics"
    
    	"code.fbi.h-da.de/danet/gosdn/controller/rbac"
    
    	"code.fbi.h-da.de/danet/gosdn/controller/store"
    
    	"github.com/prometheus/client_golang/prometheus"
    
    	"google.golang.org/grpc/codes"
    	"google.golang.org/grpc/status"
    
    // Auth holds a JWTManager and represents a AuthServiceServer.
    type Auth struct {
    
    	apb.UnimplementedAuthServiceServer
    
    	jwtManager *rbac.JWTManager
    
    // NewAuthServer receives a JWTManager and returns a new Auth interface.
    func NewAuthServer(jwtManager *rbac.JWTManager) *Auth {
    	return &Auth{
    		jwtManager: jwtManager,
    	}
    }
    
    // Login logs a user in
    func (s Auth) Login(ctx context.Context, request *apb.LoginRequest) (*apb.LoginResponse, error) {
    
    	labels := prometheus.Labels{"service": "auth", "rpc": "post"}
    
    	start := metrics.StartHook(labels, grpcRequestsTotal)
    	defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds)
    
    
    		UserName: request.Username,
    
    	//TODO: add check if user is logged in with session handling
    
    
    	// validation of credentials
    	validCredentials, err := s.isValidUser(user)
    
    	if (err != nil) || !validCredentials {
    
    		return nil, err
    	}
    
    	// generate token, persist session and return to user
    	token, err := s.jwtManager.GenerateToken(user)
    	if err != nil {
    		return nil, err
    	}
    
    
    	userToUpdate, err := userc.Get(store.Query{Name: user.UserName})
    	if err != nil {
    		return nil, err
    	}
    
    	userToUpdate.SetToken(token)
    
    	err = userc.Update(userToUpdate)
    	if err != nil {
    		return nil, err
    	}
    
    
    	return &apb.LoginResponse{
    		Timestamp: time.Now().UnixNano(),
    		Status:    apb.Status_STATUS_OK,
    
    // Logout logs a user out
    func (s Auth) Logout(ctx context.Context, request *apb.LogoutRequest) (*apb.LogoutResponse, error) {
    
    	labels := prometheus.Labels{"service": "auth", "rpc": "post"}
    
    	start := metrics.StartHook(labels, grpcRequestsTotal)
    	defer metrics.FinishHook(labels, start, grpcRequestDurationSecondsTotal, grpcRequestDurationSeconds)
    
    
    	// not implemented yet
    	// TODO: add session handling and logout
    
    
    	return &apb.LogoutResponse{
    		Timestamp: time.Now().UnixNano(),
    		Status:    apb.Status_STATUS_OK,
    	}, nil
    }
    
    
    func (s Auth) isValidUser(user rbac.User) (bool, error) {
    	storedUser, err := userc.Get(store.Query{Name: user.Name()})
    	if err != nil {
    		return false, err
    	} else if storedUser == nil {
    		return false, status.Errorf(codes.Aborted, "no user object")
    	}
    
    	if storedUser.Name() == user.Name() {
    		if storedUser.GetPassword() == user.GetPassword() {
    			return true, nil
    		}
    	}
    
    	return false, status.Errorf(codes.Unauthenticated, "incorrect user name or password")