mirror of
https://github.com/empayre/fleet.git
synced 2024-11-06 08:55:24 +00:00
885db1a597
This PR refactors most of the codebase to use the new config patterns implemented in #149. Now the core service keeps a copy of the KolideConfig struct, and service methods can reference the configuration in that struct when they need it. The most significant refactoring is in the sessions code, separating the business logic from the storage layer.
164 lines
3.6 KiB
Go
164 lines
3.6 KiB
Go
package server
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"encoding/base64"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/kolide/kolide-ose/datastore"
|
|
"github.com/kolide/kolide-ose/kolide"
|
|
"golang.org/x/net/context"
|
|
)
|
|
|
|
func (svc service) Login(ctx context.Context, username, password string) (*kolide.User, string, error) {
|
|
user, err := svc.ds.User(username)
|
|
switch err {
|
|
case nil:
|
|
case datastore.ErrNotFound:
|
|
return nil, "", authError{
|
|
message: fmt.Sprintf("user %s not found", username),
|
|
}
|
|
default:
|
|
return nil, "", err
|
|
}
|
|
if !user.Enabled {
|
|
return nil, "", authError{
|
|
message: fmt.Sprintf("account disabled %s", username),
|
|
}
|
|
}
|
|
if err := user.ValidatePassword(password); err != nil {
|
|
return nil, "", authError{
|
|
message: fmt.Sprintf("invalid password for user %s", username),
|
|
}
|
|
}
|
|
|
|
token, err := svc.makeSession(user.ID)
|
|
if err != nil {
|
|
return nil, "", err
|
|
}
|
|
|
|
return user, token, nil
|
|
}
|
|
|
|
// makeSession is a helper that creates a new session after authentication
|
|
func (svc service) makeSession(id uint) (string, error) {
|
|
sessionKeySize := svc.config.Session.KeySize
|
|
key := make([]byte, sessionKeySize)
|
|
_, err := rand.Read(key)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
session := &kolide.Session{
|
|
UserID: id,
|
|
Key: base64.StdEncoding.EncodeToString(key),
|
|
}
|
|
|
|
session, err = svc.ds.NewSession(session)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
tokenString, err := kolide.GenerateJWT(session.Key, svc.config.Auth.JwtKey)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return tokenString, nil
|
|
}
|
|
|
|
func (svc service) Logout(ctx context.Context) error {
|
|
// this should not return an error if the user wasn't logged in
|
|
return svc.DestroySession(ctx)
|
|
}
|
|
|
|
func (svc service) DestroySession(ctx context.Context) error {
|
|
vc, err := viewerContextFromContext(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
session, err := svc.ds.FindSessionByID(vc.SessionID())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return svc.ds.DestroySession(session)
|
|
}
|
|
|
|
func (svc service) GetInfoAboutSessionsForUser(ctx context.Context, id uint) ([]*kolide.Session, error) {
|
|
var validatedSessions []*kolide.Session
|
|
|
|
sessions, err := svc.ds.FindAllSessionsForUser(id)
|
|
if err != nil {
|
|
return validatedSessions, err
|
|
}
|
|
|
|
for _, session := range sessions {
|
|
if svc.validateSession(session) == nil {
|
|
validatedSessions = append(validatedSessions, session)
|
|
}
|
|
}
|
|
|
|
return validatedSessions, nil
|
|
}
|
|
|
|
func (svc service) DeleteSessionsForUser(ctx context.Context, id uint) error {
|
|
return svc.ds.DestroyAllSessionsForUser(id)
|
|
}
|
|
|
|
func (svc service) GetInfoAboutSession(ctx context.Context, id uint) (*kolide.Session, error) {
|
|
session, err := svc.ds.FindSessionByID(id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
err = svc.validateSession(session)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return session, nil
|
|
}
|
|
|
|
func (svc service) GetSessionByKey(ctx context.Context, key string) (*kolide.Session, error) {
|
|
session, err := svc.ds.FindSessionByKey(key)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
err = svc.validateSession(session)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return session, nil
|
|
}
|
|
|
|
func (svc service) DeleteSession(ctx context.Context, id uint) error {
|
|
session, err := svc.ds.FindSessionByID(id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return svc.ds.DestroySession(session)
|
|
}
|
|
|
|
func (svc service) validateSession(session *kolide.Session) error {
|
|
if session == nil {
|
|
return kolide.ErrNoActiveSession
|
|
}
|
|
|
|
sessionDuration := svc.config.Session.Duration
|
|
// duration 0 = unlimited
|
|
if sessionDuration != 0 && time.Since(session.AccessedAt) >= sessionDuration {
|
|
err := svc.ds.DestroySession(session)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return kolide.ErrSessionExpired
|
|
}
|
|
|
|
return svc.ds.MarkSessionAccessed(session)
|
|
}
|