-
-
Notifications
You must be signed in to change notification settings - Fork 60
/
user-d.go
123 lines (111 loc) · 3.5 KB
/
user-d.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package main
import (
"time"
lm "github.com/hrfee/jfa-go/logmessages"
"github.com/hrfee/mediabrowser"
"github.com/lithammer/shortuuid/v3"
)
func newUserDaemon(interval time.Duration, app *appContext) *GenericDaemon {
d := NewGenericDaemon(interval, app,
func(app *appContext) {
app.checkUsers()
},
)
d.Name("User daemon")
return d
}
func (app *appContext) checkUsers() {
if len(app.storage.GetUserExpiries()) == 0 {
return
}
app.info.Println(lm.CheckUserExpiries)
users, err := app.jf.GetUsers(false)
if err != nil {
app.err.Printf(lm.FailedGetUsers, lm.Jellyfin, err)
return
}
mode := "disable"
if app.config.Section("user_expiry").Key("behaviour").MustString("disable_user") == "delete_user" {
mode = "delete"
}
deleteAfterPeriod := app.config.Section("user_expiry").Key("delete_expired_after_days").MustInt(0)
if mode == "delete" {
deleteAfterPeriod = 0
}
contact := false
if messagesEnabled && app.config.Section("user_expiry").Key("send_email").MustBool(true) {
contact = true
}
// Use a map to speed up checking for deleted users later
userExists := map[string]mediabrowser.User{}
for _, user := range users {
userExists[user.ID] = user
}
for _, expiry := range app.storage.GetUserExpiries() {
id := expiry.JellyfinID
user, ok := userExists[id]
if !ok {
app.info.Printf(lm.DeleteExpiryForOldUser, id)
app.storage.DeleteUserExpiryKey(expiry.JellyfinID)
continue
}
if !time.Now().After(expiry.Expiry) {
continue
}
deleteUserLater := deleteAfterPeriod != 0 && expiry.DeleteAfterPeriod
// Record activity
activity := Activity{
UserID: id,
SourceType: ActivityDaemon,
Time: time.Now(),
}
deleteUserNow := deleteUserLater && time.Now().After(expiry.Expiry.AddDate(0, 0, deleteAfterPeriod))
if mode == "delete" || deleteUserNow {
app.info.Printf(lm.DeleteExpiredUser, user.Name)
deleted := false
err, deleted = app.DeleteUser(user)
// Silence unimportant errors
if deleted {
err = nil
}
activity.Type = ActivityDeletion
// Store the user name, since there's no longer a user ID to reference back to
activity.Value = user.Name
} else if mode == "disable" && !deleteUserLater {
app.info.Printf(lm.DisableExpiredUser, user.Name)
// Admins can't be disabled
// so they're not an admin anymore, sorry
user.Policy.IsAdministrator = false
err, _, _ = app.SetUserDisabled(user, true)
activity.Type = ActivityDisabled
}
if err != nil {
app.err.Printf(lm.FailedDeleteOrDisableExpiredUser, user.ID, err)
continue
}
app.storage.SetActivityKey(shortuuid.New(), activity, nil, false)
// If the we're not gonna be deleting the user later, we don't need this.
// also, if the admin re-enabled the user, we should get rid of the countdown.
if deleteAfterPeriod <= 0 || mode == "delete" || deleteUserNow || (deleteUserLater && !user.Policy.IsDisabled) {
app.storage.DeleteUserExpiryKey(user.ID)
} else if deleteAfterPeriod > 0 && !deleteUserLater {
expiry.DeleteAfterPeriod = true
app.storage.SetUserExpiryKey(user.ID, expiry)
}
app.jf.CacheExpiry = time.Now()
if contact {
if !ok {
continue
}
name := app.getAddressOrName(user.ID)
msg, err := app.email.constructUserExpired(app, false)
if err != nil {
app.err.Printf(lm.FailedConstructExpiryMessage, user.ID, err)
} else if err := app.sendByID(msg, user.ID); err != nil {
app.err.Printf(lm.FailedSendExpiryMessage, user.ID, name, err)
} else {
app.err.Printf(lm.SentExpiryMessage, user.ID, name)
}
}
}
}