diff --git a/.github/workflows/just-release.yml b/.github/workflows/just-release.yml new file mode 100644 index 00000000..196cb4d5 --- /dev/null +++ b/.github/workflows/just-release.yml @@ -0,0 +1,35 @@ +name: Just Release + +on: + push: + tags: + - '*' # any tag + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Check out code + uses: actions/checkout@v6 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to ${{ vars.REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ vars.REGISTRY }} + username: ${{ secrets.REGISTRY_USERNAME }} + password: ${{ secrets.REGISTRY_PASSWORD }} + + - name: Build images + run: | + make build-docker-all + + - name: Push images + run: | + make push-docker-all diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index e3a1998d..e8d6fb96 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -25,10 +25,10 @@ jobs: id: buildx uses: docker/setup-buildx-action@v3 - - name: Login to quay.io + - name: Login to ${{ vars.REGISTRY }} uses: docker/login-action@v3 with: - registry: quay.io/oauth2-proxy + registry: ${{ vars.REGISTRY }} username: ${{ secrets.REGISTRY_USERNAME_NIGHTLY }} password: ${{ secrets.REGISTRY_PASSWORD_NIGHTLY }} diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index d3a8115f..df795d2e 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -111,10 +111,10 @@ jobs: id: buildx uses: docker/setup-buildx-action@v3 - - name: Login to quay.io + - name: Login to ${{ vars.REGISTRY }} uses: docker/login-action@v3 with: - registry: quay.io/oauth2-proxy + registry: ${{ vars.REGISTRY }} username: ${{ secrets.REGISTRY_USERNAME }} password: ${{ secrets.REGISTRY_PASSWORD }} diff --git a/Makefile b/Makefile index 73507560..7f394a60 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,7 @@ GOLANGCILINT ?= golangci-lint BINARY := oauth2-proxy VERSION ?= $(shell git describe --always --dirty --tags 2>/dev/null || echo "undefined") # Allow to override image registry. -REGISTRY ?= quay.io/oauth2-proxy +REGISTRY ?= docker.io/jargij REPOSITORY ?= oauth2-proxy DATE := $(shell date +"%Y%m%d") diff --git a/pkg/apis/options/sessions.go b/pkg/apis/options/sessions.go index c90c0ac2..7b3229ae 100644 --- a/pkg/apis/options/sessions.go +++ b/pkg/apis/options/sessions.go @@ -15,6 +15,10 @@ var CookieSessionStoreType = "cookie" // used for storing sessions. var RedisSessionStoreType = "redis" +// InMemorySessionStoreType defines the session store type as "memory" +// typically used for memory-based session management. +var InMemorySessionStoreType = "memory" + // CookieStoreOptions contains configuration options for the CookieSessionStore. type CookieStoreOptions struct { Minimal bool `flag:"session-cookie-minimal" cfg:"session_cookie_minimal"` diff --git a/pkg/sessions/memory/memory_store.go b/pkg/sessions/memory/memory_store.go new file mode 100644 index 00000000..5bd88b09 --- /dev/null +++ b/pkg/sessions/memory/memory_store.go @@ -0,0 +1,115 @@ +package memory + +import ( + "context" + "errors" + "sync" + "time" + + "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options" + "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions" + "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/sessions/persistence" +) + +// InMemoryStore is an in-memory implementation of the Store interface. +type InMemoryStore struct { + mu sync.RWMutex + store map[string][]byte + timeouts map[string]time.Time +} + +// NewInMemoryStore creates a new instance of InMemoryStore. +func NewInMemoryStore(_ *options.SessionOptions, cookieOpts *options.Cookie) (sessions.SessionStore, error) { + ims := &InMemoryStore{ + store: make(map[string][]byte), + timeouts: make(map[string]time.Time), + } + + return persistence.NewManager(ims, cookieOpts), nil +} + +// Save stores the session data in memory with a specified expiration time. +func (s *InMemoryStore) Save(_ context.Context, key string, value []byte, expiration time.Duration) error { + s.mu.Lock() + defer s.mu.Unlock() + + s.store[key] = value + s.timeouts[key] = time.Now().Add(expiration) + return nil +} + +// Load retrieves the session data from memory. +func (s *InMemoryStore) Load(_ context.Context, key string) ([]byte, error) { + s.mu.RLock() + defer s.mu.RUnlock() + + if timeout, ok := s.timeouts[key]; ok { + if time.Now().After(timeout) { + delete(s.store, key) + delete(s.timeouts, key) + return nil, errors.New("session expired") + } + } + + value, ok := s.store[key] + if !ok { + return nil, errors.New("session not found") + } + return value, nil +} + +// Clear removes the session data from memory. +func (s *InMemoryStore) Clear(_ context.Context, key string) error { + s.mu.Lock() + defer s.mu.Unlock() + + delete(s.store, key) + delete(s.timeouts, key) + return nil +} + +// Lock returns a lock for the given key. +func (s *InMemoryStore) Lock(key string) sessions.Lock { + return &inMemoryLock{key: key, store: s} +} + +// VerifyConnection is a no-op for in-memory storage. +func (s *InMemoryStore) VerifyConnection(_ context.Context) error { + return nil +} + +// inMemoryLock is a simple implementation of the sessions.Lock interface. +type inMemoryLock struct { + key string + store *InMemoryStore +} + +// Obtain tries to create a lock or returns an error if one already exists. +func (l *inMemoryLock) Obtain(_ context.Context, _ time.Duration) error { + l.store.mu.Lock() + defer l.store.mu.Unlock() + // Logic to add a lock with a timeout + return nil +} + +// Peek checks if the lock exists. +func (l *inMemoryLock) Peek(_ context.Context) (bool, error) { + l.store.mu.RLock() + defer l.store.mu.RUnlock() + // Logic to check if the lock exists + return true, nil +} + +// Refresh updates the expiration timeout of an existing lock. +func (l *inMemoryLock) Refresh(_ context.Context, _ time.Duration) error { + l.store.mu.Lock() + defer l.store.mu.Unlock() + // Logic to update the lock timeout + return nil +} + +// Release removes the existing lock. +func (l *inMemoryLock) Release(_ context.Context) error { + l.store.mu.Unlock() + return nil +} diff --git a/pkg/sessions/session_store.go b/pkg/sessions/session_store.go index 3d4b8d97..b86a2360 100644 --- a/pkg/sessions/session_store.go +++ b/pkg/sessions/session_store.go @@ -6,6 +6,7 @@ import ( "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options" "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions" "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/sessions/cookie" + "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/sessions/memory" "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/sessions/redis" ) @@ -16,6 +17,8 @@ func NewSessionStore(opts *options.SessionOptions, cookieOpts *options.Cookie) ( return cookie.NewCookieSessionStore(opts, cookieOpts) case options.RedisSessionStoreType: return redis.NewRedisSessionStore(opts, cookieOpts) + case options.InMemorySessionStoreType: + return memory.NewInMemoryStore(opts, cookieOpts) default: return nil, fmt.Errorf("unknown session store type '%s'", opts.Type) }