summaryrefslogtreecommitdiff
path: root/src/helsinki.at/rhimport/session_store.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/helsinki.at/rhimport/session_store.go')
-rw-r--r--src/helsinki.at/rhimport/session_store.go310
1 files changed, 0 insertions, 310 deletions
diff --git a/src/helsinki.at/rhimport/session_store.go b/src/helsinki.at/rhimport/session_store.go
deleted file mode 100644
index e47366e..0000000
--- a/src/helsinki.at/rhimport/session_store.go
+++ /dev/null
@@ -1,310 +0,0 @@
-//
-// rhimportd
-//
-// The Radio Helsinki Rivendell Import Daemon
-//
-//
-// Copyright (C) 2015-2016 Christian Pointner <equinox@helsinki.at>
-//
-// This file is part of rhimportd.
-//
-// rhimportd is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// any later version.
-//
-// rhimportd is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with rhimportd. If not, see <http://www.gnu.org/licenses/>.
-//
-
-package rhimport
-
-import (
- "crypto/rand"
- "encoding/base64"
- "fmt"
- "helsinki.at/rhrd-go/rddb"
- "net/http"
-)
-
-type newSessionResponse struct {
- id string
- session *SessionChan
- responsecode int
- errorstring string
-}
-
-type newSessionRequest struct {
- ctx *Context
- refId string
- response chan newSessionResponse
-}
-
-type getSessionResponse struct {
- session *SessionChan
- refId string
- responsecode int
- errorstring string
-}
-
-type getSessionRequest struct {
- user string
- id string
- refId string
- response chan getSessionResponse
-}
-
-type listSessionsResponse struct {
- sessions map[string]string
- responsecode int
- errorstring string
-}
-
-type listSessionsRequest struct {
- user string
- password string
- trusted bool
- response chan listSessionsResponse
-}
-
-type removeSessionResponse struct {
- responsecode int
- errorstring string
-}
-
-type removeSessionRequest struct {
- user string
- id string
- response chan removeSessionResponse
-}
-
-type SessionStoreElement struct {
- s *Session
- refId string
-}
-
-type SessionStore struct {
- store map[string]map[string]*SessionStoreElement
- conf *Config
- db *rddb.DBChan
- quit chan bool
- done chan bool
- newChan chan newSessionRequest
- getChan chan getSessionRequest
- listChan chan listSessionsRequest
- removeChan chan removeSessionRequest
-}
-
-func generateSessionId() (string, error) {
- var b [32]byte
- if _, err := rand.Read(b[:]); err != nil {
- return "", err
- }
- return base64.RawStdEncoding.EncodeToString(b[:]), nil
-}
-
-func (self *SessionStore) new(ctx *Context, refId string) (resp newSessionResponse) {
- resp.responsecode = http.StatusOK
- resp.errorstring = "OK"
- if !ctx.Trusted {
- if ok, err := self.db.CheckPassword(ctx.UserName, ctx.Password); err != nil {
- resp.responsecode = http.StatusInternalServerError
- resp.errorstring = err.Error()
- return
- } else if !ok {
- resp.responsecode = http.StatusUnauthorized
- resp.errorstring = "invalid username and/or password"
- return
- }
- }
- if id, err := generateSessionId(); err != nil {
- resp.responsecode = http.StatusInternalServerError
- resp.errorstring = err.Error()
- } else {
- resp.id = id
- if _, exists := self.store[ctx.UserName]; !exists {
- self.store[ctx.UserName] = make(map[string]*SessionStoreElement)
- }
- ctx.conf = self.conf
- ctx.db = self.db
- s := &SessionStoreElement{newSession(ctx, func() { self.GetInterface().Remove(ctx.UserName, resp.id) }), refId}
- self.store[ctx.UserName][resp.id] = s
- resp.session = self.store[ctx.UserName][resp.id].s.getInterface()
- rhdl.Printf("SessionStore: created session for '%s' -> %s", ctx.UserName, resp.id)
- }
- return
-}
-
-func (self *SessionStore) get(user, id string) (resp getSessionResponse) {
- resp.responsecode = http.StatusOK
- resp.errorstring = "OK"
- if session, exists := self.store[user][id]; exists {
- resp.session = session.s.getInterface()
- resp.refId = session.refId
- } else {
- resp.responsecode = http.StatusNotFound
- resp.errorstring = fmt.Sprintf("SessionStore: session '%s/%s' not found", user, id)
- }
- return
-}
-
-func (self *SessionStore) list(user, password string, trusted bool) (resp listSessionsResponse) {
- resp.responsecode = http.StatusOK
- resp.errorstring = "OK"
- if !trusted {
- if ok, err := self.db.CheckPassword(user, password); err != nil {
- resp.responsecode = http.StatusInternalServerError
- resp.errorstring = err.Error()
- return
- } else if !ok {
- resp.responsecode = http.StatusUnauthorized
- resp.errorstring = "invalid username and/or password"
- return
- }
- }
- resp.sessions = make(map[string]string)
- if sessions, exists := self.store[user]; exists {
- for id, e := range sessions {
- resp.sessions[id] = e.refId
- }
- }
- return
-}
-
-func (self *SessionStore) remove(user, id string) (resp removeSessionResponse) {
- resp.responsecode = http.StatusOK
- resp.errorstring = "OK"
- if session, exists := self.store[user][id]; exists {
- go session.s.cleanup() // cleanup could take a while -> don't block all the other stuff
- delete(self.store[user], id)
- rhdl.Printf("SessionStore: removed session '%s/%s'", user, id)
- if userstore, exists := self.store[user]; exists {
- if len(userstore) == 0 {
- delete(self.store, user)
- rhdl.Printf("SessionStore: removed user '%s'", user)
- }
- }
- } else {
- resp.responsecode = http.StatusNotFound
- resp.errorstring = fmt.Sprintf("SessionStore: session '%s/%s' not found", user, id)
- }
- return
-}
-
-func (self *SessionStore) dispatchRequests() {
- defer func() { self.done <- true }()
- for {
- select {
- case <-self.quit:
- return
- case req := <-self.newChan:
- req.response <- self.new(req.ctx, req.refId)
- case req := <-self.getChan:
- req.response <- self.get(req.user, req.id)
- case req := <-self.listChan:
- req.response <- self.list(req.user, req.password, req.trusted)
- case req := <-self.removeChan:
- req.response <- self.remove(req.user, req.id)
- }
- }
-}
-
-// *********************************************************
-// Public Interface
-
-type SessionStoreChan struct {
- newChan chan<- newSessionRequest
- getChan chan<- getSessionRequest
- listChan chan listSessionsRequest
- removeChan chan<- removeSessionRequest
-}
-
-func (self *SessionStoreChan) New(ctx *Context, refId string) (string, *SessionChan, int, string) {
- resCh := make(chan newSessionResponse)
- req := newSessionRequest{}
- req.ctx = ctx
- req.refId = refId
- req.response = resCh
- self.newChan <- req
-
- res := <-resCh
- return res.id, res.session, res.responsecode, res.errorstring
-}
-
-func (self *SessionStoreChan) Get(user, id string) (*SessionChan, string, int, string) {
- resCh := make(chan getSessionResponse)
- req := getSessionRequest{}
- req.user = user
- req.id = id
- req.response = resCh
- self.getChan <- req
-
- res := <-resCh
- return res.session, res.refId, res.responsecode, res.errorstring
-}
-
-func (self *SessionStoreChan) List(user, password string, trusted bool) (map[string]string, int, string) {
- resCh := make(chan listSessionsResponse)
- req := listSessionsRequest{}
- req.user = user
- req.password = password
- req.trusted = trusted
- req.response = resCh
- self.listChan <- req
-
- res := <-resCh
- return res.sessions, res.responsecode, res.errorstring
-}
-
-func (self *SessionStoreChan) Remove(user, id string) (int, string) {
- resCh := make(chan removeSessionResponse)
- req := removeSessionRequest{}
- req.user = user
- req.id = id
- req.response = resCh
- self.removeChan <- req
-
- res := <-resCh
- return res.responsecode, res.errorstring
-}
-
-func (self *SessionStore) GetInterface() *SessionStoreChan {
- ch := &SessionStoreChan{}
- ch.newChan = self.newChan
- ch.getChan = self.getChan
- ch.listChan = self.listChan
- ch.removeChan = self.removeChan
- return ch
-}
-
-func (self *SessionStore) Cleanup() {
- self.quit <- true
- <-self.done
- close(self.quit)
- close(self.done)
- close(self.newChan)
- close(self.getChan)
- close(self.listChan)
- close(self.removeChan)
-}
-
-func NewSessionStore(conf *Config, db *rddb.DBChan) (store *SessionStore, err error) {
- store = new(SessionStore)
- store.conf = conf
- store.db = db
- store.quit = make(chan bool)
- store.done = make(chan bool)
- store.store = make(map[string]map[string]*SessionStoreElement)
- store.newChan = make(chan newSessionRequest, 10)
- store.getChan = make(chan getSessionRequest, 10)
- store.listChan = make(chan listSessionsRequest, 10)
- store.removeChan = make(chan removeSessionRequest, 10)
-
- go store.dispatchRequests()
- return
-}