3
0

Removed session memstore, mocked it in tests

Updated mocked notification service
This commit is contained in:
Peter Grlica
2021-03-12 09:19:27 +01:00
parent 4a08f08f84
commit f96211b8c6
18 changed files with 113 additions and 437 deletions
+9 -12
View File
@@ -10,15 +10,13 @@ import (
"github.com/cortezaproject/corteza-server/auth/settings"
"github.com/cortezaproject/corteza-server/system/service"
"github.com/cortezaproject/corteza-server/system/types"
"github.com/quasoft/memstore"
"github.com/stretchr/testify/require"
)
func Test_changePasswordForm_setValues(t *testing.T) {
var (
ctx = context.Background()
memStore = memstore.NewMemStore()
user = makeMockUser(ctx)
ctx = context.Background()
user = makeMockUser(ctx)
req = &http.Request{}
@@ -34,8 +32,8 @@ func Test_changePasswordForm_setValues(t *testing.T) {
authSettings := &settings.Settings{}
authService = prepareClientAuthService(ctx, user, memStore)
authReq = prepareClientAuthReq(ctx, req, user, memStore)
authService = prepareClientAuthService(ctx, user)
authReq = prepareClientAuthReq(ctx, req, user)
authHandlers = prepareClientAuthHandlers(ctx, authService, authSettings)
payload := map[string]string{"key": "value"}
@@ -50,9 +48,8 @@ func Test_changePasswordForm_setValues(t *testing.T) {
func Test_changePasswordProc(t *testing.T) {
var (
ctx = context.Background()
memStore = memstore.NewMemStore()
user = makeMockUser(ctx)
ctx = context.Background()
user = makeMockUser(ctx)
req = &http.Request{}
@@ -60,8 +57,6 @@ func Test_changePasswordProc(t *testing.T) {
authHandlers *AuthHandlers
authReq *request.AuthReq
rq = require.New(t)
authSettings = &settings.Settings{}
)
service.CurrentSettings = &types.AppSettings{}
@@ -132,11 +127,13 @@ func Test_changePasswordProc(t *testing.T) {
for _, tc := range tcc {
t.Run(tc.name, func(t *testing.T) {
rq := require.New(t)
req.PostForm = url.Values{}
tc.fn()
authReq = prepareClientAuthReq(ctx, req, user, memStore)
authReq = prepareClientAuthReq(ctx, req, user)
authHandlers = prepareClientAuthHandlers(ctx, authService, authSettings)
err := authHandlers.changePasswordProc(authReq)
+9 -12
View File
@@ -10,7 +10,6 @@ import (
"github.com/cortezaproject/corteza-server/auth/settings"
"github.com/cortezaproject/corteza-server/system/service"
"github.com/cortezaproject/corteza-server/system/types"
"github.com/quasoft/memstore"
"github.com/stretchr/testify/require"
)
@@ -23,9 +22,8 @@ type (
func Test_loginForm_setValues(t *testing.T) {
var (
ctx = context.Background()
memStore = memstore.NewMemStore()
user = makeMockUser(ctx)
ctx = context.Background()
user = makeMockUser(ctx)
req = &http.Request{}
@@ -41,8 +39,8 @@ func Test_loginForm_setValues(t *testing.T) {
authSettings := &settings.Settings{}
authService = prepareClientAuthService(ctx, user, memStore)
authReq = prepareClientAuthReq(ctx, req, user, memStore)
authService = prepareClientAuthService(ctx, user)
authReq = prepareClientAuthReq(ctx, req, user)
authHandlers = prepareClientAuthHandlers(ctx, authService, authSettings)
payload := map[string]string{"key": "value"}
@@ -61,9 +59,8 @@ func Test_loginForm_setValues(t *testing.T) {
func Test_loginProc(t *testing.T) {
var (
ctx = context.Background()
memStore = memstore.NewMemStore()
user = makeMockUser(ctx)
ctx = context.Background()
user = makeMockUser(ctx)
req = &http.Request{}
@@ -72,8 +69,6 @@ func Test_loginProc(t *testing.T) {
authReq *request.AuthReq
authSettings = &settings.Settings{}
rq = require.New(t)
)
service.CurrentSettings = &types.AppSettings{}
@@ -163,6 +158,8 @@ func Test_loginProc(t *testing.T) {
for _, tc := range tcc {
t.Run(tc.name, func(t *testing.T) {
rq := require.New(t)
// reset from previous
req.Form = url.Values{}
req.PostForm = url.Values{}
@@ -170,7 +167,7 @@ func Test_loginProc(t *testing.T) {
tc.fn()
authReq = prepareClientAuthReq(ctx, req, user, memStore)
authReq = prepareClientAuthReq(ctx, req, user)
authHandlers = prepareClientAuthHandlers(ctx, authService, authSettings)
err := authHandlers.loginProc(authReq)
+3 -6
View File
@@ -10,15 +10,13 @@ import (
"github.com/cortezaproject/corteza-server/auth/settings"
"github.com/cortezaproject/corteza-server/system/service"
"github.com/cortezaproject/corteza-server/system/types"
"github.com/quasoft/memstore"
"github.com/stretchr/testify/require"
)
func Test_logoutProc(t *testing.T) {
var (
ctx = context.Background()
memStore = memstore.NewMemStore()
user = makeMockUser(ctx)
ctx = context.Background()
user = makeMockUser(ctx)
req = &http.Request{}
@@ -36,7 +34,7 @@ func Test_logoutProc(t *testing.T) {
service.CurrentSettings.Auth.Internal.Enabled = true
authService = &authServiceMocked{}
authReq = prepareClientAuthReq(ctx, req, user, memStore)
authReq = prepareClientAuthReq(ctx, req, user)
authHandlers = prepareClientAuthHandlers(ctx, authService, authSettings)
req.PostForm = url.Values{}
@@ -44,7 +42,6 @@ func Test_logoutProc(t *testing.T) {
authReq.Session.Values = map[interface{}]interface{}{"key": url.Values{"key": []string{"value"}}}
err := authHandlers.logoutProc(authReq)
rq.NoError(err)
rq.Empty(authReq.Session.Values)
rq.Empty(authReq.AuthUser)
+5 -7
View File
@@ -10,15 +10,13 @@ import (
"github.com/cortezaproject/corteza-server/auth/settings"
"github.com/cortezaproject/corteza-server/system/service"
"github.com/cortezaproject/corteza-server/system/types"
"github.com/quasoft/memstore"
"github.com/stretchr/testify/require"
)
func Test_mfaProc(t *testing.T) {
var (
ctx = context.Background()
memStore = memstore.NewMemStore()
user = makeMockUser(ctx)
ctx = context.Background()
user = makeMockUser(ctx)
req = &http.Request{}
@@ -27,8 +25,6 @@ func Test_mfaProc(t *testing.T) {
authReq *request.AuthReq
authSettings = &settings.Settings{}
rq = require.New(t)
)
service.CurrentSettings = &types.AppSettings{}
@@ -194,6 +190,8 @@ func Test_mfaProc(t *testing.T) {
for _, tc := range tcc {
t.Run(tc.name, func(t *testing.T) {
rq := require.New(t)
// reset from previous
req.Form = url.Values{}
req.PostForm = url.Values{}
@@ -201,7 +199,7 @@ func Test_mfaProc(t *testing.T) {
tc.fn()
authReq = prepareClientAuthReq(ctx, req, user, memStore)
authReq = prepareClientAuthReq(ctx, req, user)
authHandlers = prepareClientAuthHandlers(ctx, authService, authSettings)
err := authHandlers.mfaProc(authReq)
+8 -11
View File
@@ -9,16 +9,14 @@ import (
"github.com/cortezaproject/corteza-server/auth/request"
"github.com/cortezaproject/corteza-server/auth/settings"
"github.com/quasoft/memstore"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
)
func Test_oauth2AuthorizeSuccess(t *testing.T) {
var (
ctx = context.Background()
memStore = memstore.NewMemStore()
user = makeMockUser(ctx)
ctx = context.Background()
user = makeMockUser(ctx)
req = &http.Request{
Form: url.Values{},
@@ -31,8 +29,6 @@ func Test_oauth2AuthorizeSuccess(t *testing.T) {
authReq *request.AuthReq
authSettings = &settings.Settings{}
rq = require.New(t)
)
tcc := []testingExpect{
@@ -66,9 +62,11 @@ func Test_oauth2AuthorizeSuccess(t *testing.T) {
for _, tc := range tcc {
t.Run(tc.name, func(t *testing.T) {
rq := require.New(t)
tc.fn()
authReq = prepareClientAuthReq(ctx, req, user, memStore)
authReq = prepareClientAuthReq(ctx, req, user)
authHandlers = &AuthHandlers{
Log: zap.NewNop(),
AuthService: authService,
@@ -91,9 +89,8 @@ func Test_oauth2AuthorizeSuccess(t *testing.T) {
func Test_oauth2AuthorizeSuccessSetParams(t *testing.T) {
var (
ctx = context.Background()
memStore = memstore.NewMemStore()
user = makeMockUser(ctx)
ctx = context.Background()
user = makeMockUser(ctx)
req = &http.Request{
Form: url.Values{},
@@ -115,7 +112,7 @@ func Test_oauth2AuthorizeSuccessSetParams(t *testing.T) {
},
}
authReq = prepareClientAuthReq(ctx, req, user, memStore)
authReq = prepareClientAuthReq(ctx, req, user)
authReq.Session.Values["oauth2AuthParams"] = url.Values{"foo": []string{"bar"}}
authHandlers = &AuthHandlers{
+18 -23
View File
@@ -11,15 +11,13 @@ import (
"github.com/cortezaproject/corteza-server/auth/settings"
"github.com/cortezaproject/corteza-server/system/service"
"github.com/cortezaproject/corteza-server/system/types"
"github.com/quasoft/memstore"
"github.com/stretchr/testify/require"
)
func Test_requestPasswordResetForm(t *testing.T) {
var (
ctx = context.Background()
memStore = memstore.NewMemStore()
user = makeMockUser(ctx)
ctx = context.Background()
user = makeMockUser(ctx)
req = &http.Request{
URL: &url.URL{},
@@ -34,7 +32,7 @@ func Test_requestPasswordResetForm(t *testing.T) {
rq = require.New(t)
)
authReq = prepareClientAuthReq(ctx, req, user, memStore)
authReq = prepareClientAuthReq(ctx, req, user)
authHandlers = prepareClientAuthHandlers(ctx, authService, authSettings)
payload := map[string]string{"foo": "bar"}
@@ -49,9 +47,8 @@ func Test_requestPasswordResetForm(t *testing.T) {
func Test_resetPasswordForm(t *testing.T) {
var (
ctx = context.Background()
memStore = memstore.NewMemStore()
user = makeMockUser(ctx)
ctx = context.Background()
user = makeMockUser(ctx)
req = &http.Request{
URL: &url.URL{},
@@ -62,8 +59,6 @@ func Test_resetPasswordForm(t *testing.T) {
authReq *request.AuthReq
authSettings = &settings.Settings{}
rq = require.New(t)
)
tcc := []testingExpect{
@@ -106,13 +101,15 @@ func Test_resetPasswordForm(t *testing.T) {
for _, tc := range tcc {
t.Run(tc.name, func(t *testing.T) {
rq := require.New(t)
// reset from previous
req.Form = url.Values{}
req.PostForm = url.Values{}
tc.fn()
authReq = prepareClientAuthReq(ctx, req, user, memStore)
authReq = prepareClientAuthReq(ctx, req, user)
authHandlers = prepareClientAuthHandlers(ctx, authService, authSettings)
// unset so we get to the main functionality
@@ -131,9 +128,8 @@ func Test_resetPasswordForm(t *testing.T) {
func Test_requestPasswordReset(t *testing.T) {
var (
ctx = context.Background()
memStore = memstore.NewMemStore()
user = makeMockUser(ctx)
ctx = context.Background()
user = makeMockUser(ctx)
req = &http.Request{}
@@ -142,8 +138,6 @@ func Test_requestPasswordReset(t *testing.T) {
authReq *request.AuthReq
authSettings = &settings.Settings{}
rq = require.New(t)
)
tcc := []testingExpect{
@@ -177,6 +171,8 @@ func Test_requestPasswordReset(t *testing.T) {
for _, tc := range tcc {
t.Run(tc.name, func(t *testing.T) {
rq := require.New(t)
// reset from previous
req.Form = url.Values{}
req.PostForm = url.Values{}
@@ -184,7 +180,7 @@ func Test_requestPasswordReset(t *testing.T) {
tc.fn()
authReq = prepareClientAuthReq(ctx, req, user, memStore)
authReq = prepareClientAuthReq(ctx, req, user)
authHandlers = prepareClientAuthHandlers(ctx, authService, authSettings)
err := authHandlers.requestPasswordResetProc(authReq)
@@ -199,9 +195,8 @@ func Test_requestPasswordReset(t *testing.T) {
func Test_requestPasswordProc(t *testing.T) {
var (
ctx = context.Background()
memStore = memstore.NewMemStore()
user = makeMockUser(ctx)
ctx = context.Background()
user = makeMockUser(ctx)
req = &http.Request{}
@@ -210,8 +205,6 @@ func Test_requestPasswordProc(t *testing.T) {
authReq *request.AuthReq
authSettings = &settings.Settings{}
rq = require.New(t)
)
tcc := []testingExpect{
@@ -245,9 +238,11 @@ func Test_requestPasswordProc(t *testing.T) {
for _, tc := range tcc {
t.Run(tc.name, func(t *testing.T) {
rq := require.New(t)
tc.fn()
authReq = prepareClientAuthReq(ctx, req, user, memStore)
authReq = prepareClientAuthReq(ctx, req, user)
authHandlers = prepareClientAuthHandlers(ctx, authService, authSettings)
err := authHandlers.resetPasswordProc(authReq)
+8 -11
View File
@@ -10,15 +10,13 @@ import (
"github.com/cortezaproject/corteza-server/auth/settings"
"github.com/cortezaproject/corteza-server/system/service"
"github.com/cortezaproject/corteza-server/system/types"
"github.com/quasoft/memstore"
"github.com/stretchr/testify/require"
)
func Test_profileForm(t *testing.T) {
var (
ctx = context.Background()
memStore = memstore.NewMemStore()
user = makeMockUser(ctx)
ctx = context.Background()
user = makeMockUser(ctx)
req = &http.Request{
URL: &url.URL{},
@@ -35,7 +33,7 @@ func Test_profileForm(t *testing.T) {
rq = require.New(t)
)
authReq = prepareClientAuthReq(ctx, req, user, memStore)
authReq = prepareClientAuthReq(ctx, req, user)
authHandlers = prepareClientAuthHandlers(ctx, authService, authSettings)
userForm := map[string]string{
@@ -56,9 +54,8 @@ func Test_profileForm(t *testing.T) {
func Test_profileFormProc(t *testing.T) {
var (
ctx = context.Background()
memStore = memstore.NewMemStore()
user = makeMockUser(ctx)
ctx = context.Background()
user = makeMockUser(ctx)
req = &http.Request{
PostForm: url.Values{},
@@ -70,8 +67,6 @@ func Test_profileFormProc(t *testing.T) {
authReq *request.AuthReq
authSettings = &settings.Settings{}
rq = require.New(t)
)
tcc := []testingExpect{
@@ -184,13 +179,15 @@ func Test_profileFormProc(t *testing.T) {
for _, tc := range tcc {
t.Run(tc.name, func(t *testing.T) {
rq := require.New(t)
// reset from previous
req.Form = url.Values{}
req.PostForm = url.Values{}
tc.fn()
authReq = prepareClientAuthReq(ctx, req, user, memStore)
authReq = prepareClientAuthReq(ctx, req, user)
authHandlers = prepareClientAuthHandlers(ctx, authService, authSettings)
authHandlers.UserService = userService
+11 -15
View File
@@ -10,15 +10,13 @@ import (
"github.com/cortezaproject/corteza-server/auth/request"
"github.com/cortezaproject/corteza-server/auth/settings"
"github.com/cortezaproject/corteza-server/system/types"
"github.com/quasoft/memstore"
"github.com/stretchr/testify/require"
)
func Test_securityForm(t *testing.T) {
var (
ctx = context.Background()
memStore = memstore.NewMemStore()
user = makeMockUser(ctx)
ctx = context.Background()
user = makeMockUser(ctx)
req = &http.Request{
URL: &url.URL{},
@@ -33,7 +31,7 @@ func Test_securityForm(t *testing.T) {
rq = require.New(t)
)
authReq = prepareClientAuthReq(ctx, req, user, memStore)
authReq = prepareClientAuthReq(ctx, req, user)
authHandlers = prepareClientAuthHandlers(ctx, authService, authSettings)
err := authHandlers.securityForm(authReq)
@@ -46,9 +44,8 @@ func Test_securityForm(t *testing.T) {
func Test_securityProc(t *testing.T) {
var (
ctx = context.Background()
memStore = memstore.NewMemStore()
user = makeMockUser(ctx)
ctx = context.Background()
user = makeMockUser(ctx)
req = &http.Request{
PostForm: url.Values{},
@@ -59,8 +56,6 @@ func Test_securityProc(t *testing.T) {
authReq *request.AuthReq
authSettings = &settings.Settings{}
rq = require.New(t)
)
tcc := []testingExpect{
@@ -99,13 +94,15 @@ func Test_securityProc(t *testing.T) {
for _, tc := range tcc {
t.Run(tc.name, func(t *testing.T) {
rq := require.New(t)
// reset from previous
req.Form = url.Values{}
req.PostForm = url.Values{}
tc.fn()
authReq = prepareClientAuthReq(ctx, req, user, memStore)
authReq = prepareClientAuthReq(ctx, req, user)
authHandlers = prepareClientAuthHandlers(ctx, authService, authSettings)
authReq.Session.Values = map[interface{}]interface{}{"totpSecret": "SECRET_VALUE"}
@@ -128,9 +125,8 @@ func Test_securityProc(t *testing.T) {
func Test_securityProcDisableEmailOTPSuccess(t *testing.T) {
var (
ctx = context.Background()
memStore = memstore.NewMemStore()
user = makeMockUser(ctx)
ctx = context.Background()
user = makeMockUser(ctx)
req = &http.Request{
Form: url.Values{},
@@ -154,7 +150,7 @@ func Test_securityProcDisableEmailOTPSuccess(t *testing.T) {
},
}
authReq = prepareClientAuthReq(ctx, req, user, memStore)
authReq = prepareClientAuthReq(ctx, req, user)
authHandlers = prepareClientAuthHandlers(ctx, authService, authSettings)
authReq.Session.Values = map[interface{}]interface{}{"totpSecret": "SECRET_VALUE"}
+8 -11
View File
@@ -10,15 +10,13 @@ import (
"github.com/cortezaproject/corteza-server/auth/settings"
"github.com/cortezaproject/corteza-server/system/service"
"github.com/cortezaproject/corteza-server/system/types"
"github.com/quasoft/memstore"
"github.com/stretchr/testify/require"
)
func Test_signupForm(t *testing.T) {
var (
ctx = context.Background()
memStore = memstore.NewMemStore()
user = makeMockUser(ctx)
ctx = context.Background()
user = makeMockUser(ctx)
req = &http.Request{
URL: &url.URL{},
@@ -33,7 +31,7 @@ func Test_signupForm(t *testing.T) {
rq = require.New(t)
)
authReq = prepareClientAuthReq(ctx, req, user, memStore)
authReq = prepareClientAuthReq(ctx, req, user)
authHandlers = prepareClientAuthHandlers(ctx, authService, authSettings)
userForm := map[string]string{
@@ -53,9 +51,8 @@ func Test_signupForm(t *testing.T) {
func Test_signupProc(t *testing.T) {
var (
ctx = context.Background()
memStore = memstore.NewMemStore()
user = makeMockUser(ctx)
ctx = context.Background()
user = makeMockUser(ctx)
req = &http.Request{
PostForm: url.Values{},
@@ -66,8 +63,6 @@ func Test_signupProc(t *testing.T) {
authReq *request.AuthReq
authSettings = &settings.Settings{}
rq = require.New(t)
)
tcc := []testingExpect{
@@ -183,13 +178,15 @@ func Test_signupProc(t *testing.T) {
for _, tc := range tcc {
t.Run(tc.name, func(t *testing.T) {
rq := require.New(t)
// reset from previous
req.Form = url.Values{}
req.PostForm = url.Values{}
tc.fn()
authReq = prepareClientAuthReq(ctx, req, user, memStore)
authReq = prepareClientAuthReq(ctx, req, user)
authHandlers = prepareClientAuthHandlers(ctx, authService, authSettings)
err := authHandlers.signupProc(authReq)
+33 -7
View File
@@ -16,7 +16,6 @@ import (
"github.com/go-oauth2/oauth2/v4/server"
"github.com/gorilla/sessions"
"github.com/markbates/goth"
"github.com/quasoft/memstore"
"go.uber.org/zap"
)
@@ -41,6 +40,13 @@ type (
opt options.AuthOpt
}
mockSession struct {
Options *sessions.Options
get func(r *http.Request, name string) (*sessions.Session, error)
new func(r *http.Request, name string) (*sessions.Session, error)
save func(r *http.Request, w http.ResponseWriter, s *sessions.Session) error
}
oauth2ServiceMocked struct {
getRedirectURI func(req *server.AuthorizeRequest, data map[string]interface{}) (string, error)
checkResponseType func(rt oauth2.ResponseType) bool
@@ -250,18 +256,31 @@ func (ma mockedAuthService) ValidateTOTP(ctx context.Context, code string) (err
//
// Mocking notification service
//
func (m mockNotificationService) EmailConfirmation(ctx context.Context, lang string, emailAddress string, url string) error {
func (m mockNotificationService) EmailConfirmation(ctx context.Context, emailAddress string, token string) error {
return nil
}
func (m mockNotificationService) PasswordReset(ctx context.Context, lang string, emailAddress string, url string) error {
func (m mockNotificationService) PasswordReset(ctx context.Context, emailAddress string, token string) error {
return nil
}
func (m mockNotificationService) EmailOTP(ctx context.Context, lang string, emailAddress string, otp string) error {
func (m mockNotificationService) EmailOTP(ctx context.Context, emailAddress string, code string) error {
return nil
}
//
// Mocking gorilla session
//
func (ms mockSession) Get(r *http.Request, name string) (*sessions.Session, error) {
return ms.get(r, name)
}
func (ms mockSession) New(r *http.Request, name string) (*sessions.Session, error) {
return ms.new(r, name)
}
func (ms mockSession) Save(r *http.Request, w http.ResponseWriter, s *sessions.Session) error {
return ms.save(r, w, s)
}
//
// Helpers
//
@@ -292,7 +311,7 @@ func makeMockUser(ctx context.Context) *types.User {
return u
}
func prepareClientAuthReq(ctx context.Context, req *http.Request, user *types.User, memStore *memstore.MemStore) *request.AuthReq {
func prepareClientAuthReq(ctx context.Context, req *http.Request, user *types.User) *request.AuthReq {
s := &settings.Settings{}
s.MultiFactor.EmailOTP.Enabled = true
s.MultiFactor.EmailOTP.Enforced = true
@@ -300,16 +319,23 @@ func prepareClientAuthReq(ctx context.Context, req *http.Request, user *types.Us
authUser := request.NewAuthUser(s, user, true, time.Duration(time.Hour))
session := sessions.NewSession(&mockSession{
save: func(r *http.Request, w http.ResponseWriter, s *sessions.Session) error {
s.Values = make(map[interface{}]interface{})
return nil
},
}, "session")
return &request.AuthReq{
Request: req,
AuthUser: authUser,
Session: sessions.NewSession(memStore, "session"),
Session: session,
Response: httptest.NewRecorder(),
Data: make(map[string]interface{}),
}
}
func prepareClientAuthService(ctx context.Context, user *types.User, memStore *memstore.MemStore) *mockAuthService {
func prepareClientAuthService(ctx context.Context, user *types.User) *mockAuthService {
authService := makeMockAuthService(ctx)
return authService
}
+1 -1
View File
@@ -54,7 +54,7 @@ require (
github.com/pkg/errors v0.9.1
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
github.com/prometheus/client_golang v0.9.3
github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b
github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b // indirect
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd // indirect
github.com/sony/sonyflake v0.0.0-20181109022403-6d5bd6181009
github.com/spf13/afero v1.2.2
-14
View File
@@ -1,14 +0,0 @@
# Binaries for programs and plugins
*.exe
*.dll
*.so
*.dylib
# Test binary, build with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
.glide/
-8
View File
@@ -1,8 +0,0 @@
language: go
sudo: false
go:
- tip
before_install:
- go get github.com/mattn/goveralls
script:
- $GOPATH/bin/goveralls -service=travis-ci
-29
View File
@@ -1,29 +0,0 @@
BSD 3-Clause License
Copyright (c) 2018, QuaSoft
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-74
View File
@@ -1,74 +0,0 @@
# memstore
[![GoDoc](https://godoc.org/github.com/quasoft/memstore?status.svg)](https://godoc.org/github.com/quasoft/memstore) [![Build Status](https://travis-ci.org/quasoft/memstore.png?branch=master)](https://travis-ci.org/quasoft/memstore) [![Coverage Status](https://coveralls.io/repos/github/quasoft/memstore/badge.svg?branch=master)](https://coveralls.io/github/quasoft/memstore?branch=master) [![Go Report Card](https://goreportcard.com/badge/github.com/quasoft/memstore)](https://goreportcard.com/report/github.com/quasoft/memstore)
In-memory implementation of [gorilla/sessions](https://github.com/gorilla/sessions) for use in tests and dev environments
## How to install
go get github.com/quasoft/memstore
## Documentation
Documentation, as usual, can be found at [godoc.org](http://www.godoc.org/github.com/quasoft/memstore).
The interface of [gorilla/sessions](https://github.com/gorilla/sessions) is described at http://www.gorillatoolkit.org/pkg/sessions.
### How to use
``` go
package main
import (
"fmt"
"log"
"net/http"
"github.com/quasoft/memstore"
)
func main() {
// Create a memory store, providing authentication and
// encryption key for securecookie
store := memstore.NewMemStore(
[]byte("authkey123"),
[]byte("enckey12341234567890123456789012"),
)
http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
// Get session by name.
session, err := store.Get(r, "session1")
if err != nil {
log.Printf("Error retrieving session: %v", err)
}
// The name should be 'foobar' if home page was visited before that and 'Guest' otherwise.
user, ok := session.Values["username"]
if !ok {
user = "Guest"
}
fmt.Fprintf(w, "Hello %s", user)
})
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
// Get session by name.
session, err := store.Get(r, "session1")
if err != nil {
log.Printf("Error retrieving session: %v", err)
}
// Add values to the session object
session.Values["username"] = "foobar"
session.Values["email"] = "spam@eggs.com"
// Save values
err = session.Save(r, w)
if err != nil {
log.Fatalf("Error saving session: %v", err)
}
})
log.Printf("listening on http://%s/", "127.0.0.1:9090")
log.Fatal(http.ListenAndServe("127.0.0.1:9090", nil))
}
```
-40
View File
@@ -1,40 +0,0 @@
package memstore
import (
"sync"
)
type cache struct {
data map[string]valueType
mutex sync.RWMutex
}
func newCache() *cache {
return &cache{
data: make(map[string]valueType),
}
}
func (c *cache) value(name string) (valueType, bool) {
c.mutex.RLock()
defer c.mutex.RUnlock()
v, ok := c.data[name]
return v, ok
}
func (c *cache) setValue(name string, value valueType) {
c.mutex.Lock()
defer c.mutex.Unlock()
c.data[name] = value
}
func (c *cache) delete(name string) {
c.mutex.Lock()
defer c.mutex.Unlock()
if _, ok := c.data[name]; ok {
delete(c.data, name)
}
}
-155
View File
@@ -1,155 +0,0 @@
package memstore
import (
"bytes"
"encoding/base32"
"encoding/gob"
"fmt"
"net/http"
"strings"
"github.com/gorilla/securecookie"
"github.com/gorilla/sessions"
)
// MemStore is an in-memory implementation of gorilla/sessions, suitable
// for use in tests and development environments. Do not use in production.
// Values are cached in a map. The cache is protected and can be used by
// multiple goroutines.
type MemStore struct {
Codecs []securecookie.Codec
Options *sessions.Options
cache *cache
}
type valueType map[interface{}]interface{}
// NewMemStore returns a new MemStore.
//
// Keys are defined in pairs to allow key rotation, but the common case is
// to set a single authentication key and optionally an encryption key.
//
// The first key in a pair is used for authentication and the second for
// encryption. The encryption key can be set to nil or omitted in the last
// pair, but the authentication key is required in all pairs.
//
// It is recommended to use an authentication key with 32 or 64 bytes.
// The encryption key, if set, must be either 16, 24, or 32 bytes to select
// AES-128, AES-192, or AES-256 modes.
//
// Use the convenience function securecookie.GenerateRandomKey() to create
// strong keys.
func NewMemStore(keyPairs ...[]byte) *MemStore {
store := MemStore{
Codecs: securecookie.CodecsFromPairs(keyPairs...),
Options: &sessions.Options{
Path: "/",
MaxAge: 86400 * 30,
},
cache: newCache(),
}
store.MaxAge(store.Options.MaxAge)
return &store
}
// Get returns a session for the given name after adding it to the registry.
//
// It returns a new session if the sessions doesn't exist. Access IsNew on
// the session to check if it is an existing session or a new one.
//
// It returns a new session and an error if the session exists but could
// not be decoded.
func (m *MemStore) Get(r *http.Request, name string) (*sessions.Session, error) {
return sessions.GetRegistry(r).Get(m, name)
}
// New returns a session for the given name without adding it to the registry.
//
// The difference between New() and Get() is that calling New() twice will
// decode the session data twice, while Get() registers and reuses the same
// decoded session after the first call.
func (m *MemStore) New(r *http.Request, name string) (*sessions.Session, error) {
session := sessions.NewSession(m, name)
options := *m.Options
session.Options = &options
session.IsNew = true
c, err := r.Cookie(name)
if err != nil {
// Cookie not found, this is a new session
return session, nil
}
err = securecookie.DecodeMulti(name, c.Value, &session.ID, m.Codecs...)
if err != nil {
// Value could not be decrypted, consider this is a new session
return session, err
}
v, ok := m.cache.value(session.ID)
if !ok {
// No value found in cache, don't set any values in session object,
// consider a new session
return session, nil
}
// Values found in session, this is not a new session
session.Values = m.copy(v)
session.IsNew = false
return session, nil
}
// Save adds a single session to the response.
// Set Options.MaxAge to -1 or call MaxAge(-1) before saving the session to delete all values in it.
func (m *MemStore) Save(r *http.Request, w http.ResponseWriter, s *sessions.Session) error {
var cookieValue string
if s.Options.MaxAge < 0 {
cookieValue = ""
m.cache.delete(s.ID)
for k := range s.Values {
delete(s.Values, k)
}
} else {
if s.ID == "" {
s.ID = strings.TrimRight(base32.StdEncoding.EncodeToString(securecookie.GenerateRandomKey(32)), "=")
}
encrypted, err := securecookie.EncodeMulti(s.Name(), s.ID, m.Codecs...)
if err != nil {
return err
}
cookieValue = encrypted
m.cache.setValue(s.ID, m.copy(s.Values))
}
http.SetCookie(w, sessions.NewCookie(s.Name(), cookieValue, s.Options))
return nil
}
// MaxAge sets the maximum age for the store and the underlying cookie
// implementation. Individual sessions can be deleted by setting Options.MaxAge
// = -1 for that session.
func (m *MemStore) MaxAge(age int) {
m.Options.MaxAge = age
// Set the maxAge for each securecookie instance.
for _, codec := range m.Codecs {
if sc, ok := codec.(*securecookie.SecureCookie); ok {
sc.MaxAge(age)
}
}
}
func (m *MemStore) copy(v valueType) valueType {
var buf bytes.Buffer
enc := gob.NewEncoder(&buf)
dec := gob.NewDecoder(&buf)
err := enc.Encode(v)
if err != nil {
panic(fmt.Errorf("could not copy memstore value. Encoding to gob failed: %v", err))
}
var value valueType
err = dec.Decode(&value)
if err != nil {
panic(fmt.Errorf("could not copy memstore value. Decoding from gob failed: %v", err))
}
return value
}
-1
View File
@@ -211,7 +211,6 @@ github.com/prometheus/procfs
github.com/prometheus/procfs/internal/fs
# github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b
## explicit
github.com/quasoft/memstore
# github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd
## explicit
github.com/rwcarlsen/goexif/exif