github.com/quickfeed/quickfeed@v0.0.0-20240507093252-ed8ca812a09c/web/interceptor/tokens_test.go (about)

     1  package interceptor_test
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  	"time"
     7  
     8  	"connectrpc.com/connect"
     9  	"github.com/golang-jwt/jwt"
    10  	"github.com/quickfeed/quickfeed/internal/qtest"
    11  	"github.com/quickfeed/quickfeed/qf"
    12  	"github.com/quickfeed/quickfeed/web"
    13  	"github.com/quickfeed/quickfeed/web/auth"
    14  	"github.com/quickfeed/quickfeed/web/interceptor"
    15  )
    16  
    17  func TestRefreshTokens(t *testing.T) {
    18  	db, cleanup := qtest.TestDB(t)
    19  	defer cleanup()
    20  	logger := qtest.Logger(t)
    21  
    22  	tm, err := auth.NewTokenManager(db)
    23  	if err != nil {
    24  		t.Fatal(err)
    25  	}
    26  	client := web.MockClient(t, db, connect.WithInterceptors(
    27  		interceptor.NewUserInterceptor(logger, tm),
    28  		interceptor.NewTokenInterceptor(tm),
    29  	))
    30  	ctx := context.Background()
    31  
    32  	f := func(t *testing.T, id uint64) string {
    33  		cookie, err := tm.NewAuthCookie(id)
    34  		if err != nil {
    35  			t.Fatal(err)
    36  		}
    37  		return cookie.String()
    38  	}
    39  
    40  	admin := qtest.CreateFakeCustomUser(t, db, &qf.User{Name: "admin", Login: "admin"})
    41  	user := qtest.CreateFakeUser(t, db)
    42  	adminCookie := f(t, admin.ID)
    43  	userCookie := f(t, user.ID)
    44  	adminClaims := &auth.Claims{
    45  		UserID: admin.ID,
    46  		Admin:  true,
    47  		StandardClaims: jwt.StandardClaims{
    48  			ExpiresAt: time.Now().Add(1 * time.Minute).Unix(),
    49  		},
    50  	}
    51  	userClaims := &auth.Claims{
    52  		UserID: user.ID,
    53  		StandardClaims: jwt.StandardClaims{
    54  			ExpiresAt: time.Now().Add(1 * time.Minute).Unix(),
    55  		},
    56  	}
    57  	if updateRequired(t, tm, userClaims) || updateRequired(t, tm, adminClaims) {
    58  		t.Error("No users should be in the token update list at the start")
    59  	}
    60  	if _, err := client.GetUsers(ctx, qtest.RequestWithCookie(&qf.Void{}, adminCookie)); err != nil {
    61  		t.Fatal(err)
    62  	}
    63  	if updateRequired(t, tm, adminClaims) || updateRequired(t, tm, userClaims) {
    64  		t.Error("No users should be in the token update list")
    65  	}
    66  	if _, err := client.UpdateUser(ctx, qtest.RequestWithCookie(user, adminCookie)); err != nil {
    67  		t.Fatal(err)
    68  	}
    69  	if !updateRequired(t, tm, userClaims) {
    70  		t.Error("User must be in the token update list after admin has updated the user's information")
    71  	}
    72  	if _, err := client.GetUser(ctx, qtest.RequestWithCookie(&qf.Void{}, userCookie)); err != nil {
    73  		t.Fatal(err)
    74  	}
    75  	if updateRequired(t, tm, userClaims) {
    76  		t.Error("User should not be in the token update list after the token has been updated")
    77  	}
    78  	course := &qf.Course{
    79  		ID:                  1,
    80  		ScmOrganizationID:   1,
    81  		ScmOrganizationName: qtest.MockOrg,
    82  	}
    83  	group := &qf.Group{
    84  		ID:       1,
    85  		Name:     "test",
    86  		CourseID: 1,
    87  		Users: []*qf.User{
    88  			user,
    89  		},
    90  	}
    91  	if _, err := client.CreateCourse(ctx, qtest.RequestWithCookie(course, adminCookie)); err != nil {
    92  		t.Fatal(err)
    93  	}
    94  	if !updateRequired(t, tm, adminClaims) {
    95  		t.Error("Admin must be in the token update list after creating a new course")
    96  	}
    97  	qtest.EnrollStudent(t, db, user, course)
    98  	if _, err := client.CreateGroup(ctx, qtest.RequestWithCookie(group, adminCookie)); err != nil {
    99  		t.Fatal(err)
   100  	}
   101  	if updateRequired(t, tm, userClaims) {
   102  		t.Error("User should not be in the token update list after methods that don't affect the user's information")
   103  	}
   104  	if _, err := client.UpdateGroup(ctx, qtest.RequestWithCookie(group, adminCookie)); err != nil {
   105  		t.Fatal(err)
   106  	}
   107  	if !updateRequired(t, tm, userClaims) {
   108  		t.Error("User must be in the token update group after changes to the group")
   109  	}
   110  	if _, err := client.GetUser(ctx, qtest.RequestWithCookie(&qf.Void{}, userCookie)); err != nil {
   111  		t.Fatal(err)
   112  	}
   113  	if updateRequired(t, tm, userClaims) {
   114  		t.Error("User should be removed from the token update list after the user's token has been updated")
   115  	}
   116  	if _, err := client.DeleteGroup(ctx, qtest.RequestWithCookie(&qf.GroupRequest{
   117  		GroupID:  group.ID,
   118  		CourseID: course.ID,
   119  	}, adminCookie)); err != nil {
   120  		t.Fatal(err)
   121  	}
   122  	if !updateRequired(t, tm, userClaims) {
   123  		t.Error("User must be in the token update list after the group has been deleted")
   124  	}
   125  	if updateRequired(t, tm, adminClaims) {
   126  		t.Error("Admin should not be in the token update list")
   127  	}
   128  }
   129  
   130  func updateRequired(t *testing.T, tm *auth.TokenManager, claims *auth.Claims) bool {
   131  	t.Helper()
   132  	updated, err := tm.UpdateCookie(claims)
   133  	if err != nil {
   134  		t.Error(err)
   135  	}
   136  	return updated != nil
   137  }