1
Fork 0
mirror of https://github.com/jech/galene.git synced 2024-11-22 16:45:58 +01:00

Keep track of issuer and creation date in tokens.

This commit is contained in:
Juliusz Chroboczek 2023-04-08 21:13:35 +02:00
parent c501b76d2b
commit 8775ce6406
4 changed files with 50 additions and 18 deletions

View file

@ -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 {
} }
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",
) )

View file

@ -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
} }
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
/** /**
* @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(),
]; ];
} }

View file

@ -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 {

View file

@ -11,23 +11,29 @@ import (
"time" "time"
) )
func equal(a, b *Stateful) bool { func timeEqual(a, b *time.Time) bool {
if a.Token != b.Token || a.Group != b.Group || if a == nil && b == nil {
!reflect.DeepEqual(a.Username, b.Username) || return true
!reflect.DeepEqual(a.Permissions, b.Permissions) {
return false
} }
if a.Expires != nil && b.Expires != nil {
return (*a.Expires).Equal(*b.Expires) if a!= nil && b != nil {
return (*a).Equal(*b)
} }
if (a.Expires != nil) != (b.Expires != nil) {
return false return false
} }
if a.NotBefore != nil && b.NotBefore != nil { func equal(a, b *Stateful) bool {
return (*a.NotBefore).Equal(*b.NotBefore) if a.Token != b.Token || a.Group != b.Group ||
!reflect.DeepEqual(a.Username, b.Username) ||
!reflect.DeepEqual(a.Permissions, b.Permissions) ||
!timeEqual(a.Expires, b.Expires) ||
!reflect.DeepEqual(a.IssuedBy, b.IssuedBy) ||
!timeEqual(a.IssuedAt, b.IssuedAt) {
return false
} }
return (a.NotBefore != nil) == (b.NotBefore != nil)
return true
} }
func TestStatefulCheck(t *testing.T) { func TestStatefulCheck(t *testing.T) {