Newer
Older
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)
Password: request.Pwd,
}
//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")