mirror of
https://github.com/photoprism/photoprism.git
synced 2025-12-12 00:34:13 +01:00
Auth: Add "node" and "portal" roles, refactor session entity #98
Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
@@ -70,7 +70,7 @@ func GetAlbum(router *gin.RouterGroup) {
|
||||
}
|
||||
|
||||
// Other restricted users can only access their own or shared content.
|
||||
if s.User().HasSharedAccessOnly(acl.ResourceAlbums) && album.CreatedBy != s.UserUID && !s.HasShare(uid) {
|
||||
if s.GetUser().HasSharedAccessOnly(acl.ResourceAlbums) && album.CreatedBy != s.UserUID && !s.HasShare(uid) {
|
||||
AbortForbidden(c)
|
||||
return
|
||||
}
|
||||
@@ -171,7 +171,7 @@ func UpdateAlbum(router *gin.RouterGroup) {
|
||||
uid := clean.UID(c.Param("uid"))
|
||||
|
||||
// Visitors and other restricted users can only access shared content.
|
||||
if (s.User().HasSharedAccessOnly(acl.ResourceAlbums) || s.NotRegistered()) && !s.HasShare(uid) {
|
||||
if (s.GetUser().HasSharedAccessOnly(acl.ResourceAlbums) || s.NotRegistered()) && !s.HasShare(uid) {
|
||||
AbortForbidden(c)
|
||||
return
|
||||
}
|
||||
@@ -242,7 +242,7 @@ func DeleteAlbum(router *gin.RouterGroup) {
|
||||
uid := clean.UID(c.Param("uid"))
|
||||
|
||||
// Visitors and other restricted users can only access shared content.
|
||||
if (s.User().HasSharedAccessOnly(acl.ResourceAlbums) || s.NotRegistered()) && !s.HasShare(uid) {
|
||||
if (s.GetUser().HasSharedAccessOnly(acl.ResourceAlbums) || s.NotRegistered()) && !s.HasShare(uid) {
|
||||
AbortForbidden(c)
|
||||
return
|
||||
}
|
||||
@@ -317,7 +317,7 @@ func LikeAlbum(router *gin.RouterGroup) {
|
||||
uid := clean.UID(c.Param("uid"))
|
||||
|
||||
// Visitors and other restricted users can only access shared content.
|
||||
if (s.User().HasSharedAccessOnly(acl.ResourceAlbums) || s.NotRegistered()) && !s.HasShare(uid) {
|
||||
if (s.GetUser().HasSharedAccessOnly(acl.ResourceAlbums) || s.NotRegistered()) && !s.HasShare(uid) {
|
||||
AbortForbidden(c)
|
||||
return
|
||||
}
|
||||
@@ -368,7 +368,7 @@ func DislikeAlbum(router *gin.RouterGroup) {
|
||||
uid := clean.UID(c.Param("uid"))
|
||||
|
||||
// Visitors and other restricted users can only access shared content.
|
||||
if (s.User().HasSharedAccessOnly(acl.ResourceAlbums) || s.NotRegistered()) && !s.HasShare(uid) {
|
||||
if (s.GetUser().HasSharedAccessOnly(acl.ResourceAlbums) || s.NotRegistered()) && !s.HasShare(uid) {
|
||||
AbortForbidden(c)
|
||||
return
|
||||
}
|
||||
@@ -421,7 +421,7 @@ func CloneAlbums(router *gin.RouterGroup) {
|
||||
uid := clean.UID(c.Param("uid"))
|
||||
|
||||
// Visitors and other restricted users can only access shared content.
|
||||
if (s.User().HasSharedAccessOnly(acl.ResourceAlbums) || s.NotRegistered()) && !s.HasShare(uid) {
|
||||
if (s.GetUser().HasSharedAccessOnly(acl.ResourceAlbums) || s.NotRegistered()) && !s.HasShare(uid) {
|
||||
AbortForbidden(c)
|
||||
return
|
||||
}
|
||||
@@ -507,7 +507,7 @@ func AddPhotosToAlbum(router *gin.RouterGroup) {
|
||||
uid := clean.UID(c.Param("uid"))
|
||||
|
||||
// Visitors and other restricted users can only access shared content.
|
||||
if (s.User().HasSharedAccessOnly(acl.ResourceAlbums) || s.NotRegistered()) && !s.HasShare(uid) {
|
||||
if (s.GetUser().HasSharedAccessOnly(acl.ResourceAlbums) || s.NotRegistered()) && !s.HasShare(uid) {
|
||||
AbortForbidden(c)
|
||||
return
|
||||
}
|
||||
@@ -622,7 +622,7 @@ func RemovePhotosFromAlbum(router *gin.RouterGroup) {
|
||||
uid := clean.UID(c.Param("uid"))
|
||||
|
||||
// Visitors and other restricted users can only access shared content.
|
||||
if (s.User().HasSharedAccessOnly(acl.ResourceAlbums) || s.NotRegistered()) && !s.HasShare(uid) {
|
||||
if (s.GetUser().HasSharedAccessOnly(acl.ResourceAlbums) || s.NotRegistered()) && !s.HasShare(uid) {
|
||||
AbortForbidden(c)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -44,31 +44,31 @@ func AuthAny(c *gin.Context, resource acl.Resource, perms acl.Permissions) (s *e
|
||||
if s.IsClient() {
|
||||
// Check the resource and required permissions against the session scope.
|
||||
if s.InsufficientScope(resource, perms) {
|
||||
event.AuditErr([]string{clientIp, "client %s", "session %s", "access %s", authn.ErrInsufficientScope.Error()}, clean.Log(s.ClientInfo()), s.RefID, string(resource))
|
||||
event.AuditErr([]string{clientIp, "client %s", "session %s", "access %s", authn.ErrInsufficientScope.Error()}, clean.Log(s.GetClientInfo()), s.RefID, string(resource))
|
||||
return entity.SessionStatusForbidden()
|
||||
}
|
||||
|
||||
// Check request authorization against client application ACL rules.
|
||||
if acl.Rules.DenyAll(resource, s.ClientRole(), perms) {
|
||||
event.AuditErr([]string{clientIp, "client %s", "session %s", "%s %s", authn.Denied}, clean.Log(s.ClientInfo()), s.RefID, perms.String(), string(resource))
|
||||
if acl.Rules.DenyAll(resource, s.GetClientRole(), perms) {
|
||||
event.AuditErr([]string{clientIp, "client %s", "session %s", "%s %s", authn.Denied}, clean.Log(s.GetClientInfo()), s.RefID, perms.String(), string(resource))
|
||||
return entity.SessionStatusForbidden()
|
||||
}
|
||||
|
||||
// Also check the request authorization against the user's ACL rules?
|
||||
if s.NoUser() {
|
||||
// Allow access based on the ACL defaults for client applications.
|
||||
event.AuditInfo([]string{clientIp, "client %s", "session %s", "%s %s", authn.Granted}, clean.Log(s.ClientInfo()), s.RefID, perms.String(), string(resource))
|
||||
} else if u := s.User(); !u.IsDisabled() && !u.IsUnknown() && u.IsRegistered() {
|
||||
event.AuditInfo([]string{clientIp, "client %s", "session %s", "%s %s", authn.Granted}, clean.Log(s.GetClientInfo()), s.RefID, perms.String(), string(resource))
|
||||
} else if u := s.GetUser(); !u.IsDisabled() && !u.IsUnknown() && u.IsRegistered() {
|
||||
if acl.Rules.DenyAll(resource, u.AclRole(), perms) {
|
||||
event.AuditErr([]string{clientIp, "client %s", "session %s", "%s %s as %s", authn.Denied}, clean.Log(s.ClientInfo()), s.RefID, perms.String(), string(resource), u.String())
|
||||
event.AuditErr([]string{clientIp, "client %s", "session %s", "%s %s as %s", authn.Denied}, clean.Log(s.GetClientInfo()), s.RefID, perms.String(), string(resource), u.String())
|
||||
return entity.SessionStatusForbidden()
|
||||
}
|
||||
|
||||
// Allow access based on the user role.
|
||||
event.AuditInfo([]string{clientIp, "client %s", "session %s", "%s %s as %s", authn.Granted}, clean.Log(s.ClientInfo()), s.RefID, perms.String(), string(resource), u.String())
|
||||
event.AuditInfo([]string{clientIp, "client %s", "session %s", "%s %s as %s", authn.Granted}, clean.Log(s.GetClientInfo()), s.RefID, perms.String(), string(resource), u.String())
|
||||
} else {
|
||||
// Deny access if it is not a regular user account or the account has been disabled.
|
||||
event.AuditErr([]string{clientIp, "client %s", "session %s", "%s %s as unauthorized user", authn.Denied}, clean.Log(s.ClientInfo()), s.RefID, perms.String(), string(resource))
|
||||
event.AuditErr([]string{clientIp, "client %s", "session %s", "%s %s as unauthorized user", authn.Denied}, clean.Log(s.GetClientInfo()), s.RefID, perms.String(), string(resource))
|
||||
return entity.SessionStatusForbidden()
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ func AuthAny(c *gin.Context, resource acl.Resource, perms acl.Permissions) (s *e
|
||||
}
|
||||
|
||||
// Otherwise, perform a regular ACL authorization check based on the user role.
|
||||
if u := s.User(); u.IsUnknown() || u.IsDisabled() {
|
||||
if u := s.GetUser(); u.IsUnknown() || u.IsDisabled() {
|
||||
event.AuditWarn([]string{clientIp, "session %s", "%s %s as unauthorized user", authn.Denied}, s.RefID, perms.String(), string(resource))
|
||||
return entity.SessionStatusUnauthorized()
|
||||
} else if acl.Rules.DenyAll(resource, u.AclRole(), perms) {
|
||||
|
||||
@@ -32,7 +32,7 @@ func TestAuth(t *testing.T) {
|
||||
// Check successful authorization in public mode.
|
||||
s := Auth(c, acl.ResourceFiles, acl.ActionUpdate)
|
||||
assert.NotNil(t, s)
|
||||
assert.Equal(t, "admin", s.Username())
|
||||
assert.Equal(t, "admin", s.GetUserName())
|
||||
assert.Equal(t, session.PublicID, s.ID)
|
||||
assert.Equal(t, http.StatusOK, s.HttpStatus())
|
||||
assert.False(t, s.Abort(c))
|
||||
@@ -40,7 +40,7 @@ func TestAuth(t *testing.T) {
|
||||
// Check failed authorization in public mode.
|
||||
s = Auth(c, acl.ResourceUsers, acl.ActionUpload)
|
||||
assert.NotNil(t, s)
|
||||
assert.Equal(t, "", s.Username())
|
||||
assert.Equal(t, "", s.GetUserName())
|
||||
assert.Equal(t, "", s.ID)
|
||||
assert.Equal(t, http.StatusForbidden, s.HttpStatus())
|
||||
assert.True(t, s.Abort(c))
|
||||
@@ -66,7 +66,7 @@ func TestAuthAny(t *testing.T) {
|
||||
// Check successful authorization in public mode.
|
||||
s := AuthAny(c, acl.ResourceFiles, acl.Permissions{acl.ActionUpdate})
|
||||
assert.NotNil(t, s)
|
||||
assert.Equal(t, "admin", s.Username())
|
||||
assert.Equal(t, "admin", s.GetUserName())
|
||||
assert.Equal(t, session.PublicID, s.ID)
|
||||
assert.Equal(t, http.StatusOK, s.HttpStatus())
|
||||
assert.False(t, s.Abort(c))
|
||||
@@ -74,7 +74,7 @@ func TestAuthAny(t *testing.T) {
|
||||
// Check failed authorization in public mode.
|
||||
s = AuthAny(c, acl.ResourceUsers, acl.Permissions{acl.ActionUpload})
|
||||
assert.NotNil(t, s)
|
||||
assert.Equal(t, "", s.Username())
|
||||
assert.Equal(t, "", s.GetUserName())
|
||||
assert.Equal(t, "", s.ID)
|
||||
assert.Equal(t, http.StatusForbidden, s.HttpStatus())
|
||||
assert.True(t, s.Abort(c))
|
||||
@@ -82,7 +82,7 @@ func TestAuthAny(t *testing.T) {
|
||||
// Check successful authorization with multiple actions in public mode.
|
||||
s = AuthAny(c, acl.ResourceUsers, acl.Permissions{acl.ActionUpload, acl.ActionView})
|
||||
assert.NotNil(t, s)
|
||||
assert.Equal(t, "admin", s.Username())
|
||||
assert.Equal(t, "admin", s.GetUserName())
|
||||
assert.Equal(t, session.PublicID, s.ID)
|
||||
assert.Equal(t, http.StatusOK, s.HttpStatus())
|
||||
assert.False(t, s.Abort(c))
|
||||
|
||||
@@ -323,7 +323,7 @@ func BatchPhotosDelete(router *gin.RouterGroup) {
|
||||
var err error
|
||||
|
||||
// Abort if user wants to delete all but does not have sufficient privileges.
|
||||
if frm.All && !acl.Rules.AllowAll(acl.ResourcePhotos, s.UserRole(), acl.Permissions{acl.AccessAll, acl.ActionManage}) {
|
||||
if frm.All && !acl.Rules.AllowAll(acl.ResourcePhotos, s.GetUserRole(), acl.Permissions{acl.AccessAll, acl.ActionManage}) {
|
||||
AbortForbidden(c)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -72,9 +72,9 @@ func SaveSettings(router *gin.RouterGroup) {
|
||||
var settings *customize.Settings
|
||||
|
||||
// Only super admins can change global config defaults.
|
||||
if s.User().IsSuperAdmin() {
|
||||
if s.GetUser().IsSuperAdmin() {
|
||||
// Update global defaults and user preferences.
|
||||
user := s.User()
|
||||
user := s.GetUser()
|
||||
settings = conf.Settings()
|
||||
|
||||
// Set values from request.
|
||||
@@ -103,7 +103,7 @@ func SaveSettings(router *gin.RouterGroup) {
|
||||
UpdateClientConfig()
|
||||
} else {
|
||||
// Update user preferences without changing global defaults.
|
||||
user := s.User()
|
||||
user := s.GetUser()
|
||||
|
||||
if user == nil {
|
||||
AbortUnexpectedError(c)
|
||||
@@ -119,7 +119,7 @@ func SaveSettings(router *gin.RouterGroup) {
|
||||
}
|
||||
|
||||
// Update user preferences.
|
||||
if acl.Rules.DenyAll(acl.ResourceSettings, s.UserRole(), acl.Permissions{acl.ActionUpdate, acl.ActionManage}) {
|
||||
if acl.Rules.DenyAll(acl.ResourceSettings, s.GetUserRole(), acl.Permissions{acl.ActionUpdate, acl.ActionManage}) {
|
||||
c.JSON(http.StatusOK, user.Settings().Apply(settings).ApplyTo(conf.Settings().ApplyACL(acl.Rules, user.AclRole())))
|
||||
return
|
||||
} else if err := user.Settings().Apply(settings).Save(); err != nil {
|
||||
|
||||
@@ -51,7 +51,7 @@ func Connect(router *gin.RouterGroup) {
|
||||
s := Auth(c, acl.ResourceConfig, acl.ActionUpdate)
|
||||
|
||||
if !s.IsSuperAdmin() {
|
||||
log.Errorf("connect: %s not authorized", clean.Log(s.User().UserName))
|
||||
log.Errorf("connect: %s not authorized", clean.Log(s.GetUser().UserName))
|
||||
AbortForbidden(c)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ func SearchFolders(router *gin.RouterGroup, urlPath, rootName, rootPath string)
|
||||
return
|
||||
}
|
||||
|
||||
user := s.User()
|
||||
user := s.GetUser()
|
||||
aclRole := user.AclRole()
|
||||
|
||||
// Exclude private content?
|
||||
|
||||
@@ -85,9 +85,9 @@ func StartImport(router *gin.RouterGroup) {
|
||||
// To avoid conflicts, uploads are imported from "import_path/upload/session_ref/timestamp".
|
||||
if token := path.Base(srcFolder); token != "" && path.Dir(srcFolder) == UploadPath {
|
||||
srcFolder = path.Join(UploadPath, s.RefID+token)
|
||||
event.AuditInfo([]string{ClientIP(c), "session %s", "import uploads from %s as %s", authn.Granted}, s.RefID, clean.Log(srcFolder), s.UserRole().String())
|
||||
} else if acl.Rules.Deny(acl.ResourceFiles, s.UserRole(), acl.ActionManage) {
|
||||
event.AuditErr([]string{ClientIP(c), "session %s", "import files from %s as %s", authn.Denied}, s.RefID, clean.Log(srcFolder), s.UserRole().String())
|
||||
event.AuditInfo([]string{ClientIP(c), "session %s", "import uploads from %s as %s", authn.Granted}, s.RefID, clean.Log(srcFolder), s.GetUserRole().String())
|
||||
} else if acl.Rules.Deny(acl.ResourceFiles, s.GetUserRole(), acl.ActionManage) {
|
||||
event.AuditErr([]string{ClientIP(c), "session %s", "import files from %s as %s", authn.Denied}, s.RefID, clean.Log(srcFolder), s.GetUserRole().String())
|
||||
AbortForbidden(c)
|
||||
return
|
||||
}
|
||||
@@ -100,7 +100,7 @@ func StartImport(router *gin.RouterGroup) {
|
||||
|
||||
// Get destination folder.
|
||||
var destFolder string
|
||||
if destFolder = s.User().GetUploadPath(); destFolder == "" {
|
||||
if destFolder = s.GetUser().GetUploadPath(); destFolder == "" {
|
||||
destFolder = conf.ImportDest()
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ func StartImport(router *gin.RouterGroup) {
|
||||
|
||||
// Add imported files to albums if allowed.
|
||||
if len(frm.Albums) > 0 &&
|
||||
acl.Rules.AllowAny(acl.ResourceAlbums, s.UserRole(), acl.Permissions{acl.ActionCreate, acl.ActionUpload}) {
|
||||
acl.Rules.AllowAny(acl.ResourceAlbums, s.GetUserRole(), acl.Permissions{acl.ActionCreate, acl.ActionUpload}) {
|
||||
log.Debugf("import: adding files to album %s", clean.Log(strings.Join(frm.Albums, " and ")))
|
||||
opt.Albums = frm.Albums
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ func StartIndexing(router *gin.RouterGroup) {
|
||||
skipArchived := settings.Index.SkipArchived
|
||||
|
||||
indOpt := photoprism.NewIndexOptions(filepath.Clean(frm.Path), frm.Rescan, convert, true, false, skipArchived)
|
||||
indOpt.SetUser(s.User())
|
||||
indOpt.SetUser(s.GetUser())
|
||||
|
||||
if len(indOpt.Path) > 1 {
|
||||
event.InfoMsg(i18n.MsgIndexingFiles, clean.Log(indOpt.Path))
|
||||
@@ -120,7 +120,7 @@ func StartIndexing(router *gin.RouterGroup) {
|
||||
}
|
||||
|
||||
// Delete orphaned index entries, sidecar files and thumbnails?
|
||||
if frm.Cleanup && s.User().IsAdmin() {
|
||||
if frm.Cleanup && s.GetUser().IsAdmin() {
|
||||
event.Publish("index.updating", event.Data{
|
||||
"uid": indOpt.UID,
|
||||
"action": indOpt.Action,
|
||||
|
||||
@@ -61,14 +61,14 @@ func OAuthRevoke(router *gin.RouterGroup) {
|
||||
// Set log role and actor based on the session referenced in request header.
|
||||
sUserUID = s.UserUID
|
||||
if s.IsClient() {
|
||||
role = s.ClientRole()
|
||||
actor = fmt.Sprintf("client %s", clean.Log(s.ClientInfo()))
|
||||
} else if username := s.Username(); username != "" {
|
||||
role = s.UserRole()
|
||||
role = s.GetClientRole()
|
||||
actor = fmt.Sprintf("client %s", clean.Log(s.GetClientInfo()))
|
||||
} else if username := s.GetUserName(); username != "" {
|
||||
role = s.GetUserRole()
|
||||
actor = fmt.Sprintf("user %s", clean.Log(username))
|
||||
} else {
|
||||
role = s.UserRole()
|
||||
actor = fmt.Sprintf("unknown %s", s.UserRole().String())
|
||||
role = s.GetUserRole()
|
||||
actor = fmt.Sprintf("unknown %s", s.GetUserRole().String())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,14 +113,14 @@ func OAuthRevoke(router *gin.RouterGroup) {
|
||||
// If not already set, get the log role and actor from the session to be revoked.
|
||||
if sess != nil && role == acl.RoleNone {
|
||||
if sess.IsClient() {
|
||||
role = sess.ClientRole()
|
||||
actor = fmt.Sprintf("client %s", clean.Log(sess.ClientInfo()))
|
||||
} else if username := sess.Username(); username != "" {
|
||||
role = s.UserRole()
|
||||
role = sess.GetClientRole()
|
||||
actor = fmt.Sprintf("client %s", clean.Log(sess.GetClientInfo()))
|
||||
} else if username := sess.GetUserName(); username != "" {
|
||||
role = s.GetUserRole()
|
||||
actor = fmt.Sprintf("user %s", clean.Log(username))
|
||||
} else {
|
||||
role = sess.UserRole()
|
||||
actor = fmt.Sprintf("unknown %s", sess.UserRole().String())
|
||||
role = sess.GetUserRole()
|
||||
actor = fmt.Sprintf("unknown %s", sess.GetUserRole().String())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -127,17 +127,17 @@ func OAuthToken(router *gin.RouterGroup) {
|
||||
if s == nil {
|
||||
AbortInvalidCredentials(c)
|
||||
return
|
||||
} else if s.Username() == "" || s.IsClient() || !s.IsRegistered() {
|
||||
} else if s.GetUserName() == "" || s.IsClient() || !s.IsRegistered() {
|
||||
event.AuditErr([]string{clientIp, "oauth2", actor, action, authn.ErrInvalidGrantType.Error()})
|
||||
AbortInvalidCredentials(c)
|
||||
return
|
||||
}
|
||||
|
||||
actor = fmt.Sprintf("user %s", clean.Log(s.Username()))
|
||||
actor = fmt.Sprintf("user %s", clean.Log(s.GetUserName()))
|
||||
|
||||
if s.User().Provider().SupportsPasswordAuthentication() {
|
||||
if s.GetUser().Provider().SupportsPasswordAuthentication() {
|
||||
loginForm := form.Login{
|
||||
Username: s.Username(),
|
||||
Username: s.GetUserName(),
|
||||
Password: frm.Password,
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ func OAuthToken(router *gin.RouterGroup) {
|
||||
event.AuditErr([]string{clientIp, "oauth2", actor, action, "%s"}, strings.ToLower(clean.Error(authErr)))
|
||||
AbortInvalidCredentials(c)
|
||||
return
|
||||
} else if !authUser.Equal(s.User()) {
|
||||
} else if !authUser.Equal(s.GetUser()) {
|
||||
event.AuditErr([]string{clientIp, "oauth2", actor, action, authn.ErrUserDoesNotMatch.Error()})
|
||||
AbortInvalidCredentials(c)
|
||||
return
|
||||
@@ -164,7 +164,7 @@ func OAuthToken(router *gin.RouterGroup) {
|
||||
frm.GrantType = authn.GrantSession
|
||||
}
|
||||
|
||||
sess = entity.NewClientSession(frm.ClientName, frm.ExpiresIn, frm.Scope, frm.GrantType, s.User())
|
||||
sess = entity.NewClientSession(frm.ClientName, frm.ExpiresIn, frm.Scope, frm.GrantType, s.GetUser())
|
||||
|
||||
// Return the reserved request rate limit tokens after successful authentication.
|
||||
r.Success()
|
||||
@@ -201,7 +201,8 @@ func OAuthToken(router *gin.RouterGroup) {
|
||||
"access_token": sess.AuthToken(),
|
||||
"token_type": sess.AuthTokenType(),
|
||||
"expires_in": sess.ExpiresIn(),
|
||||
"client_name": sess.ClientName,
|
||||
"client_name": sess.GetClientName(),
|
||||
"client_role": sess.GetClientRole(),
|
||||
"scope": sess.Scope(),
|
||||
}
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ func SearchPhotos(router *gin.RouterGroup) {
|
||||
// Ignore private flag if feature is disabled.
|
||||
if frm.Scope == "" &&
|
||||
settings.Features.Review &&
|
||||
acl.Rules.Deny(acl.ResourcePhotos, s.UserRole(), acl.ActionManage) {
|
||||
acl.Rules.Deny(acl.ResourcePhotos, s.GetUserRole(), acl.ActionManage) {
|
||||
frm.Quality = 3
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ func SearchGeo(router *gin.RouterGroup) {
|
||||
// Ignore private flag if feature is disabled.
|
||||
if frm.Scope == "" &&
|
||||
settings.Features.Review &&
|
||||
acl.Rules.Deny(acl.ResourcePhotos, s.UserRole(), acl.ActionManage) {
|
||||
acl.Rules.Deny(acl.ResourcePhotos, s.GetUserRole(), acl.ActionManage) {
|
||||
frm.Quality = 3
|
||||
}
|
||||
|
||||
|
||||
@@ -39,11 +39,11 @@ func LikePhoto(router *gin.RouterGroup) {
|
||||
return
|
||||
}
|
||||
|
||||
if get.Config().Develop() && acl.Rules.Allow(acl.ResourcePhotos, s.UserRole(), acl.ActionReact) {
|
||||
logWarn("react", m.React(s.User(), react.Find("love")))
|
||||
if get.Config().Develop() && acl.Rules.Allow(acl.ResourcePhotos, s.GetUserRole(), acl.ActionReact) {
|
||||
logWarn("react", m.React(s.GetUser(), react.Find("love")))
|
||||
}
|
||||
|
||||
if acl.Rules.Allow(acl.ResourcePhotos, s.UserRole(), acl.ActionUpdate) {
|
||||
if acl.Rules.Allow(acl.ResourcePhotos, s.GetUserRole(), acl.ActionUpdate) {
|
||||
err = m.SetFavorite(true)
|
||||
|
||||
if err != nil {
|
||||
@@ -87,11 +87,11 @@ func DislikePhoto(router *gin.RouterGroup) {
|
||||
return
|
||||
}
|
||||
|
||||
if get.Config().Develop() && acl.Rules.Allow(acl.ResourcePhotos, s.UserRole(), acl.ActionReact) {
|
||||
logWarn("react", m.UnReact(s.User()))
|
||||
if get.Config().Develop() && acl.Rules.Allow(acl.ResourcePhotos, s.GetUserRole(), acl.ActionReact) {
|
||||
logWarn("react", m.UnReact(s.GetUser()))
|
||||
}
|
||||
|
||||
if acl.Rules.Allow(acl.ResourcePhotos, s.UserRole(), acl.ActionUpdate) {
|
||||
if acl.Rules.Allow(acl.ResourcePhotos, s.GetUserRole(), acl.ActionUpdate) {
|
||||
err = m.SetFavorite(false)
|
||||
|
||||
if err != nil {
|
||||
|
||||
@@ -87,7 +87,7 @@ func CreateSession(router *gin.RouterGroup) {
|
||||
|
||||
// Check authentication credentials.
|
||||
if err = sess.LogIn(frm, c); err != nil {
|
||||
if sess.Method().IsNot(authn.Method2FA) {
|
||||
if sess.GetMethod().IsNot(authn.Method2FA) {
|
||||
c.AbortWithStatusJSON(sess.HttpStatus(), gin.H{"error": i18n.Msg(i18n.ErrInvalidCredentials)})
|
||||
} else if errors.Is(err, authn.ErrPasscodeRequired) {
|
||||
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": err.Error(), "code": 32, "message": i18n.Msg(i18n.ErrPasscodeRequired)})
|
||||
|
||||
@@ -51,27 +51,27 @@ func DeleteSession(router *gin.RouterGroup) {
|
||||
|
||||
// Only admins may delete other sessions by ref id.
|
||||
if rnd.IsRefID(id) {
|
||||
if !acl.Rules.AllowAll(acl.ResourceSessions, s.UserRole(), acl.Permissions{acl.AccessAll, acl.ActionManage}) {
|
||||
event.AuditErr([]string{clientIp, "session %s", "delete %s as %s", authn.Denied}, s.RefID, acl.ResourceSessions.String(), s.UserRole())
|
||||
if !acl.Rules.AllowAll(acl.ResourceSessions, s.GetUserRole(), acl.Permissions{acl.AccessAll, acl.ActionManage}) {
|
||||
event.AuditErr([]string{clientIp, "session %s", "delete %s as %s", authn.Denied}, s.RefID, acl.ResourceSessions.String(), s.GetUserRole())
|
||||
Abort(c, http.StatusForbidden, i18n.ErrForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
event.AuditInfo([]string{clientIp, "session %s", "delete %s as %s", authn.Granted}, s.RefID, acl.ResourceSessions.String(), s.UserRole())
|
||||
event.AuditInfo([]string{clientIp, "session %s", "delete %s as %s", authn.Granted}, s.RefID, acl.ResourceSessions.String(), s.GetUserRole())
|
||||
|
||||
if s = entity.FindSessionByRefID(id); s == nil {
|
||||
Abort(c, http.StatusNotFound, i18n.ErrNotFound)
|
||||
return
|
||||
}
|
||||
} else if id != "" && s.ID != id {
|
||||
event.AuditWarn([]string{clientIp, "session %s", "delete %s as %s", "ids do not match"}, s.RefID, acl.ResourceSessions.String(), s.UserRole())
|
||||
event.AuditWarn([]string{clientIp, "session %s", "delete %s as %s", "ids do not match"}, s.RefID, acl.ResourceSessions.String(), s.GetUserRole())
|
||||
Abort(c, http.StatusForbidden, i18n.ErrForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete session cache and database record.
|
||||
if err := s.Delete(); err != nil {
|
||||
event.AuditErr([]string{clientIp, "session %s", "delete session as %s", "%s"}, s.RefID, s.UserRole(), err)
|
||||
event.AuditErr([]string{clientIp, "session %s", "delete session as %s", "%s"}, s.RefID, s.GetUserRole(), err)
|
||||
} else {
|
||||
event.AuditDebug([]string{clientIp, "session %s", "deleted"}, s.RefID)
|
||||
}
|
||||
|
||||
@@ -32,10 +32,10 @@ func GetSessionResponse(authToken string, sess *entity.Session, conf *config.Cli
|
||||
"status": StatusSuccess,
|
||||
"session_id": sess.ID,
|
||||
"expires_in": sess.ExpiresIn(),
|
||||
"provider": sess.Provider().String(),
|
||||
"provider": sess.GetProvider().String(),
|
||||
"scope": sess.Scope(),
|
||||
"user": sess.User(),
|
||||
"data": sess.Data(),
|
||||
"user": sess.GetUser(),
|
||||
"data": sess.GetData(),
|
||||
"config": conf,
|
||||
}
|
||||
} else {
|
||||
@@ -48,10 +48,10 @@ func GetSessionResponse(authToken string, sess *entity.Session, conf *config.Cli
|
||||
"access_token": authToken,
|
||||
"token_type": sess.AuthTokenType(),
|
||||
"expires_in": sess.ExpiresIn(),
|
||||
"provider": sess.Provider().String(),
|
||||
"provider": sess.GetProvider().String(),
|
||||
"scope": sess.Scope(),
|
||||
"user": sess.User(),
|
||||
"data": sess.Data(),
|
||||
"user": sess.GetUser(),
|
||||
"data": sess.GetData(),
|
||||
"config": conf,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,9 +37,9 @@ func TestGetSessionResponse(t *testing.T) {
|
||||
assert.Equal(t, sess.AuthToken(), result["access_token"])
|
||||
assert.Equal(t, sess.AuthTokenType(), result["token_type"])
|
||||
assert.Equal(t, sess.ExpiresIn(), result["expires_in"])
|
||||
assert.Equal(t, sess.Provider().String(), result["provider"])
|
||||
assert.Equal(t, sess.User(), result["user"])
|
||||
assert.Equal(t, sess.Data(), result["data"])
|
||||
assert.Equal(t, sess.GetProvider().String(), result["provider"])
|
||||
assert.Equal(t, sess.GetUser(), result["user"])
|
||||
assert.Equal(t, sess.GetData(), result["data"])
|
||||
assert.Equal(t, conf, result["config"])
|
||||
})
|
||||
t.Run("NoAuthToken", func(t *testing.T) {
|
||||
@@ -56,9 +56,9 @@ func TestGetSessionResponse(t *testing.T) {
|
||||
assert.Nil(t, result["access_token"])
|
||||
assert.Nil(t, result["token_type"])
|
||||
assert.Equal(t, sess.ExpiresIn(), result["expires_in"])
|
||||
assert.Equal(t, sess.Provider().String(), result["provider"])
|
||||
assert.Equal(t, sess.User(), result["user"])
|
||||
assert.Equal(t, sess.Data(), result["data"])
|
||||
assert.Equal(t, sess.GetProvider().String(), result["provider"])
|
||||
assert.Equal(t, sess.GetUser(), result["user"])
|
||||
assert.Equal(t, sess.GetData(), result["data"])
|
||||
assert.Equal(t, conf, result["config"])
|
||||
})
|
||||
}
|
||||
|
||||
@@ -37,11 +37,11 @@ func UploadUserAvatar(router *gin.RouterGroup) {
|
||||
}
|
||||
|
||||
// Check if the session user is has user management privileges.
|
||||
isAdmin := acl.Rules.AllowAll(acl.ResourceUsers, s.UserRole(), acl.Permissions{acl.AccessAll, acl.ActionManage})
|
||||
isAdmin := acl.Rules.AllowAll(acl.ResourceUsers, s.GetUserRole(), acl.Permissions{acl.AccessAll, acl.ActionManage})
|
||||
uid := clean.UID(c.Param("uid"))
|
||||
|
||||
// Users may only change their own avatar.
|
||||
if !isAdmin && s.User().UserUID != uid {
|
||||
if !isAdmin && s.GetUser().UserUID != uid {
|
||||
event.AuditErr([]string{ClientIP(c), "session %s", "upload avatar", "user does not match"}, s.RefID)
|
||||
AbortForbidden(c)
|
||||
return
|
||||
|
||||
@@ -243,7 +243,7 @@ func checkUserPasscodeAuth(c *gin.Context, action acl.Permission) (*entity.Sessi
|
||||
uid := clean.UID(c.Param("uid"))
|
||||
|
||||
// Get user from session.
|
||||
user := s.User()
|
||||
user := s.GetUser()
|
||||
|
||||
// Regular users can only set up a passcode for their own account.
|
||||
if user.UserUID != uid || !user.CanLogIn() {
|
||||
|
||||
@@ -49,18 +49,18 @@ func UpdateUserPassword(router *gin.RouterGroup) {
|
||||
}
|
||||
|
||||
// Check if the current user has management privileges.
|
||||
isAdmin := acl.Rules.AllowAll(acl.ResourceUsers, s.UserRole(), acl.Permissions{acl.AccessAll, acl.ActionManage})
|
||||
isSuperAdmin := isAdmin && s.User().IsSuperAdmin()
|
||||
isAdmin := acl.Rules.AllowAll(acl.ResourceUsers, s.GetUserRole(), acl.Permissions{acl.AccessAll, acl.ActionManage})
|
||||
isSuperAdmin := isAdmin && s.GetUser().IsSuperAdmin()
|
||||
uid := clean.UID(c.Param("uid"))
|
||||
|
||||
var u *entity.User
|
||||
|
||||
// Regular users may only change their own password.
|
||||
if !isAdmin && s.User().UserUID != uid {
|
||||
if !isAdmin && s.GetUser().UserUID != uid {
|
||||
AbortForbidden(c)
|
||||
return
|
||||
} else if s.User().UserUID == uid {
|
||||
u = s.User()
|
||||
} else if s.GetUser().UserUID == uid {
|
||||
u = s.GetUser()
|
||||
isAdmin = false
|
||||
isSuperAdmin = false
|
||||
} else if u = entity.FindUserByUID(uid); u == nil {
|
||||
@@ -94,7 +94,7 @@ func UpdateUserPassword(router *gin.RouterGroup) {
|
||||
}
|
||||
|
||||
// Update tokens if user matches with session.
|
||||
if s.User().UserUID == u.GetUID() {
|
||||
if s.GetUser().UserUID == u.GetUID() {
|
||||
s.SetPreviewToken(u.PreviewToken)
|
||||
s.SetDownloadToken(u.DownloadToken)
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ func UpdateUser(router *gin.RouterGroup) {
|
||||
}
|
||||
|
||||
// Check if the session user has user management privileges.
|
||||
isAdmin := acl.Rules.AllowAll(acl.ResourceUsers, s.UserRole(), acl.Permissions{acl.AccessAll, acl.ActionManage})
|
||||
isAdmin := acl.Rules.AllowAll(acl.ResourceUsers, s.GetUserRole(), acl.Permissions{acl.AccessAll, acl.ActionManage})
|
||||
privilegeLevelChange := isAdmin && m.PrivilegeLevelChange(f)
|
||||
|
||||
// Check if the user account quota has been exceeded.
|
||||
@@ -74,7 +74,7 @@ func UpdateUser(router *gin.RouterGroup) {
|
||||
}
|
||||
|
||||
// Get user from session.
|
||||
u := s.User()
|
||||
u := s.GetUser()
|
||||
|
||||
// Save model with values from form.
|
||||
if err = m.SaveForm(f, u); err != nil {
|
||||
|
||||
@@ -49,7 +49,7 @@ func UploadUserFiles(router *gin.RouterGroup) {
|
||||
uid := clean.UID(c.Param("uid"))
|
||||
|
||||
// Users may only upload files for their own account.
|
||||
if s.User().UserUID != uid {
|
||||
if s.GetUser().UserUID != uid {
|
||||
event.AuditErr([]string{ClientIP(c), "session %s", "upload files", "user does not match"}, s.RefID)
|
||||
AbortForbidden(c)
|
||||
return
|
||||
@@ -264,7 +264,7 @@ func ProcessUserUpload(router *gin.RouterGroup) {
|
||||
}
|
||||
|
||||
// Users may only upload their own files.
|
||||
if s.User().UserUID != clean.UID(c.Param("uid")) {
|
||||
if s.GetUser().UserUID != clean.UID(c.Param("uid")) {
|
||||
AbortForbidden(c)
|
||||
return
|
||||
}
|
||||
@@ -299,7 +299,7 @@ func ProcessUserUpload(router *gin.RouterGroup) {
|
||||
|
||||
// Get destination folder.
|
||||
var destFolder string
|
||||
if destFolder = s.User().GetUploadPath(); destFolder == "" {
|
||||
if destFolder = s.GetUser().GetUploadPath(); destFolder == "" {
|
||||
destFolder = conf.ImportDest()
|
||||
}
|
||||
|
||||
@@ -309,7 +309,7 @@ func ProcessUserUpload(router *gin.RouterGroup) {
|
||||
|
||||
// Add imported files to albums if allowed.
|
||||
if len(frm.Albums) > 0 &&
|
||||
acl.Rules.AllowAny(acl.ResourceAlbums, s.UserRole(), acl.Permissions{acl.ActionCreate, acl.ActionUpload}) {
|
||||
acl.Rules.AllowAny(acl.ResourceAlbums, s.GetUserRole(), acl.Permissions{acl.ActionCreate, acl.ActionUpload}) {
|
||||
log.Debugf("upload: adding files to album %s", clean.Log(strings.Join(frm.Albums, " and ")))
|
||||
opt.Albums = frm.Albums
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ func wsReader(ws *websocket.Conn, writeMutex *sync.Mutex, connId string, conf *c
|
||||
wsAuth.mutex.Lock()
|
||||
wsAuth.sid[connId] = s.ID
|
||||
wsAuth.rid[connId] = s.RefID
|
||||
wsAuth.user[connId] = *s.User()
|
||||
wsAuth.user[connId] = *s.GetUser()
|
||||
wsAuth.mutex.Unlock()
|
||||
|
||||
wsSendMessage("config.updated", event.Data{"config": conf.ClientSession(s)}, ws, writeMutex)
|
||||
|
||||
@@ -8,6 +8,8 @@ const (
|
||||
RoleViewer Role = "viewer"
|
||||
RoleGuest Role = "guest"
|
||||
RoleVisitor Role = "visitor"
|
||||
RoleNode Role = "node"
|
||||
RolePortal Role = "portal"
|
||||
RoleClient Role = "client"
|
||||
RoleNone Role = ""
|
||||
)
|
||||
|
||||
@@ -157,6 +157,8 @@ var GrantDefaults = Roles{
|
||||
RoleAdmin: GrantFullAccess,
|
||||
RoleGuest: GrantReactShared,
|
||||
RoleVisitor: GrantViewShared,
|
||||
RoleNode: GrantSearchShared,
|
||||
RolePortal: GrantFullAccess,
|
||||
RoleClient: GrantFullAccess,
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@ var UserRoles = RoleStrings{
|
||||
// ClientRoles maps valid API client roles.
|
||||
var ClientRoles = RoleStrings{
|
||||
string(RoleAdmin): RoleAdmin,
|
||||
string(RoleNode): RoleNode,
|
||||
string(RolePortal): RolePortal,
|
||||
string(RoleClient): RoleClient,
|
||||
string(RoleNone): RoleNone,
|
||||
}
|
||||
|
||||
@@ -47,6 +47,8 @@ var Rules = ACL{
|
||||
RoleAdmin: GrantFullAccess,
|
||||
RoleGuest: GrantReactShared,
|
||||
RoleVisitor: GrantViewShared,
|
||||
RoleNode: GrantUseOwn,
|
||||
RolePortal: GrantUseOwn,
|
||||
RoleClient: GrantFullAccess,
|
||||
},
|
||||
ResourceLabels: Roles{
|
||||
@@ -62,30 +64,38 @@ var Rules = ACL{
|
||||
RoleAdmin: GrantFullAccess,
|
||||
RoleGuest: GrantViewUpdateOwn,
|
||||
RoleVisitor: GrantViewOwn,
|
||||
RolePortal: GrantFullAccess,
|
||||
RoleClient: GrantViewUpdateOwn,
|
||||
},
|
||||
ResourceServices: Roles{
|
||||
RoleAdmin: GrantFullAccess,
|
||||
RoleAdmin: GrantFullAccess,
|
||||
RolePortal: GrantFullAccess,
|
||||
},
|
||||
ResourcePasscode: Roles{
|
||||
RoleAdmin: GrantFullAccess,
|
||||
RoleGuest: GrantConfigureOwn,
|
||||
RoleAdmin: GrantFullAccess,
|
||||
RolePortal: GrantFullAccess,
|
||||
RoleGuest: GrantConfigureOwn,
|
||||
},
|
||||
ResourcePassword: Roles{
|
||||
RoleAdmin: GrantFullAccess,
|
||||
RoleGuest: GrantUpdateOwn,
|
||||
RoleAdmin: GrantFullAccess,
|
||||
RolePortal: GrantFullAccess,
|
||||
RoleGuest: GrantUpdateOwn,
|
||||
},
|
||||
ResourceUsers: Roles{
|
||||
RoleAdmin: GrantManageOwn,
|
||||
RoleGuest: GrantViewUpdateOwn,
|
||||
RoleNode: GrantViewOwn,
|
||||
RolePortal: GrantFullAccess,
|
||||
RoleClient: GrantViewOwn,
|
||||
},
|
||||
ResourceSessions: Roles{
|
||||
RoleAdmin: GrantManageOwn,
|
||||
RolePortal: GrantFullAccess,
|
||||
RoleDefault: GrantOwn,
|
||||
},
|
||||
ResourceLogs: Roles{
|
||||
RoleAdmin: GrantFullAccess,
|
||||
RolePortal: GrantFullAccess,
|
||||
RoleClient: GrantFullAccess,
|
||||
},
|
||||
ResourceApi: Roles{
|
||||
@@ -94,6 +104,7 @@ var Rules = ACL{
|
||||
},
|
||||
ResourceWebDAV: Roles{
|
||||
RoleAdmin: GrantFullAccess,
|
||||
RolePortal: GrantFullAccess,
|
||||
RoleClient: GrantFullAccess,
|
||||
},
|
||||
ResourceWebhooks: Roles{
|
||||
@@ -102,14 +113,20 @@ var Rules = ACL{
|
||||
},
|
||||
ResourceMetrics: Roles{
|
||||
RoleAdmin: GrantFullAccess,
|
||||
RoleNode: GrantNone,
|
||||
RolePortal: GrantViewAll,
|
||||
RoleClient: GrantViewAll,
|
||||
},
|
||||
ResourceVision: Roles{
|
||||
RoleAdmin: GrantFullAccess,
|
||||
RoleNode: GrantUseOwn,
|
||||
RolePortal: GrantUseOwn,
|
||||
RoleClient: GrantUseOwn,
|
||||
},
|
||||
ResourceCluster: Roles{
|
||||
RoleAdmin: GrantFullAccess,
|
||||
RoleNode: GrantSearchDownloadUpdateOwn,
|
||||
RolePortal: GrantFullAccess,
|
||||
RoleClient: GrantSearchDownloadUpdateOwn,
|
||||
},
|
||||
ResourceFeedback: Roles{
|
||||
@@ -117,6 +134,8 @@ var Rules = ACL{
|
||||
},
|
||||
ResourceDefault: Roles{
|
||||
RoleAdmin: GrantFullAccess,
|
||||
RoleNode: GrantNone,
|
||||
RolePortal: GrantNone,
|
||||
RoleClient: GrantNone,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -52,8 +52,8 @@ func authListAction(ctx *cli.Context) error {
|
||||
rows[i] = []string{
|
||||
res.RefID,
|
||||
res.UserInfo(),
|
||||
res.AuthInfo(),
|
||||
res.ClientInfo(),
|
||||
res.GetAuthInfo(),
|
||||
res.GetClientInfo(),
|
||||
res.AuthScope,
|
||||
res.LoginIP,
|
||||
res.ClientIP,
|
||||
|
||||
@@ -734,12 +734,12 @@ func (c *Config) ClientRole(role acl.Role) *ClientConfig {
|
||||
// ClientSession provides the client config values for the specified session.
|
||||
func (c *Config) ClientSession(sess *entity.Session) (cfg *ClientConfig) {
|
||||
if sess.NoUser() && sess.IsClient() {
|
||||
cfg = c.ClientUser(false).ApplyACL(acl.Rules, sess.ClientRole())
|
||||
cfg = c.ClientUser(false).ApplyACL(acl.Rules, sess.GetClientRole())
|
||||
cfg.Settings = c.SessionSettings(sess)
|
||||
} else if sess.User().IsVisitor() {
|
||||
} else if sess.GetUser().IsVisitor() {
|
||||
cfg = c.ClientShare()
|
||||
} else if sess.User().IsRegistered() {
|
||||
cfg = c.ClientUser(false).ApplyACL(acl.Rules, sess.UserRole())
|
||||
} else if sess.GetUser().IsRegistered() {
|
||||
cfg = c.ClientUser(false).ApplyACL(acl.Rules, sess.GetUserRole())
|
||||
cfg.Settings = c.SessionSettings(sess)
|
||||
} else {
|
||||
cfg = c.ClientPublic()
|
||||
|
||||
@@ -74,10 +74,10 @@ func (c *Config) SessionSettings(sess *entity.Session) *customize.Settings {
|
||||
}
|
||||
|
||||
if sess.NoUser() && sess.IsClient() {
|
||||
return c.Settings().ApplyACL(acl.Rules, sess.ClientRole()).ApplyScope(sess.Scope())
|
||||
return c.Settings().ApplyACL(acl.Rules, sess.GetClientRole()).ApplyScope(sess.Scope())
|
||||
}
|
||||
|
||||
user := sess.User()
|
||||
user := sess.GetUser()
|
||||
|
||||
// Return public settings if the session does not have a user.
|
||||
if user == nil {
|
||||
|
||||
@@ -202,11 +202,11 @@ func (m *Session) Save() error {
|
||||
}
|
||||
|
||||
// Limit the number of sessions that are created with an app password.
|
||||
if !m.Method().IsSession() {
|
||||
if !m.GetMethod().IsSession() {
|
||||
return nil
|
||||
} else if !m.Provider().IsApplication() {
|
||||
} else if !m.GetProvider().IsApplication() {
|
||||
return nil
|
||||
} else if client := m.Client(); client.NoName() || client.Tokens() < 1 {
|
||||
} else if client := m.GetClient(); client.NoName() || client.Tokens() < 1 {
|
||||
return nil
|
||||
} else if deleted := DeleteClientSessions(client, authn.MethodSession, client.Tokens()); deleted > 0 {
|
||||
event.AuditInfo([]string{m.IP(), "session %s", "deleted %s"}, m.RefID, english.Plural(deleted, "previously created client session", "previously created client sessions"))
|
||||
@@ -241,7 +241,7 @@ func (m *Session) BeforeCreate(scope *gorm.Scope) error {
|
||||
return scope.SetColumn("ID", m.ID)
|
||||
}
|
||||
|
||||
// SetClient updates the client of this session.
|
||||
// SetClient sets the client of this session.
|
||||
func (m *Session) SetClient(c *Client) *Session {
|
||||
if c == nil {
|
||||
return m
|
||||
@@ -258,7 +258,7 @@ func (m *Session) SetClient(c *Client) *Session {
|
||||
return m
|
||||
}
|
||||
|
||||
// SetClientName changes the session's client name.
|
||||
// SetClientName changes the client name of this session.
|
||||
func (m *Session) SetClientName(s string) *Session {
|
||||
if s == "" {
|
||||
return m
|
||||
@@ -269,8 +269,8 @@ func (m *Session) SetClientName(s string) *Session {
|
||||
return m
|
||||
}
|
||||
|
||||
// Client returns the session's client.
|
||||
func (m *Session) Client() *Client {
|
||||
// GetClient returns the client this session belongs to.
|
||||
func (m *Session) GetClient() *Client {
|
||||
if m == nil {
|
||||
return &Client{}
|
||||
} else if m.client != nil {
|
||||
@@ -284,17 +284,22 @@ func (m *Session) Client() *Client {
|
||||
UserUID: m.UserUID,
|
||||
UserName: m.UserName,
|
||||
ClientUID: m.ClientUID,
|
||||
ClientName: m.ClientName,
|
||||
ClientRole: m.ClientRole().String(),
|
||||
ClientName: m.GetClientName(),
|
||||
ClientRole: m.GetClientRole().String(),
|
||||
AuthScope: m.Scope(),
|
||||
AuthMethod: m.AuthMethod,
|
||||
}
|
||||
}
|
||||
|
||||
// ClientRole returns the session's client ACL role.
|
||||
func (m *Session) ClientRole() acl.Role {
|
||||
// GetClientName returns the client name.
|
||||
func (m *Session) GetClientName() string {
|
||||
return m.ClientName
|
||||
}
|
||||
|
||||
// GetClientRole returns the client ACL role.
|
||||
func (m *Session) GetClientRole() acl.Role {
|
||||
if m.HasClient() {
|
||||
return m.Client().AclRole()
|
||||
return m.GetClient().AclRole()
|
||||
} else if m.IsClient() {
|
||||
return acl.RoleClient
|
||||
}
|
||||
@@ -302,10 +307,10 @@ func (m *Session) ClientRole() acl.Role {
|
||||
return acl.RoleNone
|
||||
}
|
||||
|
||||
// ClientInfo returns the session's client identifier string.
|
||||
func (m *Session) ClientInfo() string {
|
||||
// GetClientInfo returns the client identifier string.
|
||||
func (m *Session) GetClientInfo() string {
|
||||
if m.HasClient() {
|
||||
return m.Client().String()
|
||||
return m.GetClient().String()
|
||||
} else if m.ClientName != "" {
|
||||
return m.ClientName
|
||||
}
|
||||
@@ -332,8 +337,8 @@ func (m *Session) IsClient() bool {
|
||||
return authn.Provider(m.AuthProvider).IsClient()
|
||||
}
|
||||
|
||||
// User returns the session's user entity.
|
||||
func (m *Session) User() *User {
|
||||
// GetUser returns the related user entity.
|
||||
func (m *Session) GetUser() *User {
|
||||
if m == nil {
|
||||
return &User{}
|
||||
} else if m.user != nil {
|
||||
@@ -350,20 +355,20 @@ func (m *Session) User() *User {
|
||||
return &User{}
|
||||
}
|
||||
|
||||
// UserRole returns the session's user ACL role.
|
||||
func (m *Session) UserRole() acl.Role {
|
||||
return m.User().AclRole()
|
||||
// GetUserRole returns the session's user ACL role.
|
||||
func (m *Session) GetUserRole() acl.Role {
|
||||
return m.GetUser().AclRole()
|
||||
}
|
||||
|
||||
// UserInfo returns the session's user information.
|
||||
func (m *Session) UserInfo() string {
|
||||
name := m.Username()
|
||||
name := m.GetUserName()
|
||||
|
||||
if name != "" {
|
||||
return name
|
||||
}
|
||||
|
||||
return m.UserRole().String()
|
||||
return m.GetUserRole().String()
|
||||
}
|
||||
|
||||
// SetUser updates the user entity of this session.
|
||||
@@ -414,15 +419,15 @@ func (m *Session) RefreshUser() *Session {
|
||||
return m
|
||||
}
|
||||
|
||||
// Username returns the login name.
|
||||
func (m *Session) Username() string {
|
||||
// GetUserName returns the login name.
|
||||
func (m *Session) GetUserName() string {
|
||||
return m.UserName
|
||||
}
|
||||
|
||||
// AuthInfo returns information about the authentication type.
|
||||
func (m *Session) AuthInfo() string {
|
||||
provider := m.Provider()
|
||||
method := m.Method()
|
||||
// GetAuthInfo returns information about the authentication type.
|
||||
func (m *Session) GetAuthInfo() string {
|
||||
provider := m.GetProvider()
|
||||
method := m.GetMethod()
|
||||
|
||||
if method.IsDefault() {
|
||||
return provider.Pretty()
|
||||
@@ -443,8 +448,8 @@ func (m *Session) SetAuthID(id, issuer string) *Session {
|
||||
return m
|
||||
}
|
||||
|
||||
// Provider returns the authentication provider.
|
||||
func (m *Session) Provider() authn.ProviderType {
|
||||
// GetProvider returns the authentication provider.
|
||||
func (m *Session) GetProvider() authn.ProviderType {
|
||||
return authn.Provider(m.AuthProvider)
|
||||
}
|
||||
|
||||
@@ -459,14 +464,14 @@ func (m *Session) SetProvider(provider authn.ProviderType) *Session {
|
||||
return m
|
||||
}
|
||||
|
||||
// Method returns the authentication method.
|
||||
func (m *Session) Method() authn.MethodType {
|
||||
// GetMethod returns the authentication method.
|
||||
func (m *Session) GetMethod() authn.MethodType {
|
||||
return authn.Method(m.AuthMethod)
|
||||
}
|
||||
|
||||
// Is2FA checks if 2-Factor Authentication (2FA) was used to log in.
|
||||
func (m *Session) Is2FA() bool {
|
||||
return m.Method().Is(authn.Method2FA)
|
||||
return m.GetMethod().Is(authn.Method2FA)
|
||||
}
|
||||
|
||||
// SetMethod sets a custom authentication method.
|
||||
@@ -539,8 +544,8 @@ func (m *Session) SetScope(scope string) *Session {
|
||||
return m
|
||||
}
|
||||
|
||||
// AuthGrantType returns the session's grant type as authn.GrantType.
|
||||
func (m *Session) AuthGrantType() authn.GrantType {
|
||||
// GetGrantType returns the session's grant type as authn.GrantType.
|
||||
func (m *Session) GetGrantType() authn.GrantType {
|
||||
return authn.Grant(m.GrantType)
|
||||
}
|
||||
|
||||
@@ -557,7 +562,7 @@ func (m *Session) SetGrantType(t authn.GrantType) *Session {
|
||||
|
||||
// ChangePassword changes the password of the current user.
|
||||
func (m *Session) ChangePassword(newPw string) (err error) {
|
||||
u := m.User()
|
||||
u := m.GetUser()
|
||||
|
||||
if u == nil {
|
||||
return fmt.Errorf("unknown user")
|
||||
@@ -606,8 +611,8 @@ func (m *Session) SetDownloadToken(token string) *Session {
|
||||
return m
|
||||
}
|
||||
|
||||
// Data returns the session's data.
|
||||
func (m *Session) Data() (data *SessionData) {
|
||||
// GetData returns the data that belong to this session.
|
||||
func (m *Session) GetData() (data *SessionData) {
|
||||
if m.data != nil {
|
||||
data = m.data
|
||||
}
|
||||
@@ -626,7 +631,7 @@ func (m *Session) Data() (data *SessionData) {
|
||||
return data
|
||||
}
|
||||
|
||||
// SetData updates the session's data.
|
||||
// SetData updates the data that belong to this session.
|
||||
func (m *Session) SetData(data *SessionData) *Session {
|
||||
if data == nil {
|
||||
log.Debugf("auth: empty data passed to session %s", m.RefID)
|
||||
@@ -704,7 +709,7 @@ func (m *Session) UpdateContext(c *gin.Context) *Session {
|
||||
|
||||
// IsVisitor checks if the session belongs to a sharing link visitor.
|
||||
func (m *Session) IsVisitor() bool {
|
||||
return m.User().IsVisitor()
|
||||
return m.GetUser().IsVisitor()
|
||||
}
|
||||
|
||||
// IsSuperAdmin checks if the session belongs to a registered super admin user.
|
||||
@@ -713,7 +718,7 @@ func (m *Session) IsSuperAdmin() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
return m.User().IsSuperAdmin()
|
||||
return m.GetUser().IsSuperAdmin()
|
||||
}
|
||||
|
||||
// IsRegistered checks if the session belongs to a registered user account.
|
||||
@@ -722,7 +727,7 @@ func (m *Session) IsRegistered() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
return m.User().IsRegistered()
|
||||
return m.GetUser().IsRegistered()
|
||||
}
|
||||
|
||||
// NotRegistered checks if the user is not registered with an own account.
|
||||
@@ -737,9 +742,9 @@ func (m *Session) NoShares() bool {
|
||||
|
||||
// HasShares checks if the session has any shares.
|
||||
func (m *Session) HasShares() bool {
|
||||
if user := m.User(); user.IsRegistered() {
|
||||
if user := m.GetUser(); user.IsRegistered() {
|
||||
return user.HasShares()
|
||||
} else if data := m.Data(); data == nil {
|
||||
} else if data := m.GetData(); data == nil {
|
||||
return false
|
||||
} else {
|
||||
return data.HasShares()
|
||||
@@ -752,14 +757,14 @@ func (m *Session) HasRegisteredUser() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
return m.User().IsRegistered()
|
||||
return m.GetUser().IsRegistered()
|
||||
}
|
||||
|
||||
// HasShare if the session includes the specified share
|
||||
func (m *Session) HasShare(uid string) bool {
|
||||
if user := m.User(); user.IsRegistered() {
|
||||
if user := m.GetUser(); user.IsRegistered() {
|
||||
return user.HasShare(uid)
|
||||
} else if data := m.Data(); data == nil {
|
||||
} else if data := m.GetData(); data == nil {
|
||||
return false
|
||||
} else {
|
||||
return data.HasShare(uid)
|
||||
@@ -768,9 +773,9 @@ func (m *Session) HasShare(uid string) bool {
|
||||
|
||||
// SharedUIDs returns shared entity UIDs.
|
||||
func (m *Session) SharedUIDs() UIDs {
|
||||
if user := m.User(); user.IsRegistered() {
|
||||
if user := m.GetUser(); user.IsRegistered() {
|
||||
return user.SharedUIDs()
|
||||
} else if data := m.Data(); data == nil {
|
||||
} else if data := m.GetData(); data == nil {
|
||||
return UIDs{}
|
||||
} else {
|
||||
return data.SharedUIDs()
|
||||
@@ -779,9 +784,9 @@ func (m *Session) SharedUIDs() UIDs {
|
||||
|
||||
// RedeemToken updates shared entity UIDs using the specified token.
|
||||
func (m *Session) RedeemToken(token string) (n int) {
|
||||
if user := m.User(); user.IsRegistered() {
|
||||
if user := m.GetUser(); user.IsRegistered() {
|
||||
return user.RedeemToken(token)
|
||||
} else if data := m.Data(); data == nil {
|
||||
} else if data := m.GetData(); data == nil {
|
||||
return 0
|
||||
} else {
|
||||
return data.RedeemToken(token)
|
||||
@@ -889,7 +894,7 @@ func (m *Session) UpdateLastActive(save bool) *Session {
|
||||
}
|
||||
|
||||
// Update the activity timestamp of the parent session, if any.
|
||||
if m.Method().IsNot(authn.MethodSession) || m.AuthID == "" || m.AuthID == m.ID {
|
||||
if m.GetMethod().IsNot(authn.MethodSession) || m.AuthID == "" || m.AuthID == m.ID {
|
||||
return m
|
||||
} else if err := Db().Table(Session{}.TableName()).Where("id = ?", m.AuthID).UpdateColumn("last_active", m.LastActive).Error; err != nil {
|
||||
event.AuditWarn([]string{m.IP(), "session %s", "failed to update activity timestamp of parent session", "%s"}, m.RefID, err)
|
||||
@@ -909,7 +914,7 @@ func (m *Session) Valid() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
return m.User().IsRegistered() || m.IsVisitor() && m.HasShares()
|
||||
return m.GetUser().IsRegistered() || m.IsVisitor() && m.HasShares()
|
||||
}
|
||||
|
||||
// Abort aborts the request with the appropriate error code if access to the requested resource is denied.
|
||||
|
||||
@@ -42,7 +42,7 @@ func DeleteSession(s *Session) error {
|
||||
func DeleteChildSessions(s *Session) (deleted int) {
|
||||
if s == nil {
|
||||
return 0
|
||||
} else if !rnd.IsSessionID(s.ID) || s.Method().Is(authn.MethodSession) {
|
||||
} else if !rnd.IsSessionID(s.ID) || s.GetMethod().Is(authn.MethodSession) {
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ func AuthSession(frm form.Login, c *gin.Context) (sess *Session, user *User, err
|
||||
sess.UpdateContext(c)
|
||||
|
||||
// Returns session and user if all checks have passed.
|
||||
return sess, sess.User(), nil
|
||||
return sess, sess.GetUser(), nil
|
||||
}
|
||||
|
||||
// AuthLocal authenticates against the local user database with the specified username and password.
|
||||
@@ -140,7 +140,7 @@ func AuthLocal(user *User, frm form.Login, s *Session, c *gin.Context) (provider
|
||||
if s != nil {
|
||||
// Set scope, client UID, and client name to that of the parent session.
|
||||
s.ClientUID = authSess.ClientUID
|
||||
s.ClientName = authSess.ClientName
|
||||
s.ClientName = authSess.GetClientName()
|
||||
s.SetScope(authSess.Scope())
|
||||
|
||||
// Set provider and method to help identify the session type.
|
||||
@@ -267,7 +267,7 @@ func (m *Session) LogIn(frm form.Login, c *gin.Context) (err error) {
|
||||
|
||||
// Try to redeem link share token, if provided.
|
||||
if frm.HasShareToken() {
|
||||
user = m.User()
|
||||
user = m.GetUser()
|
||||
|
||||
// Redeem token.
|
||||
if user.IsRegistered() {
|
||||
@@ -279,7 +279,7 @@ func (m *Session) LogIn(frm form.Login, c *gin.Context) (err error) {
|
||||
} else {
|
||||
event.AuditInfo([]string{m.IP(), "session %s", "token redeemed for %d shares"}, m.RefID, user.RedeemToken(frm.Token))
|
||||
}
|
||||
} else if data := m.Data(); data == nil {
|
||||
} else if data := m.GetData(); data == nil {
|
||||
m.Status = http.StatusInternalServerError
|
||||
return i18n.Error(i18n.ErrUnexpected)
|
||||
} else if shares := data.RedeemToken(frm.Token); shares == 0 {
|
||||
@@ -308,7 +308,7 @@ func (m *Session) LogIn(frm form.Login, c *gin.Context) (err error) {
|
||||
}
|
||||
|
||||
// Unregistered visitors must use a valid share link to obtain a session.
|
||||
if m.User().NotRegistered() && m.Data().NoShares() {
|
||||
if m.GetUser().NotRegistered() && m.GetData().NoShares() {
|
||||
m.Status = http.StatusUnauthorized
|
||||
return i18n.Error(i18n.ErrInvalidCredentials)
|
||||
}
|
||||
|
||||
@@ -101,9 +101,9 @@ func TestAuthSession(t *testing.T) {
|
||||
assert.NotNil(t, authUser)
|
||||
|
||||
assert.Equal(t, u.UserUID, s.UserUID)
|
||||
assert.Equal(t, u.Username(), s.Username())
|
||||
assert.Equal(t, u.Username(), s.GetUserName())
|
||||
assert.Equal(t, authUser.UserUID, authSess.UserUID)
|
||||
assert.Equal(t, authUser.Username(), authSess.Username())
|
||||
assert.Equal(t, authUser.Username(), authSess.GetUserName())
|
||||
assert.Equal(t, authUser.UserUID, authUser.UserUID)
|
||||
assert.Equal(t, authUser.Username(), authUser.Username())
|
||||
|
||||
@@ -139,9 +139,9 @@ func TestAuthSession(t *testing.T) {
|
||||
assert.NotNil(t, authUser)
|
||||
|
||||
assert.Equal(t, u.UserUID, s.UserUID)
|
||||
assert.Equal(t, u.Username(), s.Username())
|
||||
assert.Equal(t, u.Username(), s.GetUserName())
|
||||
assert.Equal(t, authUser.UserUID, authSess.UserUID)
|
||||
assert.Equal(t, authUser.Username(), authSess.Username())
|
||||
assert.Equal(t, authUser.Username(), authSess.GetUserName())
|
||||
assert.Equal(t, authUser.UserUID, authUser.UserUID)
|
||||
assert.Equal(t, authUser.Username(), authUser.Username())
|
||||
|
||||
|
||||
@@ -26,8 +26,8 @@ func TestNewSession(t *testing.T) {
|
||||
assert.False(t, m.UpdatedAt.IsZero())
|
||||
assert.False(t, m.ExpiresAt().IsZero())
|
||||
assert.NotEmpty(t, m.ID)
|
||||
assert.NotNil(t, m.Data())
|
||||
assert.Equal(t, 0, len(m.Data().Tokens))
|
||||
assert.NotNil(t, m.GetData())
|
||||
assert.Equal(t, 0, len(m.GetData().Tokens))
|
||||
})
|
||||
t.Run("EmptySessionData", func(t *testing.T) {
|
||||
m := NewSession(unix.Day, unix.Hour*6)
|
||||
@@ -39,8 +39,8 @@ func TestNewSession(t *testing.T) {
|
||||
assert.False(t, m.UpdatedAt.IsZero())
|
||||
assert.False(t, m.ExpiresAt().IsZero())
|
||||
assert.NotEmpty(t, m.ID)
|
||||
assert.NotNil(t, m.Data())
|
||||
assert.Equal(t, 0, len(m.Data().Tokens))
|
||||
assert.NotNil(t, m.GetData())
|
||||
assert.Equal(t, 0, len(m.GetData().Tokens))
|
||||
})
|
||||
t.Run("WithSessionData", func(t *testing.T) {
|
||||
data := NewSessionData()
|
||||
@@ -54,10 +54,10 @@ func TestNewSession(t *testing.T) {
|
||||
assert.False(t, m.UpdatedAt.IsZero())
|
||||
assert.False(t, m.ExpiresAt().IsZero())
|
||||
assert.NotEmpty(t, m.ID)
|
||||
assert.NotNil(t, m.Data())
|
||||
assert.Len(t, m.Data().Tokens, 2)
|
||||
assert.Equal(t, "foo", m.Data().Tokens[0])
|
||||
assert.Equal(t, "bar", m.Data().Tokens[1])
|
||||
assert.NotNil(t, m.GetData())
|
||||
assert.Len(t, m.GetData().Tokens, 2)
|
||||
assert.Equal(t, "foo", m.GetData().Tokens[0])
|
||||
assert.Equal(t, "bar", m.GetData().Tokens[1])
|
||||
})
|
||||
}
|
||||
|
||||
@@ -292,72 +292,72 @@ func TestSession_Client(t *testing.T) {
|
||||
t.Run("Alice", func(t *testing.T) {
|
||||
m := FindSessionByRefID("sessxkkcabcd")
|
||||
assert.Equal(t, "uqxetse3cy5eo9z2", m.UserUID)
|
||||
assert.Equal(t, "uqxetse3cy5eo9z2", m.User().UserUID)
|
||||
assert.Equal(t, "", m.Client().ClientUID)
|
||||
assert.Equal(t, "uqxetse3cy5eo9z2", m.Client().UserUID)
|
||||
assert.Equal(t, acl.RoleNone, m.Client().AclRole())
|
||||
assert.Equal(t, acl.RoleNone, m.ClientRole())
|
||||
assert.Equal(t, "uqxetse3cy5eo9z2", m.GetUser().UserUID)
|
||||
assert.Equal(t, "", m.GetClient().ClientUID)
|
||||
assert.Equal(t, "uqxetse3cy5eo9z2", m.GetClient().UserUID)
|
||||
assert.Equal(t, acl.RoleNone, m.GetClient().AclRole())
|
||||
assert.Equal(t, acl.RoleNone, m.GetClientRole())
|
||||
})
|
||||
t.Run("AliceTokenPersonal", func(t *testing.T) {
|
||||
m := SessionFixtures.Get("alice_token_personal")
|
||||
assert.Equal(t, "uqxetse3cy5eo9z2", m.UserUID)
|
||||
assert.Equal(t, "uqxetse3cy5eo9z2", m.User().UserUID)
|
||||
assert.Equal(t, "", m.Client().ClientUID)
|
||||
assert.Equal(t, "uqxetse3cy5eo9z2", m.Client().UserUID)
|
||||
assert.Equal(t, acl.RoleClient, m.Client().AclRole())
|
||||
assert.Equal(t, acl.RoleClient, m.ClientRole())
|
||||
assert.Equal(t, "uqxetse3cy5eo9z2", m.GetUser().UserUID)
|
||||
assert.Equal(t, "", m.GetClient().ClientUID)
|
||||
assert.Equal(t, "uqxetse3cy5eo9z2", m.GetClient().UserUID)
|
||||
assert.Equal(t, acl.RoleClient, m.GetClient().AclRole())
|
||||
assert.Equal(t, acl.RoleClient, m.GetClientRole())
|
||||
})
|
||||
t.Run("ClientMetrics", func(t *testing.T) {
|
||||
m := SessionFixtures.Get("client_metrics")
|
||||
assert.Equal(t, "", m.UserUID)
|
||||
assert.Equal(t, "", m.User().UserUID)
|
||||
assert.Equal(t, "cs5cpu17n6gj2qo5", m.Client().ClientUID)
|
||||
assert.Equal(t, "", m.Client().UserUID)
|
||||
assert.Equal(t, acl.RoleClient, m.Client().AclRole())
|
||||
assert.Equal(t, acl.RoleClient, m.ClientRole())
|
||||
assert.Equal(t, "", m.GetUser().UserUID)
|
||||
assert.Equal(t, "cs5cpu17n6gj2qo5", m.GetClient().ClientUID)
|
||||
assert.Equal(t, "", m.GetClient().UserUID)
|
||||
assert.Equal(t, acl.RoleClient, m.GetClient().AclRole())
|
||||
assert.Equal(t, acl.RoleClient, m.GetClientRole())
|
||||
})
|
||||
t.Run("Default", func(t *testing.T) {
|
||||
m := &Session{}
|
||||
assert.Equal(t, "", m.UserUID)
|
||||
assert.Equal(t, "", m.User().UserUID)
|
||||
assert.Equal(t, "", m.Client().ClientUID)
|
||||
assert.Equal(t, "", m.Client().UserUID)
|
||||
assert.Equal(t, acl.RoleNone, m.Client().AclRole())
|
||||
assert.Equal(t, acl.RoleNone, m.ClientRole())
|
||||
assert.Equal(t, "", m.GetUser().UserUID)
|
||||
assert.Equal(t, "", m.GetClient().ClientUID)
|
||||
assert.Equal(t, "", m.GetClient().UserUID)
|
||||
assert.Equal(t, acl.RoleNone, m.GetClient().AclRole())
|
||||
assert.Equal(t, acl.RoleNone, m.GetClientRole())
|
||||
})
|
||||
}
|
||||
|
||||
func TestSession_ClientRole(t *testing.T) {
|
||||
t.Run("Alice", func(t *testing.T) {
|
||||
m := SessionFixtures.Get("alice")
|
||||
assert.Equal(t, acl.RoleNone, m.ClientRole())
|
||||
assert.Equal(t, acl.RoleNone, m.GetClientRole())
|
||||
})
|
||||
t.Run("AliceTokenPersonal", func(t *testing.T) {
|
||||
m := SessionFixtures.Get("alice_token_personal")
|
||||
assert.Equal(t, acl.RoleClient, m.ClientRole())
|
||||
assert.Equal(t, acl.RoleClient, m.GetClientRole())
|
||||
})
|
||||
t.Run("TokenMetrics", func(t *testing.T) {
|
||||
m := SessionFixtures.Get("token_metrics")
|
||||
assert.Equal(t, acl.RoleClient, m.ClientRole())
|
||||
assert.Equal(t, acl.RoleClient, m.GetClientRole())
|
||||
})
|
||||
t.Run("TokenSettings", func(t *testing.T) {
|
||||
m := SessionFixtures.Get("token_settings")
|
||||
assert.Equal(t, acl.RoleClient, m.ClientRole())
|
||||
assert.Equal(t, acl.RoleClient, m.GetClientRole())
|
||||
})
|
||||
t.Run("Default", func(t *testing.T) {
|
||||
m := &Session{}
|
||||
assert.Equal(t, acl.RoleNone, m.ClientRole())
|
||||
assert.Equal(t, acl.RoleNone, m.GetClientRole())
|
||||
})
|
||||
}
|
||||
|
||||
func TestSession_ClientInfo(t *testing.T) {
|
||||
t.Run("Alice", func(t *testing.T) {
|
||||
m := SessionFixtures.Get("alice")
|
||||
assert.Equal(t, "n/a", m.ClientInfo())
|
||||
assert.Equal(t, "n/a", m.GetClientInfo())
|
||||
})
|
||||
t.Run("Metrics", func(t *testing.T) {
|
||||
m := SessionFixtures.Get("client_metrics")
|
||||
assert.Equal(t, "cs5cpu17n6gj2qo5", m.ClientInfo())
|
||||
assert.Equal(t, "cs5cpu17n6gj2qo5", m.GetClientInfo())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -375,11 +375,11 @@ func TestSession_NoClient(t *testing.T) {
|
||||
func TestSession_SetClient(t *testing.T) {
|
||||
t.Run("Alice", func(t *testing.T) {
|
||||
m := SessionFixtures.Get("alice")
|
||||
assert.Equal(t, acl.RoleNone, m.ClientRole())
|
||||
assert.Equal(t, "", m.Client().ClientUID)
|
||||
assert.Equal(t, acl.RoleNone, m.GetClientRole())
|
||||
assert.Equal(t, "", m.GetClient().ClientUID)
|
||||
m.SetClient(ClientFixtures.Pointer("alice"))
|
||||
assert.Equal(t, acl.RoleClient, m.ClientRole())
|
||||
assert.Equal(t, "cs5gfen1bgxz7s9i", m.Client().ClientUID)
|
||||
assert.Equal(t, acl.RoleClient, m.GetClientRole())
|
||||
assert.Equal(t, "cs5gfen1bgxz7s9i", m.GetClient().ClientUID)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -387,36 +387,36 @@ func TestSession_SetClientName(t *testing.T) {
|
||||
t.Run("Empty", func(t *testing.T) {
|
||||
m := SessionFixtures.Get("alice_token_personal")
|
||||
assert.Equal(t, "", m.ClientUID)
|
||||
assert.Equal(t, "alice_token_personal", m.ClientName)
|
||||
assert.Equal(t, "alice_token_personal", m.ClientInfo())
|
||||
assert.Equal(t, "alice_token_personal", m.GetClientName())
|
||||
assert.Equal(t, "alice_token_personal", m.GetClientInfo())
|
||||
m.SetClientName("Foo Bar!")
|
||||
assert.Equal(t, "", m.ClientUID)
|
||||
assert.Equal(t, "Foo Bar!", m.ClientName)
|
||||
assert.Equal(t, "Foo Bar!", m.ClientInfo())
|
||||
assert.Equal(t, "Foo Bar!", m.GetClientName())
|
||||
assert.Equal(t, "Foo Bar!", m.GetClientInfo())
|
||||
m.SetClientName("")
|
||||
assert.Equal(t, "Foo Bar!", m.ClientName)
|
||||
assert.Equal(t, "Foo Bar!", m.ClientInfo())
|
||||
assert.Equal(t, "Foo Bar!", m.GetClientName())
|
||||
assert.Equal(t, "Foo Bar!", m.GetClientInfo())
|
||||
})
|
||||
t.Run("setNewID", func(t *testing.T) {
|
||||
m := NewSession(0, 0)
|
||||
assert.Equal(t, "", m.ClientUID)
|
||||
assert.Equal(t, "", m.ClientName)
|
||||
assert.Equal(t, report.NotAssigned, m.ClientInfo())
|
||||
assert.Equal(t, "", m.GetClientName())
|
||||
assert.Equal(t, report.NotAssigned, m.GetClientInfo())
|
||||
m.SetClientName("Foo Bar!")
|
||||
assert.Equal(t, "", m.ClientUID)
|
||||
assert.Equal(t, "Foo Bar!", m.ClientName)
|
||||
assert.Equal(t, "Foo Bar!", m.ClientInfo())
|
||||
assert.Equal(t, "Foo Bar!", m.GetClientName())
|
||||
assert.Equal(t, "Foo Bar!", m.GetClientInfo())
|
||||
})
|
||||
}
|
||||
|
||||
func TestSession_User(t *testing.T) {
|
||||
t.Run("Alice", func(t *testing.T) {
|
||||
m := FindSessionByRefID("sessxkkcabcd")
|
||||
assert.Equal(t, "uqxetse3cy5eo9z2", m.User().UserUID)
|
||||
assert.Equal(t, "uqxetse3cy5eo9z2", m.GetUser().UserUID)
|
||||
})
|
||||
t.Run("Default", func(t *testing.T) {
|
||||
m := &Session{}
|
||||
assert.Equal(t, "", m.User().UserUID)
|
||||
assert.Equal(t, "", m.GetUser().UserUID)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -434,15 +434,15 @@ func TestSession_UserInfo(t *testing.T) {
|
||||
func TestSession_UserRole(t *testing.T) {
|
||||
t.Run("Alice", func(t *testing.T) {
|
||||
m := FindSessionByRefID("sessxkkcabcd")
|
||||
assert.Equal(t, acl.RoleAdmin, m.UserRole())
|
||||
assert.Equal(t, acl.RoleAdmin, m.GetUserRole())
|
||||
})
|
||||
t.Run("Bob", func(t *testing.T) {
|
||||
m := FindSessionByRefID("sessxkkcabce")
|
||||
assert.Equal(t, acl.RoleAdmin, m.UserRole())
|
||||
assert.Equal(t, acl.RoleAdmin, m.GetUserRole())
|
||||
})
|
||||
t.Run("Default", func(t *testing.T) {
|
||||
m := &Session{}
|
||||
assert.Equal(t, acl.RoleNone, m.UserRole())
|
||||
assert.Equal(t, acl.RoleNone, m.GetUserRole())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -450,15 +450,15 @@ func TestSession_RefreshUser(t *testing.T) {
|
||||
t.Run("Bob", func(t *testing.T) {
|
||||
m := FindSessionByRefID("sessxkkcabce")
|
||||
|
||||
assert.Equal(t, "bob", m.Username())
|
||||
assert.Equal(t, "bob", m.GetUserName())
|
||||
|
||||
m.UserName = "bobby"
|
||||
|
||||
assert.Equal(t, "bobby", m.Username())
|
||||
assert.Equal(t, "bobby", m.GetUserName())
|
||||
|
||||
assert.Equal(t, "bob", m.RefreshUser().UserName)
|
||||
|
||||
assert.Equal(t, "bob", m.Username())
|
||||
assert.Equal(t, "bob", m.GetUserName())
|
||||
})
|
||||
t.Run("Empty", func(t *testing.T) {
|
||||
m := &Session{}
|
||||
@@ -470,14 +470,14 @@ func TestSession_AuthInfo(t *testing.T) {
|
||||
t.Run("bob", func(t *testing.T) {
|
||||
m := FindSessionByRefID("sessxkkcabce")
|
||||
|
||||
i := m.AuthInfo()
|
||||
i := m.GetAuthInfo()
|
||||
|
||||
assert.Equal(t, "Default", i)
|
||||
})
|
||||
t.Run("aliceTokenWebDAV", func(t *testing.T) {
|
||||
m := FindSessionByRefID("sesshjtgx8qt")
|
||||
|
||||
i := m.AuthInfo()
|
||||
i := m.GetAuthInfo()
|
||||
|
||||
assert.Equal(t, "Access Token", i)
|
||||
})
|
||||
@@ -521,8 +521,8 @@ func TestSession_SetMethod(t *testing.T) {
|
||||
|
||||
m := s.SetMethod("")
|
||||
|
||||
assert.Equal(t, authn.ProviderAccessToken, m.Provider())
|
||||
assert.Equal(t, authn.MethodDefault, m.Method())
|
||||
assert.Equal(t, authn.ProviderAccessToken, m.GetProvider())
|
||||
assert.Equal(t, authn.MethodDefault, m.GetMethod())
|
||||
})
|
||||
t.Run("Test", func(t *testing.T) {
|
||||
s := &Session{
|
||||
@@ -534,8 +534,8 @@ func TestSession_SetMethod(t *testing.T) {
|
||||
|
||||
m := s.SetMethod("Test")
|
||||
|
||||
assert.Equal(t, authn.ProviderAccessToken, m.Provider())
|
||||
assert.Equal(t, authn.Method("Test"), m.Method())
|
||||
assert.Equal(t, authn.ProviderAccessToken, m.GetProvider())
|
||||
assert.Equal(t, authn.Method("Test"), m.GetMethod())
|
||||
})
|
||||
t.Run("Test", func(t *testing.T) {
|
||||
s := &Session{
|
||||
@@ -547,8 +547,8 @@ func TestSession_SetMethod(t *testing.T) {
|
||||
|
||||
m := s.SetMethod(authn.MethodSession)
|
||||
|
||||
assert.Equal(t, authn.ProviderAccessToken, m.Provider())
|
||||
assert.Equal(t, authn.MethodSession, m.Method())
|
||||
assert.Equal(t, authn.ProviderAccessToken, m.GetProvider())
|
||||
assert.Equal(t, authn.MethodSession, m.GetMethod())
|
||||
})
|
||||
t.Run("2FA", func(t *testing.T) {
|
||||
s := &Session{
|
||||
@@ -568,13 +568,13 @@ func TestSession_SetMethod(t *testing.T) {
|
||||
|
||||
func TestSession_SetProvider(t *testing.T) {
|
||||
m := FindSessionByRefID("sessxkkcabce")
|
||||
assert.Equal(t, authn.ProviderDefault, m.Provider())
|
||||
assert.Equal(t, authn.ProviderDefault, m.GetProvider())
|
||||
m.SetProvider("")
|
||||
assert.Equal(t, authn.ProviderDefault, m.Provider())
|
||||
assert.Equal(t, authn.ProviderDefault, m.GetProvider())
|
||||
m.SetProvider(authn.ProviderLink)
|
||||
assert.Equal(t, authn.ProviderLink, m.Provider())
|
||||
assert.Equal(t, authn.ProviderLink, m.GetProvider())
|
||||
m.SetProvider(authn.ProviderDefault)
|
||||
assert.Equal(t, authn.ProviderDefault, m.Provider())
|
||||
assert.Equal(t, authn.ProviderDefault, m.GetProvider())
|
||||
}
|
||||
|
||||
func TestSession_ChangePassword(t *testing.T) {
|
||||
@@ -729,7 +729,7 @@ func TestSession_SetGrantType(t *testing.T) {
|
||||
assert.Equal(t, expected, m.GrantType)
|
||||
m.SetGrantType(authn.GrantUndefined)
|
||||
assert.Equal(t, expected, m.GrantType)
|
||||
assert.Equal(t, authn.GrantPassword, m.AuthGrantType())
|
||||
assert.Equal(t, authn.GrantPassword, m.GetGrantType())
|
||||
})
|
||||
t.Run("ClientCredentials", func(t *testing.T) {
|
||||
client := ClientFixtures.Pointer("alice")
|
||||
@@ -742,7 +742,7 @@ func TestSession_SetGrantType(t *testing.T) {
|
||||
assert.Equal(t, expected, m.GrantType)
|
||||
m.SetGrantType(authn.GrantUndefined)
|
||||
assert.Equal(t, expected, m.GrantType)
|
||||
assert.Equal(t, authn.GrantClientCredentials, m.AuthGrantType())
|
||||
assert.Equal(t, authn.GrantClientCredentials, m.GetGrantType())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -799,7 +799,7 @@ func TestSession_NotRegistered(t *testing.T) {
|
||||
func TestSession_NoShares(t *testing.T) {
|
||||
alice := FindSessionByRefID("sessxkkcabcd")
|
||||
alice.RefreshUser()
|
||||
alice.User().RefreshShares()
|
||||
alice.GetUser().RefreshShares()
|
||||
assert.False(t, alice.NoShares())
|
||||
|
||||
bob := FindSessionByRefID("sessxkkcabce")
|
||||
@@ -835,13 +835,13 @@ func TestSession_HasRegisteredUser(t *testing.T) {
|
||||
func TestSession_HasShare(t *testing.T) {
|
||||
alice := FindSessionByRefID("sessxkkcabcd")
|
||||
alice.RefreshUser()
|
||||
alice.User().RefreshShares()
|
||||
alice.GetUser().RefreshShares()
|
||||
assert.True(t, alice.HasShare("as6sg6bxpogaaba9"))
|
||||
assert.False(t, alice.HasShare("as6sg6bxpogaaba7"))
|
||||
|
||||
bob := FindSessionByRefID("sessxkkcabce")
|
||||
bob.RefreshUser()
|
||||
bob.User().RefreshShares()
|
||||
bob.GetUser().RefreshShares()
|
||||
assert.False(t, bob.HasShare("as6sg6bxpogaaba9"))
|
||||
|
||||
m := &Session{}
|
||||
@@ -851,12 +851,12 @@ func TestSession_HasShare(t *testing.T) {
|
||||
func TestSession_SharedUIDs(t *testing.T) {
|
||||
alice := FindSessionByRefID("sessxkkcabcd")
|
||||
alice.RefreshUser()
|
||||
alice.User().RefreshShares()
|
||||
alice.GetUser().RefreshShares()
|
||||
assert.Equal(t, "as6sg6bxpogaaba9", alice.SharedUIDs()[0])
|
||||
|
||||
bob := FindSessionByRefID("sessxkkcabce")
|
||||
bob.RefreshUser()
|
||||
bob.User().RefreshShares()
|
||||
bob.GetUser().RefreshShares()
|
||||
assert.Empty(t, bob.SharedUIDs())
|
||||
|
||||
m := &Session{}
|
||||
@@ -867,12 +867,12 @@ func TestSession_RedeemToken(t *testing.T) {
|
||||
t.Run("bob", func(t *testing.T) {
|
||||
bob := FindSessionByRefID("sessxkkcabce")
|
||||
bob.RefreshUser()
|
||||
bob.User().RefreshShares()
|
||||
bob.GetUser().RefreshShares()
|
||||
assert.Equal(t, 0, bob.RedeemToken("1234"))
|
||||
assert.Empty(t, bob.User().UserShares)
|
||||
assert.Empty(t, bob.GetUser().UserShares)
|
||||
assert.Equal(t, 1, bob.RedeemToken("1jxf3jfn2k"))
|
||||
bob.User().RefreshShares()
|
||||
assert.Equal(t, "as6sg6bxpogaaba8", bob.User().UserShares[0].ShareUID)
|
||||
bob.GetUser().RefreshShares()
|
||||
assert.Equal(t, "as6sg6bxpogaaba8", bob.GetUser().UserShares[0].ShareUID)
|
||||
})
|
||||
t.Run("Empty session", func(t *testing.T) {
|
||||
m := &Session{}
|
||||
|
||||
@@ -38,7 +38,7 @@ func UserAlbums(frm form.SearchAlbums, sess *entity.Session) (results AlbumResul
|
||||
|
||||
// Check session permissions and apply as needed.
|
||||
if sess != nil {
|
||||
user := sess.User()
|
||||
user := sess.GetUser()
|
||||
aclRole := user.AclRole()
|
||||
|
||||
// Determine resource to check.
|
||||
|
||||
@@ -135,7 +135,7 @@ func searchPhotos(frm form.SearchPhotos, sess *entity.Session, resultCols string
|
||||
|
||||
// Check session permissions and apply as needed.
|
||||
if sess != nil {
|
||||
user := sess.User()
|
||||
user := sess.GetUser()
|
||||
aclRole := user.AclRole()
|
||||
|
||||
// Exclude private content.
|
||||
@@ -156,7 +156,7 @@ func searchPhotos(frm form.SearchPhotos, sess *entity.Session, resultCols string
|
||||
}
|
||||
|
||||
// Visitors and other restricted users can only access shared content.
|
||||
if frm.Scope != "" && album.CreatedBy != user.UserUID && !sess.HasShare(frm.Scope) && (sess.User().HasSharedAccessOnly(acl.ResourcePhotos) || sess.NotRegistered()) ||
|
||||
if frm.Scope != "" && album.CreatedBy != user.UserUID && !sess.HasShare(frm.Scope) && (sess.GetUser().HasSharedAccessOnly(acl.ResourcePhotos) || sess.NotRegistered()) ||
|
||||
frm.Scope == "" && acl.Rules.Deny(acl.ResourcePhotos, aclRole, acl.ActionSearch) {
|
||||
event.AuditErr([]string{sess.IP(), "session %s", "%s %s as %s", authn.Denied}, sess.RefID, acl.ActionSearch.String(), string(acl.ResourcePhotos), aclRole)
|
||||
return PhotoResults{}, 0, ErrForbidden
|
||||
|
||||
@@ -118,7 +118,7 @@ func UserPhotosGeo(frm form.SearchPhotosGeo, sess *entity.Session) (results GeoR
|
||||
|
||||
// Check session permissions and apply as needed.
|
||||
if sess != nil {
|
||||
user := sess.User()
|
||||
user := sess.GetUser()
|
||||
aclRole := user.AclRole()
|
||||
|
||||
// Exclude private content.
|
||||
@@ -134,7 +134,7 @@ func UserPhotosGeo(frm form.SearchPhotosGeo, sess *entity.Session) (results GeoR
|
||||
}
|
||||
|
||||
// Visitors and other restricted users can only access shared content.
|
||||
if frm.Scope != "" && album.CreatedBy != user.UserUID && !sess.HasShare(frm.Scope) && (sess.User().HasSharedAccessOnly(acl.ResourcePlaces) || sess.NotRegistered()) ||
|
||||
if frm.Scope != "" && album.CreatedBy != user.UserUID && !sess.HasShare(frm.Scope) && (sess.GetUser().HasSharedAccessOnly(acl.ResourcePlaces) || sess.NotRegistered()) ||
|
||||
frm.Scope == "" && acl.Rules.Deny(acl.ResourcePlaces, aclRole, acl.ActionSearch) {
|
||||
event.AuditErr([]string{sess.IP(), "session %s", "%s %s as %s", authn.Denied}, sess.RefID, acl.ActionSearch.String(), string(acl.ResourcePlaces), aclRole)
|
||||
return GeoResults{}, ErrForbidden
|
||||
|
||||
@@ -108,32 +108,32 @@ func WebDAVAuth(conf *config.Config) gin.HandlerFunc {
|
||||
// Ignore and try basic auth next.
|
||||
} else if !sess.HasUser() || user == nil {
|
||||
// Log error if session does not belong to an authorized user account.
|
||||
event.AuditErr([]string{clientIp, "webdav", "client %s", "session %s", "access without user account", authn.Denied}, clean.Log(sess.ClientInfo()), sess.RefID)
|
||||
event.AuditErr([]string{clientIp, "webdav", "client %s", "session %s", "access without user account", authn.Denied}, clean.Log(sess.GetClientInfo()), sess.RefID)
|
||||
WebDAVAbortUnauthorized(c)
|
||||
return
|
||||
} else if sess.IsClient() && sess.InsufficientScope(acl.ResourceWebDAV, nil) {
|
||||
// Log error if the client is allowed to access webdav based on its scope.
|
||||
message := authn.ErrInsufficientScope.Error()
|
||||
event.AuditWarn([]string{clientIp, "webdav", "client %s", "session %s", "access as %s", message}, clean.Log(sess.ClientInfo()), sess.RefID, clean.LogQuote(user.Username()))
|
||||
event.AuditWarn([]string{clientIp, "webdav", "client %s", "session %s", "access as %s", message}, clean.Log(sess.GetClientInfo()), sess.RefID, clean.LogQuote(user.Username()))
|
||||
WebDAVAbortUnauthorized(c)
|
||||
return
|
||||
} else if !user.CanUseWebDAV() {
|
||||
// Log warning if WebDAV is disabled for this account.
|
||||
message := authn.ErrWebDAVAccessDisabled.Error()
|
||||
event.AuditWarn([]string{clientIp, "webdav", "client %s", "session %s", "access as %s", message}, clean.Log(sess.ClientInfo()), sess.RefID, clean.LogQuote(user.Username()))
|
||||
event.AuditWarn([]string{clientIp, "webdav", "client %s", "session %s", "access as %s", message}, clean.Log(sess.GetClientInfo()), sess.RefID, clean.LogQuote(user.Username()))
|
||||
WebDAVAbortUnauthorized(c)
|
||||
return
|
||||
} else if username != "" && !strings.EqualFold(clean.Username(username), user.Username()) {
|
||||
limiter.Auth.Reserve(clientIp)
|
||||
// Log warning if auth token username and specified username do not match.
|
||||
message := authn.ErrUsernameDoesNotMatch.Error()
|
||||
event.AuditWarn([]string{clientIp, "webdav", "client %s", "session %s", "access as %s", message}, clean.Log(sess.ClientInfo()), sess.RefID, clean.LogQuote(user.Username()))
|
||||
event.AuditWarn([]string{clientIp, "webdav", "client %s", "session %s", "access as %s", message}, clean.Log(sess.GetClientInfo()), sess.RefID, clean.LogQuote(user.Username()))
|
||||
WebDAVAbortUnauthorized(c)
|
||||
return
|
||||
} else if err := fs.MkdirAll(filepath.Join(conf.OriginalsPath(), user.GetUploadPath())); err != nil {
|
||||
// Log warning if upload path could not be created.
|
||||
message := authn.ErrFailedToCreateUploadPath.Error()
|
||||
event.AuditWarn([]string{clientIp, "webdav", "client %s", "session %s", "access as %s", message}, clean.Log(sess.ClientInfo()), sess.RefID, clean.LogQuote(user.Username()))
|
||||
event.AuditWarn([]string{clientIp, "webdav", "client %s", "session %s", "access as %s", message}, clean.Log(sess.GetClientInfo()), sess.RefID, clean.LogQuote(user.Username()))
|
||||
WebDAVAbortServerError(c)
|
||||
return
|
||||
} else {
|
||||
@@ -141,7 +141,7 @@ func WebDAVAuth(conf *config.Config) gin.HandlerFunc {
|
||||
sess.UpdateLastActive(true)
|
||||
|
||||
// Log successful authentication.
|
||||
event.AuditInfo([]string{clientIp, "webdav", "client %s", "session %s", "access as %s", authn.Succeeded}, clean.Log(sess.ClientInfo()), sess.RefID, clean.LogQuote(user.Username()))
|
||||
event.AuditInfo([]string{clientIp, "webdav", "client %s", "session %s", "access as %s", authn.Succeeded}, clean.Log(sess.GetClientInfo()), sess.RefID, clean.LogQuote(user.Username()))
|
||||
event.LoginInfo(clientIp, "webdav", user.Username(), api.UserAgent(c))
|
||||
|
||||
// Cache authentication to improve performance.
|
||||
|
||||
@@ -56,5 +56,5 @@ func WebDAVAuthSession(c *gin.Context, authToken string) (sess *entity.Session,
|
||||
sess.UpdateContext(c)
|
||||
|
||||
// Return session and user.
|
||||
return sess, sess.User(), sid, false
|
||||
return sess, sess.GetUser(), sid, false
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ type NodeOpts struct {
|
||||
// NodeOptsForSession returns the default exposure policy for a session.
|
||||
// Admin users see internalUrl and DB metadata; others get a redacted view.
|
||||
func NodeOptsForSession(s *entity.Session) NodeOpts {
|
||||
if s != nil && s.User() != nil && s.User().IsAdmin() {
|
||||
if s != nil && s.GetUser() != nil && s.GetUser().IsAdmin() {
|
||||
return NodeOpts{IncludeInternalURL: true, IncludeDBMeta: true}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user