Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
accountserver
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
2
Issues
2
List
Boards
Labels
Service Desk
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ai3
accountserver
Commits
11821eaf
Commit
11821eaf
authored
Jul 01, 2018
by
ale
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Move resource grouping out of the backend
It makes more sense to have this directly on the User object.
parent
e15acb1e
Pipeline
#1029
passed with stages
in 1 minute and 27 seconds
Changes
5
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
126 additions
and
66 deletions
+126
-66
actions_test.go
actions_test.go
+79
-0
backend/model.go
backend/model.go
+0
-39
backend/model_test.go
backend/model_test.go
+0
-27
service.go
service.go
+6
-0
types.go
types.go
+41
-0
No files found.
actions_test.go
View file @
11821eaf
...
...
@@ -249,6 +249,85 @@ func TestService_GetUser(t *testing.T) {
}
}
func
TestService_GetUser_ResourceGroups
(
t
*
testing
.
T
)
{
fb
:=
createFakeBackend
()
tx
,
_
:=
fb
.
NewTransaction
()
svc
,
_
:=
newAccountServiceWithSSO
(
fb
,
testConfig
(),
&
fakeValidator
{})
fb
.
addUser
(
&
User
{
Name
:
"testuser2"
,
Resources
:
[]
*
Resource
{
{
ID
:
NewResourceID
(
ResourceTypeDAV
,
"testuser2"
,
"dav1"
),
Name
:
"dav1"
,
DAV
:
&
WebDAV
{
Homedir
:
"/home/users/investici.org/dav1"
,
},
},
{
ID
:
NewResourceID
(
ResourceTypeDAV
,
"testuser2"
,
"dav1-domain2"
),
Name
:
"dav1-domain2"
,
DAV
:
&
WebDAV
{
Homedir
:
"/home/users/investici.org/dav1/html-domain2.com/subdir"
,
},
},
{
ID
:
NewResourceID
(
ResourceTypeDomain
,
"testuser2"
,
"domain1.com"
),
Name
:
"domain1.com"
,
Website
:
&
Website
{
DocumentRoot
:
"/home/users/investici.org/dav1/html-domain1.com"
,
},
},
{
ID
:
NewResourceID
(
ResourceTypeDomain
,
"testuser2"
,
"domain2.com"
),
Name
:
"domain2.com"
,
Website
:
&
Website
{
DocumentRoot
:
"/home/users/investici.org/dav1/html-domain2.com"
,
},
},
{
ID
:
NewResourceID
(
ResourceTypeDatabase
,
"testuser2"
,
"cn=domain2.com"
,
"db2"
),
ParentID
:
NewResourceID
(
ResourceTypeDomain
,
"testuser2"
,
"domain2.com"
),
Name
:
"db2"
,
Database
:
&
Database
{},
},
},
},
""
,
""
)
req
:=
&
GetUserRequest
{
RequestBase
:
RequestBase
{
Username
:
"testuser2"
,
SSO
:
"testuser2"
,
},
}
user
,
err
:=
svc
.
GetUser
(
context
.
TODO
(),
tx
,
req
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
var
grouped
[]
*
Resource
for
_
,
r
:=
range
user
.
Resources
{
switch
r
.
ID
.
Type
()
{
case
ResourceTypeWebsite
,
ResourceTypeDomain
,
ResourceTypeDAV
,
ResourceTypeDatabase
:
grouped
=
append
(
grouped
,
r
)
}
}
var
group
string
for
_
,
r
:=
range
grouped
{
if
r
.
Group
==
""
{
t
.
Errorf
(
"group not set on %s"
,
r
.
ID
)
continue
}
if
group
==
""
{
group
=
r
.
Group
}
else
if
group
!=
r
.
Group
{
t
.
Errorf
(
"wrong group on %s (%s, expected %s)"
,
r
.
ID
,
r
.
Group
,
group
)
}
}
}
func
TestService_Auth
(
t
*
testing
.
T
)
{
svc
,
tx
:=
testService
(
"adminuser"
)
...
...
backend/model.go
View file @
11821eaf
...
...
@@ -274,8 +274,6 @@ func (tx *backendTX) GetUser(ctx context.Context, username string) (*accountserv
}
}
groupWebResourcesByHomedir
(
user
.
Resources
)
return
user
,
nil
}
...
...
@@ -538,40 +536,3 @@ func (tx *backendTX) isUIDAvailable(ctx context.Context, uid int) (bool, error)
}
return
true
,
nil
}
var
siteRoot
=
"/home/users/investici.org/"
// The hosting directory for a website is the path component immediately after
// siteRoot. This works also for sites with nested documentRoots.
func
getHostingDir
(
path
string
)
string
{
path
=
strings
.
TrimPrefix
(
path
,
siteRoot
)
if
i
:=
strings
.
Index
(
path
,
"/"
);
i
>
0
{
return
path
[
:
i
]
}
return
path
}
// This is a very specific function meant to address a peculiar characteristic
// of the A/I legacy data model, where DAV accounts and websites do not have an
// explicit relation.
func
groupWebResourcesByHomedir
(
resources
[]
*
accountserver
.
Resource
)
{
// Set the group name to be the 'hostingDir' for sites and DAV
// accounts. Keep a reference of websites by ID so we can later fix the
// group for databases too, via their ParentID.
webs
:=
make
(
map
[
string
]
*
accountserver
.
Resource
)
for
_
,
r
:=
range
resources
{
switch
r
.
ID
.
Type
()
{
case
accountserver
.
ResourceTypeWebsite
,
accountserver
.
ResourceTypeDomain
:
r
.
Group
=
getHostingDir
(
r
.
Website
.
DocumentRoot
)
webs
[
r
.
ID
.
String
()]
=
r
case
accountserver
.
ResourceTypeDAV
:
r
.
Group
=
getHostingDir
(
r
.
DAV
.
Homedir
)
}
}
// Fix databases in a second pass.
for
_
,
r
:=
range
resources
{
if
r
.
ID
.
Type
()
==
accountserver
.
ResourceTypeDatabase
&&
!
r
.
ParentID
.
Empty
()
{
r
.
Group
=
webs
[
r
.
ParentID
.
String
()]
.
Group
}
}
}
backend/model_test.go
View file @
11821eaf
...
...
@@ -102,7 +102,6 @@ func TestModel_GetUser(t *testing.T) {
Name
:
"unodb"
,
Shard
:
"host2"
,
OriginalShard
:
"host2"
,
Group
:
"uno"
,
Status
:
accountserver
.
ResourceStatusActive
,
Database
:
&
accountserver
.
Database
{
CleartextPassword
:
"password"
,
...
...
@@ -126,32 +125,6 @@ func TestModel_GetUser_Has2FA(t *testing.T) {
}
}
func
TestModel_GetUser_Group
(
t
*
testing
.
T
)
{
stop
,
_
,
user
:=
startServerAndGetUser
(
t
)
defer
stop
()
var
grouped
[]
*
accountserver
.
Resource
for
_
,
r
:=
range
user
.
Resources
{
switch
r
.
ID
.
Type
()
{
case
accountserver
.
ResourceTypeWebsite
,
accountserver
.
ResourceTypeDomain
,
accountserver
.
ResourceTypeDAV
,
accountserver
.
ResourceTypeDatabase
:
grouped
=
append
(
grouped
,
r
)
}
}
var
group
string
for
_
,
r
:=
range
grouped
{
if
r
.
Group
==
""
{
t
.
Errorf
(
"group not set on %s"
,
r
.
ID
)
continue
}
if
group
==
""
{
group
=
r
.
Group
}
else
if
group
!=
r
.
Group
{
t
.
Errorf
(
"wrong group on %s (%s, expected %s)"
,
r
.
ID
,
r
.
Group
,
group
)
}
}
}
func
TestModel_GetUser_Resources
(
t
*
testing
.
T
)
{
stop
,
b
,
user
:=
startServerAndGetUser
(
t
)
defer
stop
()
...
...
service.go
View file @
11821eaf
...
...
@@ -144,6 +144,9 @@ func (s *authService) validateSSO(ssoToken string) (*sso.Ticket, error) {
return
s
.
validator
.
Validate
(
ssoToken
,
""
,
s
.
ssoService
,
s
.
ssoGroups
)
}
// Fetch a user from the backend and return an error if not found
// (instead of returning a nil User). Also, set dynamic attributes
// like resource Groups.
func
getUserOrDie
(
ctx
context
.
Context
,
tx
TX
,
username
string
)
(
*
User
,
error
)
{
user
,
err
:=
tx
.
GetUser
(
ctx
,
username
)
if
err
!=
nil
{
...
...
@@ -152,6 +155,9 @@ func getUserOrDie(ctx context.Context, tx TX, username string) (*User, error) {
if
user
==
nil
{
return
nil
,
ErrUserNotFound
}
user
.
groupWebResources
()
return
user
,
nil
}
...
...
types.go
View file @
11821eaf
...
...
@@ -352,3 +352,44 @@ type Blog struct {
Name
string
`json:"name"`
URL
string
`json:"url"`
}
const
hardcodedWebRoot
=
"/home/users/investici.org"
// Group web-related resources into groups.
//
// This is a very specific function meant to address a peculiar characteristic
// of the A/I legacy data model, where DAV accounts and websites do not have an
// explicit relation.
//
// TODO: Ideally we should be able to do this without hard-coding the webroot.
func
(
u
*
User
)
groupWebResources
()
{
// Set the group name to be the 'hostingDir' for sites and DAV
// accounts. Keep a reference of websites by ID so we can later fix the
// group for databases too, via their ParentID.
webs
:=
make
(
map
[
string
]
*
Resource
)
for
_
,
r
:=
range
u
.
Resources
{
switch
r
.
ID
.
Type
()
{
case
ResourceTypeWebsite
,
ResourceTypeDomain
:
r
.
Group
=
getHostingDir
(
r
.
Website
.
DocumentRoot
,
hardcodedWebRoot
)
webs
[
r
.
ID
.
String
()]
=
r
case
ResourceTypeDAV
:
r
.
Group
=
getHostingDir
(
r
.
DAV
.
Homedir
,
hardcodedWebRoot
)
}
}
// Fix databases in a second pass.
for
_
,
r
:=
range
u
.
Resources
{
if
r
.
ID
.
Type
()
==
ResourceTypeDatabase
&&
!
r
.
ParentID
.
Empty
()
{
r
.
Group
=
webs
[
r
.
ParentID
.
String
()]
.
Group
}
}
}
// The hosting directory for a website is the path component immediately after
// siteRoot. This works also for sites with nested documentRoots.
func
getHostingDir
(
path
,
siteRoot
string
)
string
{
path
=
strings
.
TrimPrefix
(
strings
.
TrimPrefix
(
path
,
siteRoot
),
"/"
)
if
i
:=
strings
.
Index
(
path
,
"/"
);
i
>
0
{
return
path
[
:
i
]
}
return
path
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment