Coverage for slidge / core / config.py: 100%

110 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2026-02-15 09:02 +0000

1from pathlib import Path 

2 

3from slixmpp import JID as JIDType 

4 

5# REQUIRED, so not default value 

6 

7 

8class _Categories: 

9 MANDATORY = (0, "Mandatory settings") 

10 BASE = (10, "Basic configuration") 

11 ATTACHMENTS = (20, "Attachments") 

12 LOG = (30, "Logging") 

13 ADVANCED = (40, "Advanced settings") 

14 

15 

16LEGACY_MODULE: str 

17LEGACY_MODULE__DOC = ( 

18 "Importable python module containing (at least) a BaseGateway and a LegacySession subclass. " 

19 "NB: this is not needed if you use a gateway-specific entrypoint, e.g., `slidgram` or " 

20 "`python -m slidgram`." 

21) 

22LEGACY_MODULE__CATEGORY = _Categories.BASE 

23 

24SERVER: str = "localhost" 

25SERVER__DOC = ( 

26 "The XMPP server's host name. Defaults to localhost, which is the " 

27 "standard way of running slidge, on the same host as the XMPP server. " 

28 "The 'Jabber Component Protocol' (XEP-0114) does not mention encryption, " 

29 "so you *should* provide encryption another way, eg via port forwarding, if " 

30 "you change this." 

31) 

32SERVER__SHORT = "s" 

33SERVER__CATEGORY = _Categories.BASE 

34 

35SECRET: str 

36SECRET__DOC = "The gateway component's secret (required to connect to the XMPP server)" 

37SECRET__CATEGORY = _Categories.MANDATORY 

38 

39JID: JIDType 

40JID__DOC = "The gateway component's JID" 

41JID__SHORT = "j" 

42JID__CATEGORY = _Categories.MANDATORY 

43 

44PORT: str = "5347" 

45PORT__DOC = "The XMPP server's port for incoming component connections" 

46PORT__SHORT = "p" 

47PORT__CATEGORY = _Categories.BASE 

48 

49# Dynamic default (depends on other values) 

50 

51HOME_DIR: Path 

52HOME_DIR__DOC = ( 

53 "Directory where slidge will writes it persistent data and cache. " 

54 "Defaults to /var/lib/slidge/${SLIDGE_JID}. " 

55) 

56HOME_DIR__DYNAMIC_DEFAULT = True 

57HOME_DIR__CATEGORY = _Categories.BASE 

58 

59DB_URL: str 

60DB_URL__DOC = ( 

61 "Database URL, see <https://docs.sqlalchemy.org/en/20/core/engines.html#database-urls>. " 

62 "Defaults to sqlite:///${HOME_DIR}/slidge.sqlite" 

63) 

64DB_URL__DYNAMIC_DEFAULT = True 

65DB_URL__CATEGORY = _Categories.ADVANCED 

66 

67USER_JID_VALIDATOR: str 

68USER_JID_VALIDATOR__DOC = ( 

69 "Regular expression to restrict users that can register to the gateway, by JID. " 

70 "Defaults to .*@${INFERRED_SERVER}. INFERRED_SERVER is derived for the gateway JID, " 

71 "by removing whatever is before the first encountered dot in it. Example: if " 

72 "slidge's JID=slidge.example.org, INFERRED_SERVER=example.org." 

73) 

74USER_JID_VALIDATOR__DYNAMIC_DEFAULT = True 

75USER_JID_VALIDATOR__CATEGORY = _Categories.BASE 

76 

77# Optional, so default value + type hint if default is None 

78 

79ADMINS: tuple[JIDType, ...] = () 

80ADMINS__DOC = "JIDs of the gateway admins" 

81ADMINS__CATEGORY = _Categories.BASE 

82 

83UPLOAD_SERVICE: str | None = None 

84UPLOAD_SERVICE__DOC = ( 

85 "JID of an HTTP upload service the gateway can use. " 

86 "This is optional, as it should be automatically determined via service" 

87 "discovery." 

88) 

89UPLOAD_SERVICE__CATEGORY = _Categories.ATTACHMENTS 

90 

91AVATAR_SIZE = 200 

92AVATAR_SIZE__DOC = ( 

93 "Maximum image size (width and height), image ratio will be preserved" 

94) 

95AVATAR_SIZE__CATEGORY = _Categories.ADVANCED 

96 

97USE_ATTACHMENT_ORIGINAL_URLS = False 

98USE_ATTACHMENT_ORIGINAL_URLS__DOC = ( 

99 "For legacy plugins in which attachments are publicly downloadable URLs, " 

100 "let XMPP clients directly download them from this URL. Note that this will " 

101 "probably leak your client IP to the legacy network." 

102) 

103USE_ATTACHMENT_ORIGINAL_URLS__CATEGORY = _Categories.ATTACHMENTS 

104 

105UPLOAD_REQUESTER: str | None = None 

106UPLOAD_REQUESTER__DOC = ( 

107 "Set which JID should request the upload slots. Defaults to the user's JID if " 

108 "IQ/get privileges granted for the 'urn:xmpp:http:upload:0' namespace; the component " 

109 "JID otherwise." 

110) 

111UPLOAD_REQUESTER__CATEGORY = _Categories.ATTACHMENTS 

112 

113UPLOAD_URL_PREFIX: str | None = None 

114UPLOAD_URL_PREFIX__DOC = ( 

115 "This is an optional setting to make sure the URL of your upload service is never leaked " 

116 "to the legacy network in bodies of messages. This can happen under rare circumstances and/or bugs," 

117 "when replying to an attachment. Set this to the common prefix of the public URL your attachments get, " 

118 "eg https://upload.example.org:5281/" 

119) 

120UPLOAD_URL_PREFIX__CATEGORY = _Categories.ATTACHMENTS 

121 

122NO_UPLOAD_PATH: str | None = None 

123NO_UPLOAD_PATH__DOC = ( 

124 "Instead of using the XMPP server's HTTP upload component, copy files to this dir. " 

125 "You need to set NO_UPLOAD_URL_PREFIX too if you use this option, and configure " 

126 "an web server to serve files in this dir." 

127) 

128NO_UPLOAD_PATH__CATEGORY = _Categories.ATTACHMENTS 

129 

130NO_UPLOAD_URL_PREFIX: str | None = None 

131NO_UPLOAD_URL_PREFIX__DOC = ( 

132 "Base URL that servers files in the dir set in the no-upload-path option, " 

133 "eg https://example.com:666/slidge-attachments/" 

134) 

135NO_UPLOAD_URL_PREFIX__CATEGORY = _Categories.ATTACHMENTS 

136 

137NO_UPLOAD_METHOD: str = "copy" 

138NO_UPLOAD_METHOD__DOC = ( 

139 "Whether to 'copy', 'move', 'hardlink' or 'symlink' the files in no-upload-path." 

140) 

141NO_UPLOAD_METHOD__CATEGORY = _Categories.ATTACHMENTS 

142 

143NO_UPLOAD_FILE_READ_OTHERS = False 

144NO_UPLOAD_FILE_READ_OTHERS__DOC = ( 

145 "After writing a file in NO_UPLOAD_PATH, change its permission so that 'others' can" 

146 " read it." 

147) 

148NO_UPLOAD_FILE_READ_OTHERS__CATEGORY = _Categories.ATTACHMENTS 

149 

150IGNORE_DELAY_THRESHOLD = 300 

151IGNORE_DELAY_THRESHOLD__DOC = ( 

152 "Threshold, in seconds, below which the <delay> information is stripped " 

153 "out of emitted stanzas." 

154) 

155IGNORE_DELAY_THRESHOLD__CATEGORY = _Categories.ADVANCED 

156 

157PARTIAL_REGISTRATION_TIMEOUT = 3600 

158PARTIAL_REGISTRATION_TIMEOUT__DOC = ( 

159 "Timeout before registration and login. Only useful for legacy networks where " 

160 "a single step registration process is not enough." 

161) 

162PARTIAL_REGISTRATION_TIMEOUT__CATEGORY = _Categories.ADVANCED 

163 

164QR_TIMEOUT = 60 

165QR_TIMEOUT__DOC = "Timeout for QR code flashing confirmation." 

166QR_TIMEOUT__CATEGORY = _Categories.ADVANCED 

167 

168FIX_FILENAME_SUFFIX_MIME_TYPE = False 

169FIX_FILENAME_SUFFIX_MIME_TYPE__DOC = ( 

170 "Fix the Filename suffix based on the Mime Type of the file. Some clients (eg" 

171 " Conversations) may not inline files that have a wrong suffix for the MIME Type." 

172 " Therefore the MIME Type of the file is checked, if the suffix is not valid for" 

173 " that MIME Type, a valid one will be picked." 

174) 

175FIX_FILENAME_SUFFIX_MIME_TYPE__CATEGORY = _Categories.ATTACHMENTS 

176 

177LOG_FILE: Path | None = None 

178LOG_FILE__DOC = "Log to a file instead of stdout/err" 

179LOG_FILE__CATEGORY = _Categories.LOG 

180 

181LOG_FORMAT: str = "%(levelname)s:%(name)s:%(message)s" 

182LOG_FORMAT__DOC = ( 

183 "Optionally, a format string for logging messages. Refer to " 

184 "https://docs.python.org/3/library/logging.html#logrecord-attributes " 

185 "for available options." 

186) 

187LOG_FORMAT__CATEGORY = _Categories.LOG 

188 

189MAM_MAX_DAYS = 7 

190MAM_MAX_DAYS__DOC = "Maximum number of days for group archive retention." 

191MAM_MAX_DAYS__CATEGORY = _Categories.BASE 

192 

193ATTACHMENT_MAXIMUM_FILE_NAME_LENGTH = 200 

194ATTACHMENT_MAXIMUM_FILE_NAME_LENGTH__DOC = ( 

195 "Some legacy network provide ridiculously long filenames, strip above this limit, " 

196 "preserving suffix." 

197) 

198ATTACHMENT_MAXIMUM_FILE_NAME_LENGTH__CATEGORY = _Categories.ATTACHMENTS 

199 

200CONVERT_STICKERS = False 

201CONVERT_STICKERS__DOC = ( 

202 "Convert lottie vector stickers (from the legacy side) to webp animations." 

203) 

204CONVERT_STICKERS__CATEGORY = _Categories.ATTACHMENTS 

205 

206AVATAR_RESAMPLING_THREADS = 2 

207AVATAR_RESAMPLING_THREADS__DOC = ( 

208 "Number of additional threads to use for avatar resampling. Even in a single-core " 

209 "context, this makes avatar resampling non-blocking." 

210) 

211AVATAR_RESAMPLING_THREADS__CATEGORY = _Categories.ADVANCED 

212 

213DEV_MODE = False 

214DEV_MODE__DOC = ( 

215 "Enables an interactive python shell via chat commands, for admins." 

216 "Not safe to use in prod, but great during dev." 

217) 

218DEV_MODE__CATEGORY = _Categories.ADVANCED 

219 

220 

221STRIP_LEADING_EMOJI_ADHOC = False 

222STRIP_LEADING_EMOJI_ADHOC__DOC = ( 

223 "Strip the leading emoji in ad-hoc command names, if present, in case you " 

224 "are a emoji-hater." 

225) 

226STRIP_LEADING_EMOJI_ADHOC__CATEGORY = _Categories.ADVANCED 

227 

228COMPONENT_NAME: str | None = None 

229COMPONENT_NAME__DOC = ( 

230 "Overrides the default component name with a custom one. This is seen in service discovery and as the nickname " 

231 "of the component in chat windows." 

232) 

233COMPONENT_NAME__CATEGORY = _Categories.ADVANCED 

234 

235WELCOME_MESSAGE: str | None = None 

236WELCOME_MESSAGE__DOC = ( 

237 "Overrides the default welcome message received by newly registered users." 

238) 

239WELCOME_MESSAGE__CATEGORY = _Categories.ADVANCED