Commit 8775ce64 authored by Juliusz Chroboczek's avatar Juliusz Chroboczek

Keep track of issuer and creation date in tokens.

parent c501b76d
...@@ -1748,6 +1748,14 @@ func handleClientMessage(c *webClient, m clientMessage) error { ...@@ -1748,6 +1748,14 @@ func handleClientMessage(c *webClient, m clientMessage) error {
} }
} }
user := c.username
if user != "" {
tok.IssuedBy = &user
}
now := time.Now()
tok.IssuedAt = &now
new, err := token.Add(tok) new, err := token.Add(tok)
if err != nil { if err != nil {
return terror("error", err.Error()) return terror("error", err.Error())
...@@ -1778,7 +1786,9 @@ func handleClientMessage(c *webClient, m clientMessage) error { ...@@ -1778,7 +1786,9 @@ func handleClientMessage(c *webClient, m clientMessage) error {
} }
if tok.Group != "" || tok.Username != nil || if tok.Group != "" || tok.Username != nil ||
tok.Permissions != nil || tok.Permissions != nil ||
tok.NotBefore != nil { tok.NotBefore != nil ||
tok.IssuedBy != nil ||
tok.IssuedAt != nil {
return terror( return terror(
"error", "this field cannot be edited", "error", "this field cannot be edited",
) )
......
...@@ -2651,7 +2651,7 @@ function gotUserMessage(id, dest, username, time, privileged, kind, error, messa ...@@ -2651,7 +2651,7 @@ function gotUserMessage(id, dest, username, time, privileged, kind, error, messa
displayError('Unexpected type for token'); displayError('Unexpected type for token');
return; return;
} }
let f = formatToken(message); let f = formatToken(message, false);
localMessage(f[0] + ': ' + f[1]); localMessage(f[0] + ': ' + f[1]);
if('share' in navigator) { if('share' in navigator) {
try { try {
...@@ -2676,7 +2676,7 @@ function gotUserMessage(id, dest, username, time, privileged, kind, error, messa ...@@ -2676,7 +2676,7 @@ function gotUserMessage(id, dest, username, time, privileged, kind, error, messa
} }
let s = ''; let s = '';
for(let i = 0; i < message.length; i++) { for(let i = 0; i < message.length; i++) {
let f = formatToken(message[i]); let f = formatToken(message[i], true);
s = s + f[0] + ': ' + f[1] + "\n"; s = s + f[0] + ': ' + f[1] + "\n";
} }
localMessage(s); localMessage(s);
...@@ -2689,23 +2689,37 @@ function gotUserMessage(id, dest, username, time, privileged, kind, error, messa ...@@ -2689,23 +2689,37 @@ function gotUserMessage(id, dest, username, time, privileged, kind, error, messa
/** /**
* @param {Object} token * @param {Object} token
* @param {boolean} [details]
*/ */
function formatToken(token) { function formatToken(token, details) {
let url = new URL(window.location.href); let url = new URL(window.location.href);
let params = new URLSearchParams(); let params = new URLSearchParams();
params.append('token', token.token); params.append('token', token.token);
url.search = params.toString(); url.search = params.toString();
let foruser = '' let foruser = '', by = '', togroup = '';
if(token.username) if(token.username)
foruser = ` for user ${token.username}`; foruser = ` for user ${token.username}`;
if(details) {
if(token.issuedBy)
by = ' issued by ' + token.issuedBy;
if(token.issuedAt) {
if(by === '')
by = ' issued at ' + token.issuedAt;
else
by = by + ' at ' + (new Date(token.issuedAt)).toLocaleString();
}
} else {
if(token.group)
togroup = ' to group ' + token.group;
}
/** @type{Date} */ /** @type{Date} */
let expires = null; let expires = null;
if(token.expires) if(token.expires)
expires = new Date(token.expires); expires = new Date(token.expires);
return [ return [
(expires && (expires >= new Date())) ? (expires && (expires >= new Date())) ?
`Invitation${foruser} valid until ${expires.toLocaleString()}` : `Invitation${foruser}${togroup}${by} valid until ${expires.toLocaleString()}` :
`Expired invitation${foruser}`, `Expired invitation${foruser}${togroup}${by}`,
url.toString(), url.toString(),
]; ];
} }
......
...@@ -19,6 +19,8 @@ type Stateful struct { ...@@ -19,6 +19,8 @@ type Stateful struct {
Permissions []string `json:"permissions"` Permissions []string `json:"permissions"`
Expires *time.Time `json:"expires"` Expires *time.Time `json:"expires"`
NotBefore *time.Time `json:"not-before,omitempty"` NotBefore *time.Time `json:"not-before,omitempty"`
IssuedAt *time.Time `json:"issuedAt,omitempty"`
IssuedBy *string `json:"issuedBy,omitempty"`
} }
func (token *Stateful) Clone() *Stateful { func (token *Stateful) Clone() *Stateful {
......
...@@ -11,23 +11,29 @@ import ( ...@@ -11,23 +11,29 @@ import (
"time" "time"
) )
func timeEqual(a, b *time.Time) bool {
if a == nil && b == nil {
return true
}
if a!= nil && b != nil {
return (*a).Equal(*b)
}
return false
}
func equal(a, b *Stateful) bool { func equal(a, b *Stateful) bool {
if a.Token != b.Token || a.Group != b.Group || if a.Token != b.Token || a.Group != b.Group ||
!reflect.DeepEqual(a.Username, b.Username) || !reflect.DeepEqual(a.Username, b.Username) ||
!reflect.DeepEqual(a.Permissions, b.Permissions) { !reflect.DeepEqual(a.Permissions, b.Permissions) ||
return false !timeEqual(a.Expires, b.Expires) ||
} !reflect.DeepEqual(a.IssuedBy, b.IssuedBy) ||
if a.Expires != nil && b.Expires != nil { !timeEqual(a.IssuedAt, b.IssuedAt) {
return (*a.Expires).Equal(*b.Expires)
}
if (a.Expires != nil) != (b.Expires != nil) {
return false return false
} }
if a.NotBefore != nil && b.NotBefore != nil { return true
return (*a.NotBefore).Equal(*b.NotBefore)
}
return (a.NotBefore != nil) == (b.NotBefore != nil)
} }
func TestStatefulCheck(t *testing.T) { func TestStatefulCheck(t *testing.T) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment