diff options
Diffstat (limited to 'src/helsinki.at/rhimport/session_store.go')
-rw-r--r-- | src/helsinki.at/rhimport/session_store.go | 310 |
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 -} |