lastlogin.go 1.25 KB
Newer Older
shammash's avatar
shammash committed
1 2 3 4 5 6 7 8 9
package server

import (
	"context"
	"log"
	"time"

	"git.autistici.org/ai3/go-common/clientutil"
	"git.autistici.org/id/auth"
ale's avatar
ale committed
10
	"git.autistici.org/id/auth/backend"
shammash's avatar
shammash committed
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
	"git.autistici.org/id/usermetadb"
	"git.autistici.org/id/usermetadb/client"
)

type setLastLoginClient interface {
	SetLastLogin(context.Context, string, *usermetadb.LastLoginEntry) error
}

type lastloginFilter struct {
	client setLastLoginClient
}

func newLastLoginFilter(config *clientutil.BackendConfig) (*lastloginFilter, error) {
	c, err := client.New(config)
	if err != nil {
		return nil, err
	}
	return &lastloginFilter{c}, nil
}

var lastloginTimeout = 30 * time.Second

ale's avatar
ale committed
33
func (f *lastloginFilter) Filter(user *backend.User, req *auth.Request, resp *auth.Response) *auth.Response {
shammash's avatar
shammash committed
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
	if resp.Status != auth.StatusOK {
		return resp
	}

	entry := usermetadb.LastLoginEntry{
		Timestamp: time.Now(),
		Username:  user.Name,
		Service:   req.Service,
	}

	// Make the log RPC in the background, no need to wait for it to complete.
	go func() {
		ctx, cancel := context.WithTimeout(context.Background(), lastloginTimeout)
		defer cancel()
		if err := f.client.SetLastLogin(ctx, user.Shard, &entry); err != nil {
			log.Printf("usermetadb.SetLastLogin error for %s: %v", user.Name, err)
		}
	}()

	return resp
}