// // tank // // Import and Playlist Daemon for autoradio project // // // Copyright (C) 2017-2019 Christian Pointner <equinox@helsinki.at> // // This file is part of tank. // // tank 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. // // tank 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 tank. If not, see <http://www.gnu.org/licenses/>. // package v1 import ( "net/http" "strconv" "github.com/gin-gonic/gin" "gitlab.servus.at/autoradio/tank/auth" "gitlab.servus.at/autoradio/tank/importer" "gitlab.servus.at/autoradio/tank/store" ) func idFromString(s string) (uint64, error) { return strconv.ParseUint(s, 10, 64) } func statusCodeFromError(err error) (code int, response ErrorResponse) { code = http.StatusInternalServerError response = ErrorResponse{Error: err.Error()} switch err.(type) { case *store.ErrFileInUse: code = http.StatusConflict response.Detail = err case store.ErrInvalidMetadataField: code = http.StatusBadRequest case *importer.JobSourceResult: response.Detail = err.(*importer.JobSourceResult).Log default: switch err { case ErrNotFlowJSUpload: code = http.StatusConflict case ErrFlowJSChunkAlreadUploading: code = http.StatusConflict case ErrFileVanished: code = http.StatusConflict case store.ErrNotImplemented: code = http.StatusNotImplemented case store.ErrNotFound: code = http.StatusNotFound case store.ErrFileNotNew: code = http.StatusConflict case store.ErrFileImportNotDone: code = http.StatusConflict case importer.ErrNotImplemented: code = http.StatusNotImplemented case importer.ErrNotFound: code = http.StatusNotFound case importer.ErrSourceNotSupported: code = http.StatusBadRequest case importer.ErrImportNotRunning: code = http.StatusConflict case importer.ErrSourceAlreadyAttached: code = http.StatusConflict case importer.ErrSourceNotYetAttached: code = http.StatusConflict case importer.ErrSourceNotAUpload: code = http.StatusConflict case importer.ErrTooManyJobs: code = http.StatusTooManyRequests case importer.ErrAlreadyCanceled: code = http.StatusConflict } } return } func sendError(c *gin.Context, err error) { code, response := statusCodeFromError(err) c.JSON(code, response) } func getAuthSession(r *http.Request) *auth.Session { s, ok := auth.SessionFromRequest(r) if !ok || s == nil { panic("no session attached to request - is the auth middleware installed?") } return s } func authorizeRequest(c *gin.Context, showID string) (bool, *auth.Session) { s := getAuthSession(c.Request) if s.ReadOnly { switch c.Request.Method { case http.MethodGet: break default: c.JSON(http.StatusForbidden, ErrorResponse{Error: "this session is read-only"}) return false, s } } if s.AllShows { return true, s } for _, show := range s.Shows { if show == showID { return true, s } } c.JSON(http.StatusForbidden, ErrorResponse{Error: "you are not allowed to access show: " + showID}) return false, s }