Require password for all pages (if not running in public mode)

See https://github.com/photoprism/photoprism/issues/167#issuecomment-574866401

Signed-off-by: Michael Mayer <michael@liquidbytes.net>
This commit is contained in:
Michael Mayer 2020-01-22 13:43:07 +01:00
parent 2f62084d6f
commit f569c3adb6
12 changed files with 76 additions and 49 deletions

View file

@ -42,7 +42,7 @@
</v-list-tile-action>
</v-list-tile>
<v-list-tile v-if="mini" to="/photos" @click="" class="p-navigation-photos">
<v-list-tile v-if="mini && auth" to="/photos" @click="" class="p-navigation-photos">
<v-list-tile-action>
<v-icon>photo</v-icon>
</v-list-tile-action>
@ -54,7 +54,7 @@
</v-list-tile-content>
</v-list-tile>
<v-list-group v-if="!mini" prepend-icon="photo" no-action>
<v-list-group v-if="!mini && auth" prepend-icon="photo" no-action>
<v-list-tile slot="activator" to="/photos" @click.stop="" class="p-navigation-photos">
<v-list-tile-content>
<v-list-tile-title>
@ -89,7 +89,7 @@
</v-list-tile>
</v-list-group>
<v-list-tile v-if="mini" to="/archive" @click="" class="p-navigation-archive">
<v-list-tile v-if="mini && auth" to="/archive" @click="" class="p-navigation-archive">
<v-list-tile-action>
<v-icon>archive</v-icon>
</v-list-tile-action>
@ -101,7 +101,7 @@
</v-list-tile-content>
</v-list-tile>
<v-list-tile v-if="mini" to="/albums" @click="">
<v-list-tile v-if="mini && auth" to="/albums" @click="">
<v-list-tile-action>
<v-icon>folder</v-icon>
</v-list-tile-action>
@ -113,7 +113,7 @@
</v-list-tile-content>
</v-list-tile>
<v-list-group v-if="!mini" prepend-icon="folder" no-action>
<v-list-group v-if="!mini && auth" prepend-icon="folder" no-action>
<v-list-tile slot="activator" to="/albums" @click.stop="">
<v-list-tile-content>
<v-list-tile-title>
@ -133,7 +133,7 @@
</v-list-tile>
</v-list-group>
<v-list-tile to="/favorites" @click="" class="p-navigation-favorites">
<v-list-tile to="/favorites" @click="" class="p-navigation-favorites" v-if="auth">
<v-list-tile-action>
<v-icon>favorite</v-icon>
</v-list-tile-action>
@ -146,7 +146,7 @@
</v-list-tile-content>
</v-list-tile>
<v-list-tile to="/labels" @click="" class="p-navigation-labels">
<v-list-tile to="/labels" @click="" class="p-navigation-labels" v-if="auth">
<v-list-tile-action>
<v-icon>label</v-icon>
</v-list-tile-action>
@ -159,7 +159,7 @@
</v-list-tile-content>
</v-list-tile>
<v-list-tile :to="{ name: 'places' }" @click="" class="p-navigation-places">
<v-list-tile :to="{ name: 'places' }" @click="" class="p-navigation-places" v-if="auth">
<v-list-tile-action>
<v-icon>place</v-icon>
</v-list-tile-action>
@ -172,7 +172,7 @@
</v-list-tile-content>
</v-list-tile>
<v-list-tile to="/discover" @click="" class="p-navigation-discover" v-if="config.experimental">
<v-list-tile to="/discover" @click="" class="p-navigation-discover" v-if="config.experimental && auth">
<v-list-tile-action>
<v-icon>color_lens</v-icon>
</v-list-tile-action>
@ -184,7 +184,7 @@
</v-list-tile-content>
</v-list-tile>
<!-- v-list-tile to="/events" @click="" class="p-navigation-events">
<!-- v-list-tile to="/events" @click="" class="p-navigation-events" v-if="auth">
<v-list-tile-action>
<v-icon>date_range</v-icon>
</v-list-tile-action>
@ -194,7 +194,7 @@
</v-list-tile-content>
</v-list-tile -->
<!-- v-list-tile to="/people" @click="" class="p-navigation-people">
<!-- v-list-tile to="/people" @click="" class="p-navigation-people" v-if="auth">
<v-list-tile-action>
<v-icon>people</v-icon>
</v-list-tile-action>
@ -204,7 +204,7 @@
</v-list-tile-content>
</v-list-tile -->
<v-list-tile to="/library" @click="" class="p-navigation-library" v-if="session.auth || isPublic">
<v-list-tile to="/library" @click="" class="p-navigation-library" v-if="auth">
<v-list-tile-action>
<v-icon>camera_roll</v-icon>
</v-list-tile-action>
@ -216,7 +216,7 @@
</v-list-tile-content>
</v-list-tile>
<v-list-tile to="/settings" @click="" class="p-navigation-settings" v-if="session.auth || isPublic">
<v-list-tile to="/settings" @click="" class="p-navigation-settings" v-if="auth">
<v-list-tile-action>
<v-icon>settings</v-icon>
</v-list-tile-action>
@ -228,7 +228,7 @@
</v-list-tile-content>
</v-list-tile>
<v-list-tile @click="logout" class="p-navigation-logout" v-if="!isPublic && session.auth">
<v-list-tile @click="logout" class="p-navigation-logout" v-if="!isPublic && auth">
<v-list-tile-action>
<v-icon>power_settings_new</v-icon>
</v-list-tile-action>
@ -240,7 +240,7 @@
</v-list-tile-content>
</v-list-tile>
<v-list-tile to="/login" @click="" class="p-navigation-login" v-if="!isPublic && !session.auth">
<v-list-tile to="/login" @click="" class="p-navigation-login" v-if="!auth">
<v-list-tile-action>
<v-icon>lock</v-icon>
</v-list-tile-action>
@ -274,6 +274,11 @@
page: this.$config.page,
};
},
computed: {
auth() {
return this.session.auth || this.isPublic
},
},
methods: {
showNavigation () {
this.drawer = true;

View file

@ -1,14 +1,14 @@
<template>
<div class="p-page p-page-login">
<v-toolbar flat color="secondary">
<v-toolbar-title><translate>Login</translate></v-toolbar-title>
<v-toolbar-title><translate>Authentication required</translate></v-toolbar-title>
<v-spacer></v-spacer>
</v-toolbar>
<v-container class="pt-5">
<p class="subheading">
<span><translate>Please enter the admin password to proceed...</translate></span>
<span><translate>Please enter your password to proceed:</translate></span>
</p>
<v-form ref="form" autocomplete="off" class="p-form-login" @submit.prevent="login" dense>
<v-text-field

View file

@ -24,75 +24,75 @@ export default [
name: "login",
path: "/login",
component: Login,
meta: {title: "Sign In"},
meta: {title: "Sign In", auth: false},
},
{
name: "photos",
path: "/photos",
component: Photos,
meta: {title: c.subtitle},
meta: {title: c.subtitle, auth: true},
},
{
name: "albums",
path: "/albums",
component: Albums,
meta: {title: "Albums"},
meta: {title: "Albums", auth: true},
},
{
name: "album",
path: "/albums/:uuid",
component: AlbumPhotos,
meta: {title: "Album"},
meta: {title: "Album", auth: true},
},
{
name: "favorites",
path: "/favorites",
component: Photos,
meta: {title: "Favorites"},
meta: {title: "Favorites", auth: true},
props: {staticFilter: {favorites: true}},
},
{
name: "archive",
path: "/archive",
component: Photos,
meta: {title: "Archive"},
meta: {title: "Archive", auth: true},
props: {staticFilter: {archived: true}},
},
{
name: "places",
path: "/places",
component: Places,
meta: {title: "Places"},
meta: {title: "Places", auth: true},
},
{
name: "place",
path: "/places/:q",
component: Places,
meta: {title: "Places"},
meta: {title: "Places", auth: true},
},
{
name: "labels",
path: "/labels",
component: Labels,
meta: {title: "Labels"},
meta: {title: "Labels", auth: true},
},
{
name: "events",
path: "/events",
component: Events,
meta: {title: "Events"},
meta: {title: "Events", auth: true},
},
{
name: "people",
path: "/people",
component: People,
meta: {title: "People"},
meta: {title: "People", auth: true},
},
{
name: "filters",
path: "/filters",
component: Todo,
meta: {title: "Filters"},
meta: {title: "Filters", auth: true},
},
{
name: "library_logs",
@ -139,28 +139,28 @@ export default [
name: "discover",
path: "/discover",
component: Discover,
meta: {title: "Discover", auth: false, background: "application-light"},
meta: {title: "Discover", auth: true, background: "application-light"},
props: {tab: 0},
},
{
name: "discover_similar",
path: "/discover/similar",
component: Discover,
meta: {title: "Discover", auth: false, background: "application-light"},
meta: {title: "Discover", auth: true, background: "application-light"},
props: {tab: 1},
},
{
name: "discover_season",
path: "/discover/season",
component: Discover,
meta: {title: "Discover", auth: false, background: "application-light"},
meta: {title: "Discover", auth: true, background: "application-light"},
props: {tab: 2},
},
{
name: "discover_random",
path: "/discover/random",
component: Discover,
meta: {title: "Discover", auth: false, background: "application-light"},
meta: {title: "Discover", auth: true, background: "application-light"},
props: {tab: 3},
},
{

View file

@ -27,6 +27,11 @@ import (
// GET /api/v1/albums
func GetAlbums(router *gin.RouterGroup, conf *config.Config) {
router.GET("/albums", func(c *gin.Context) {
if Unauthorized(c, conf) {
c.AbortWithStatusJSON(http.StatusUnauthorized, ErrUnauthorized)
return
}
var f form.AlbumSearch
q := query.New(conf.OriginalsPath(), conf.Db())
@ -318,7 +323,6 @@ func RemovePhotosFromAlbum(router *gin.RouterGroup, conf *config.Config) {
// GET /albums/:uuid/download
func DownloadAlbum(router *gin.RouterGroup, conf *config.Config) {
router.GET("/albums/:uuid/download", func(c *gin.Context) {
start := time.Now()
q := query.New(conf.OriginalsPath(), conf.Db())
@ -403,7 +407,7 @@ func DownloadAlbum(router *gin.RouterGroup, conf *config.Config) {
})
}
// POST /api/v1/albums/:uuid/thumbnail/:type
// GET /api/v1/albums/:uuid/thumbnail/:type
//
// Parameters:
// uuid: string Album UUID

View file

@ -17,6 +17,11 @@ import (
// GET /api/v1/geo
func GetGeo(router *gin.RouterGroup, conf *config.Config) {
router.GET("/geo", func(c *gin.Context) {
if Unauthorized(c, conf) {
c.AbortWithStatusJSON(http.StatusUnauthorized, ErrUnauthorized)
return
}
var f form.GeoSearch
q := query.New(conf.OriginalsPath(), conf.Db())

View file

@ -22,6 +22,11 @@ import (
// GET /api/v1/labels
func GetLabels(router *gin.RouterGroup, conf *config.Config) {
router.GET("/labels", func(c *gin.Context) {
if Unauthorized(c, conf) {
c.AbortWithStatusJSON(http.StatusUnauthorized, ErrUnauthorized)
return
}
var f form.LabelSearch
q := query.New(conf.OriginalsPath(), conf.Db())

View file

@ -29,6 +29,11 @@ import (
// favorites: bool Find favorites only
func GetPhotos(router *gin.RouterGroup, conf *config.Config) {
router.GET("/photos", func(c *gin.Context) {
if Unauthorized(c, conf) {
c.AbortWithStatusJSON(http.StatusUnauthorized, ErrUnauthorized)
return
}
var f form.PhotoSearch
q := query.New(conf.OriginalsPath(), conf.Db())

View file

@ -23,6 +23,11 @@ import (
// POST /api/v1/zip
func CreateZip(router *gin.RouterGroup, conf *config.Config) {
router.POST("/zip", func(c *gin.Context) {
if Unauthorized(c, conf) {
c.AbortWithStatusJSON(http.StatusUnauthorized, ErrUnauthorized)
return
}
var f form.PhotoUUIDs
start := time.Now()

View file

@ -19,8 +19,8 @@ type Location struct {
ID string `gorm:"type:varbinary(16);primary_key;auto_increment:false;"`
PlaceID string `gorm:"type:varbinary(16);"`
Place *Place
LocName string `gorm:"type:varchar(100);"`
LocCategory string `gorm:"type:varchar(50);"`
LocName string `gorm:"type:varchar(128);"`
LocCategory string `gorm:"type:varchar(64);"`
LocSource string `gorm:"type:varbinary(16);"`
CreatedAt time.Time
UpdatedAt time.Time

View file

@ -14,8 +14,8 @@ type Photo struct {
ID uint `gorm:"primary_key"`
TakenAt time.Time `gorm:"type:datetime;index:idx_photos_taken_uuid;"`
PhotoUUID string `gorm:"type:varbinary(36);unique_index;index:idx_photos_taken_uuid;"`
PhotoPath string `gorm:"type:varbinary(400);index;"`
PhotoName string `gorm:"type:varbinary(200);"`
PhotoPath string `gorm:"type:varbinary(512);index;"`
PhotoName string `gorm:"type:varbinary(256);"`
PhotoTitle string `json:"PhotoTitle"`
PhotoTitleChanged bool
PhotoDescription string `gorm:"type:text;"`
@ -32,7 +32,7 @@ type Photo struct {
PhotoFocalLength int
PhotoIso int
PhotoFNumber float64
PhotoExposure string `gorm:"type:varbinary(32);"`
PhotoExposure string `gorm:"type:varbinary(64);"`
PhotoViews uint
Camera *Camera
CameraID uint `gorm:"index:idx_photos_camera_lens;"`

View file

@ -11,10 +11,10 @@ import (
// Photo place
type Place struct {
ID string `gorm:"type:varbinary(16);primary_key;auto_increment:false;"`
LocLabel string `gorm:"type:varbinary(500);unique_index;"`
LocCity string `gorm:"type:varchar(100);"`
LocState string `gorm:"type:varchar(100);"`
LocCountry string `gorm:"type:binary(2);"`
LocLabel string `gorm:"type:varbinary(512);unique_index;"`
LocCity string `gorm:"type:varchar(128);"`
LocState string `gorm:"type:varchar(128);"`
LocCountry string `gorm:"type:varbinary(2);"`
LocNotes string `gorm:"type:text;"`
LocFavorite bool
CreatedAt time.Time

View file

@ -21,7 +21,7 @@ func Logger() gin.HandlerFunc {
end := time.Now()
latency := end.Sub(start)
clientIP := c.ClientIP()
// clientIP := c.ClientIP()
method := c.Request.Method
statusCode := c.Writer.Status()
@ -30,18 +30,16 @@ func Logger() gin.HandlerFunc {
}
if statusCode >= 400 {
log.Errorf("%s %s: %s (%3d) [%v]",
log.Errorf("%s %s (%3d) [%v]",
method,
path,
clientIP,
statusCode,
latency,
)
} else {
log.Debugf("%s %s: %s (%3d) [%v]",
log.Debugf("%s %s (%3d) [%v]",
method,
path,
clientIP,
statusCode,
latency,
)