Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
id
auth
Commits
e06ac2a9
Commit
e06ac2a9
authored
Feb 10, 2019
by
shammash
1
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'last_login' into 'master'
Last login See merge request
!3
parents
b0d2931a
12462a89
Pipeline
#2216
passed with stages
in 1 minute and 33 seconds
Changes
9
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
150 additions
and
13 deletions
+150
-13
.gitignore
.gitignore
+1
-0
README.md
README.md
+2
-0
server/authserver.go
server/authserver.go
+11
-0
server/config.go
server/config.go
+6
-5
server/lastlogin.go
server/lastlogin.go
+53
-0
vendor/git.autistici.org/id/usermetadb/README.md
vendor/git.autistici.org/id/usermetadb/README.md
+21
-2
vendor/git.autistici.org/id/usermetadb/client/client.go
vendor/git.autistici.org/id/usermetadb/client/client.go
+18
-0
vendor/git.autistici.org/id/usermetadb/protocol.go
vendor/git.autistici.org/id/usermetadb/protocol.go
+32
-0
vendor/vendor.json
vendor/vendor.json
+6
-6
No files found.
.gitignore
0 → 100644
View file @
e06ac2a9
*.swp
README.md
View file @
e06ac2a9
...
...
@@ -116,6 +116,8 @@ Each service definition is a dictionary with the following attributes:
only for interactive services)
*
`enforce_2fa`
is a boolean flag that, when true, will disable
non-2FA logins for this service
*
`enable_last_login_reporting`
is a boolean flag that enables last login
reporting to usermetadb
*
`enable_device_tracking`
is a boolean flag that enables device
tracking for this service (assuming the client provides device
information)
...
...
server/authserver.go
View file @
e06ac2a9
...
...
@@ -203,6 +203,17 @@ func createService(config *Config, sc *ServiceConfig, backends map[string]userBa
}
}
if
sc
.
EnableLastLoginReporting
{
if
config
.
UserMetaDBConfig
==
nil
{
return
nil
,
errors
.
New
(
"usermetadb config is missing"
)
}
llr
,
err
:=
newLastLoginFilter
(
config
.
UserMetaDBConfig
)
if
err
!=
nil
{
return
nil
,
err
}
s
.
filters
=
append
(
s
.
filters
,
llr
)
}
// Enabling device tracking also enables user activity
// logging.
if
sc
.
EnableDeviceTracking
{
...
...
server/config.go
View file @
e06ac2a9
...
...
@@ -19,11 +19,12 @@ type BackendSpec struct {
// ServiceConfig defines the authentication backends for a service.
type
ServiceConfig
struct
{
BackendSpecs
[]
*
BackendSpec
`yaml:"backends"`
ChallengeResponse
bool
`yaml:"challenge_response"`
Enforce2FA
bool
`yaml:"enforce_2fa"`
EnableDeviceTracking
bool
`yaml:"enable_device_tracking"`
Ratelimits
[]
string
`yaml:"rate_limits"`
BackendSpecs
[]
*
BackendSpec
`yaml:"backends"`
ChallengeResponse
bool
`yaml:"challenge_response"`
Enforce2FA
bool
`yaml:"enforce_2fa"`
EnableLastLoginReporting
bool
`yaml:"enable_last_login_reporting"`
EnableDeviceTracking
bool
`yaml:"enable_device_tracking"`
Ratelimits
[]
string
`yaml:"rate_limits"`
}
// Config for the authentication server.
...
...
server/lastlogin.go
0 → 100644
View file @
e06ac2a9
package
server
import
(
"context"
"log"
"time"
"git.autistici.org/ai3/go-common/clientutil"
"git.autistici.org/id/auth"
"git.autistici.org/id/usermetadb"
"git.autistici.org/id/usermetadb/client"
)
type
setLastLoginClient
interface
{
SetLastLogin
(
context
.
Context
,
string
,
*
usermetadb
.
LastLoginEntry
)
error
}
type
lastloginFilter
struct
{
client
setLastLoginClient
}
func
newLastLoginFilter
(
config
*
clientutil
.
BackendConfig
)
(
*
lastloginFilter
,
error
)
{
c
,
err
:=
client
.
New
(
config
)
if
err
!=
nil
{
return
nil
,
err
}
return
&
lastloginFilter
{
c
},
nil
}
var
lastloginTimeout
=
30
*
time
.
Second
func
(
f
*
lastloginFilter
)
Filter
(
user
*
User
,
req
*
auth
.
Request
,
resp
*
auth
.
Response
)
*
auth
.
Response
{
if
resp
.
Status
!=
auth
.
StatusOK
{
return
resp
}
entry
:=
usermetadb
.
LastLoginEntry
{
Timestamp
:
time
.
Now
(),
Username
:
user
.
Name
,
Service
:
req
.
Service
,
}
// Make the log RPC in the background, no need to wait for it to complete.
go
func
()
{
ctx
,
cancel
:=
context
.
WithTimeout
(
context
.
Background
(),
lastloginTimeout
)
defer
cancel
()
if
err
:=
f
.
client
.
SetLastLogin
(
ctx
,
user
.
Shard
,
&
entry
);
err
!=
nil
{
log
.
Printf
(
"usermetadb.SetLastLogin error for %s: %v"
,
user
.
Name
,
err
)
}
}()
return
resp
}
vendor/git.autistici.org/id/usermetadb/README.md
View file @
e06ac2a9
...
...
@@ -26,6 +26,11 @@ a specific device and an account if one is in possession of the
server-side log database (only partially mitigated by the fact that
the cookie is encrypted).
`usermetadb`
also stores last-login information for internal infrastructure
maintenance. The idea is to retain the minimal amount of information to perform
tasks such as "disable accounts that have not been active for more than N
years".
# API
The server exports an API over HTTP/HTTPS, all requests should be made
...
...
@@ -39,14 +44,14 @@ and the *analysis* API.
## Log API
`/api/add_log`
(
*AddLogRequest*
)
Stores a new log entry for a user in the database. The request must be
a
`LogEntry`
object. The method returns an empty response. If the log
entry contains device information, the list of devices for the
specified user is updated with that information.
`/api/get_user_logs`
(
*GetUserLogsRequest*
) ->
*GetUserLogsResponse*
Returns recent logs for a specific user.
`/api/get_user_devices`
(
*GetUserDevicesRequest*
) ->
*GetUserDevicesResponse*
...
...
@@ -60,6 +65,20 @@ Returns the list of known devices for a user.
Returns information about a device, whether we have seen it before, if
the localization information matches the historical trend, etc.
## Last-login API
`/api/set_last_login`
(
*SetLastLoginRequest*
)
Stores the last login of a user in the database. The request must be a
`LastLoginEntry`
object. The method returns an empty response. The service name
must be specified in the last login entry.
`/api/get_last_login`
(
*GetLastLoginRequest*
) ->
*GetLastLoginResponse*
Returns the last login of a given user. If the service name is specified it
returns the last login for that specific service, otherwise return last login
for all services.
# Configuration
...
...
vendor/git.autistici.org/id/usermetadb/client/client.go
View file @
e06ac2a9
...
...
@@ -15,6 +15,8 @@ type Client interface {
AddLog
(
context
.
Context
,
string
,
*
usermetadb
.
LogEntry
)
error
GetUserDevices
(
context
.
Context
,
string
,
string
)
([]
*
usermetadb
.
MetaDeviceInfo
,
error
)
GetUserLogs
(
context
.
Context
,
string
,
string
,
int
,
int
)
([]
*
usermetadb
.
LogEntry
,
error
)
SetLastLogin
(
context
.
Context
,
string
,
*
usermetadb
.
LastLoginEntry
)
error
GetLastLogin
(
context
.
Context
,
string
,
string
,
string
)
([]
*
usermetadb
.
LastLoginEntry
,
error
)
}
type
udbClient
struct
{
...
...
@@ -63,3 +65,19 @@ func (c *udbClient) GetUserLogs(ctx context.Context, shard, username string, max
err
:=
c
.
be
.
Call
(
ctx
,
shard
,
"/api/get_user_logs"
,
&
req
,
&
resp
)
return
resp
.
Results
,
err
}
func
(
c
*
udbClient
)
SetLastLogin
(
ctx
context
.
Context
,
shard
string
,
entry
*
usermetadb
.
LastLoginEntry
)
error
{
req
:=
usermetadb
.
SetLastLoginRequest
{
LastLogin
:
entry
}
return
c
.
be
.
Call
(
ctx
,
shard
,
"/api/set_last_login"
,
&
req
,
nil
)
}
func
(
c
*
udbClient
)
GetLastLogin
(
ctx
context
.
Context
,
shard
string
,
username
string
,
service
string
)
([]
*
usermetadb
.
LastLoginEntry
,
error
)
{
req
:=
usermetadb
.
GetLastLoginRequest
{
Username
:
username
,
Service
:
service
,
}
var
resp
usermetadb
.
GetLastLoginResponse
err
:=
c
.
be
.
Call
(
ctx
,
shard
,
"/api/get_last_login"
,
&
req
,
&
resp
)
return
resp
.
Results
,
err
}
vendor/git.autistici.org/id/usermetadb/protocol.go
View file @
e06ac2a9
...
...
@@ -92,3 +92,35 @@ type GetUserLogsRequest struct {
type
GetUserLogsResponse
struct
{
Results
[]
*
LogEntry
`json:"result"`
}
type
LastLoginEntry
struct
{
Timestamp
time
.
Time
`json:"timestamp"`
Username
string
`json:"username"`
Service
string
`json:"service"`
}
func
(
e
*
LastLoginEntry
)
Validate
()
error
{
if
e
.
Username
==
""
{
return
errors
.
New
(
"invalid last login entry: missing username"
)
}
if
e
.
Service
==
""
{
return
errors
.
New
(
"invalid last login entry: missing service"
)
}
return
nil
}
type
SetLastLoginRequest
struct
{
LastLogin
*
LastLoginEntry
`json:"last_login"`
}
type
SetLastLoginResponse
struct
{}
type
GetLastLoginRequest
struct
{
Username
string
`json:"username"`
Service
string
`json:"service,omitempty"`
}
type
GetLastLoginResponse
struct
{
Results
[]
*
LastLoginEntry
`json:"result"`
}
vendor/vendor.json
View file @
e06ac2a9
...
...
@@ -39,16 +39,16 @@
"revisionTime"
:
"2019-01-29T12:17:45Z"
},
{
"checksumSHA1"
:
"
NtTOmajRf6xh0mkVSm18L70ncl0
="
,
"checksumSHA1"
:
"
J0QeD9LVccFOejgPKa0td8JD0rY
="
,
"path"
:
"git.autistici.org/id/usermetadb"
,
"revision"
:
"
fa081ac5509ba4ed97ab6a447d611c1adcf9e764
"
,
"revisionTime"
:
"201
8-11-03T07:16:06
Z"
"revision"
:
"
61e5a7b24130b36be4964ffadae1b4a9ef803a7a
"
,
"revisionTime"
:
"201
9-02-09T10:52:39
Z"
},
{
"checksumSHA1"
:
"
kwosXxbzygo9ZUZSYvD+WiAbM3Q
="
,
"checksumSHA1"
:
"
HnFofi1vg8of8d1uVSRUX7LIAxI
="
,
"path"
:
"git.autistici.org/id/usermetadb/client"
,
"revision"
:
"
fa081ac5509ba4ed97ab6a447d611c1adcf9e764
"
,
"revisionTime"
:
"201
8-11-03T07:16:06
Z"
"revision"
:
"
61e5a7b24130b36be4964ffadae1b4a9ef803a7a
"
,
"revisionTime"
:
"201
9-02-09T10:52:39
Z"
},
{
"checksumSHA1"
:
"yReqUM4tQkY+1YEI+L2d0SOzFWs="
,
...
...
shammash
@shammash
mentioned in issue
#5 (closed)
·
Feb 10, 2019
mentioned in issue
#5 (closed)
mentioned in issue #5
Toggle commit list
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