mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-10-22 19:42:13 +00:00
core, ui: per-server roles for self-hosted servers (#7254)
* core, ui: plan per-server roles for self-hosted servers * core: add per-server roles field to UserServer * core: add nullable role columns to protocol_servers * core: persist per-server roles * core: validate server coverage using per-server roles * test: cover per-server roles resolution and coverage * multiplatform: per-server role toggles for self-hosted servers * ios: per-server role toggles for self-hosted servers * core: per-server role overrides with per-role defaults * test: cover three-state per-server role resolution * fix: derive Eq for ServerRolesOverride * multiplatform: three-state role dropdowns on saved servers * ios: three-state role pickers on saved servers * test: per-server roles independent across two servers * test: enable names role in name-resolution tests * style: trim comments in per-server roles code * chore: rename server_roles migration to 20260716 (last) * core: per-server roles override operator roles, inherit when unset * multiplatform: per-server role default inherits from operator * ios: per-server role default inherits from operator * refactor(servers): tidy per-server roles per review - dedup no-operator default into ServerRoles.noOperatorDefault (Kotlin/Swift) - iOS: move roles-section control flow to the call site via a named gate, and parse the server address once instead of up to three times - Kotlin: collapse redundant derivedState; revert defaultOn->default rename for cross-platform parity - drop unused Hashable conformance on Swift ServerRoles - add agentServerCfgs test for names inheritance from an operator - remove no-op enableNamesRole calls from dormant DirectoryTests - fix ChatClient import ordering * chore(migration): date server_roles migration 20260720 * only show roles when server is enabled, move section above QR code --------- Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
This commit is contained in:
1 parent
966c9f7947
commit
2ea5940e81
19 files changed
+834
-54
No files matched your search
@@ -642,41 +642,45 @@ getProtocolServers db p User {userId} =
|
||||
<$> DB.query
|
||||
db
|
||||
[sql|
|
||||
SELECT smp_server_id, host, port, key_hash, basic_auth, preset, tested, enabled
|
||||
SELECT smp_server_id, host, port, key_hash, basic_auth, preset, tested, enabled,
|
||||
role_storage, role_proxy, role_names
|
||||
FROM protocol_servers
|
||||
WHERE user_id = ? AND protocol = ?
|
||||
|]
|
||||
(userId, decodeLatin1 $ strEncode p)
|
||||
where
|
||||
toUserServer :: (DBEntityId, NonEmpty TransportHost, String, C.KeyHash, Maybe Text, BoolInt, Maybe BoolInt, BoolInt) -> UserServer p
|
||||
toUserServer (serverId, host, port, keyHash, auth_, BI preset, tested, BI enabled) =
|
||||
toUserServer :: ((DBEntityId, NonEmpty TransportHost, String, C.KeyHash, Maybe Text, BoolInt, Maybe BoolInt, BoolInt) :. (Maybe BoolInt, Maybe BoolInt, Maybe BoolInt)) -> UserServer p
|
||||
toUserServer ((serverId, host, port, keyHash, auth_, BI preset, tested, BI enabled) :. (rStorage, rProxy, rNames)) =
|
||||
let server = ProtoServerWithAuth (ProtocolServer p host port keyHash) (BasicAuth . encodeUtf8 <$> auth_)
|
||||
in UserServer {serverId, server, preset, tested = unBI <$> tested, enabled, deleted = False}
|
||||
roles = ServerRolesOverride (unBI <$> rStorage) (unBI <$> rProxy) (unBI <$> rNames)
|
||||
in UserServer {serverId, server, preset, tested = unBI <$> tested, enabled, roles, deleted = False}
|
||||
|
||||
insertProtocolServer :: forall p. ProtocolTypeI p => DB.Connection -> SProtocolType p -> User -> UTCTime -> NewUserServer p -> IO (UserServer p)
|
||||
insertProtocolServer db p User {userId} ts srv@UserServer {server, preset, tested, enabled} = do
|
||||
insertProtocolServer db p User {userId} ts srv@UserServer {server, preset, tested, enabled, roles} = do
|
||||
DB.execute
|
||||
db
|
||||
[sql|
|
||||
INSERT INTO protocol_servers
|
||||
(protocol, host, port, key_hash, basic_auth, preset, tested, enabled, user_id, created_at, updated_at)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,?,?)
|
||||
(protocol, host, port, key_hash, basic_auth, preset, tested, enabled,
|
||||
role_storage, role_proxy, role_names, user_id, created_at, updated_at)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)
|
||||
|]
|
||||
(serverColumns p server :. (BI preset, BI <$> tested, BI enabled, userId, ts, ts))
|
||||
(serverColumns p server :. (BI preset, BI <$> tested, BI enabled) :. roleColumns roles :. (userId, ts, ts))
|
||||
sId <- insertedRowId db
|
||||
pure (srv :: NewUserServer p) {serverId = DBEntityId sId}
|
||||
|
||||
updateProtocolServer :: ProtocolTypeI p => DB.Connection -> SProtocolType p -> UTCTime -> UserServer p -> IO ()
|
||||
updateProtocolServer db p ts UserServer {serverId, server, preset, tested, enabled} =
|
||||
updateProtocolServer db p ts UserServer {serverId, server, preset, tested, enabled, roles} =
|
||||
DB.execute
|
||||
db
|
||||
[sql|
|
||||
UPDATE protocol_servers
|
||||
SET protocol = ?, host = ?, port = ?, key_hash = ?, basic_auth = ?,
|
||||
preset = ?, tested = ?, enabled = ?, updated_at = ?
|
||||
preset = ?, tested = ?, enabled = ?,
|
||||
role_storage = ?, role_proxy = ?, role_names = ?, updated_at = ?
|
||||
WHERE smp_server_id = ?
|
||||
|]
|
||||
(serverColumns p server :. (BI preset, BI <$> tested, BI enabled, ts, serverId))
|
||||
(serverColumns p server :. (BI preset, BI <$> tested, BI enabled) :. roleColumns roles :. (ts, serverId))
|
||||
|
||||
serverColumns :: ProtocolTypeI p => SProtocolType p -> ProtoServerWithAuth p -> (Text, NonEmpty TransportHost, String, C.KeyHash, Maybe Text)
|
||||
serverColumns p (ProtoServerWithAuth ProtocolServer {host, port, keyHash} auth_) =
|
||||
@@ -684,6 +688,9 @@ serverColumns p (ProtoServerWithAuth ProtocolServer {host, port, keyHash} auth_)
|
||||
auth = safeDecodeUtf8 . unBasicAuth <$> auth_
|
||||
in (protocol, host, port, keyHash, auth)
|
||||
|
||||
roleColumns :: ServerRolesOverride -> (Maybe BoolInt, Maybe BoolInt, Maybe BoolInt)
|
||||
roleColumns ServerRolesOverride {storage, proxy, names} = (BI <$> storage, BI <$> proxy, BI <$> names)
|
||||
|
||||
getChatRelays :: DB.Connection -> User -> IO [UserChatRelay]
|
||||
getChatRelays db User {userId} =
|
||||
map toChatRelay
|
||||
@@ -772,7 +779,10 @@ updateServerOperator db currentTs ServerOperator {operatorId, enabled, smpRoles,
|
||||
SET enabled = ?, smp_role_storage = ?, smp_role_proxy = ?, smp_role_names = ?, xftp_role_storage = ?, xftp_role_proxy = ?, updated_at = ?
|
||||
WHERE server_operator_id = ?
|
||||
|]
|
||||
(BI enabled, BI (storage smpRoles), BI (proxy smpRoles), BI (names smpRoles), BI (storage xftpRoles), BI (proxy xftpRoles), currentTs, operatorId)
|
||||
(BI enabled, BI smpStorage, BI smpProxy, BI smpNames, BI xftpStorage, BI xftpProxy, currentTs, operatorId)
|
||||
where
|
||||
ServerRoles {storage = smpStorage, proxy = smpProxy, names = smpNames} = smpRoles
|
||||
ServerRoles {storage = xftpStorage, proxy = xftpProxy} = xftpRoles
|
||||
|
||||
getUpdateServerOperators :: DB.Connection -> NonEmpty PresetOperator -> Bool -> IO [(Maybe PresetOperator, Maybe ServerOperator)]
|
||||
getUpdateServerOperators db presetOps newUser = do
|
||||
@@ -810,7 +820,10 @@ getUpdateServerOperators db presetOps newUser = do
|
||||
SET trade_name = ?, legal_name = ?, server_domains = ?, enabled = ?, smp_role_storage = ?, smp_role_proxy = ?, smp_role_names = ?, xftp_role_storage = ?, xftp_role_proxy = ?
|
||||
WHERE server_operator_id = ?
|
||||
|]
|
||||
(tradeName, legalName, T.intercalate "," serverDomains, BI enabled, BI (storage smpRoles), BI (proxy smpRoles), BI (names smpRoles), BI (storage xftpRoles), BI (proxy xftpRoles), operatorId)
|
||||
(tradeName, legalName, T.intercalate "," serverDomains, BI enabled, BI smpStorage, BI smpProxy, BI smpNames, BI xftpStorage, BI xftpProxy, operatorId)
|
||||
where
|
||||
ServerRoles {storage = smpStorage, proxy = smpProxy, names = smpNames} = smpRoles
|
||||
ServerRoles {storage = xftpStorage, proxy = xftpProxy} = xftpRoles
|
||||
insertOperator :: NewServerOperator -> IO ServerOperator
|
||||
insertOperator op@ServerOperator {operatorTag, tradeName, legalName, serverDomains, enabled, smpRoles, xftpRoles} = do
|
||||
DB.execute
|
||||
@@ -820,9 +833,12 @@ getUpdateServerOperators db presetOps newUser = do
|
||||
(server_operator_tag, trade_name, legal_name, server_domains, enabled, smp_role_storage, smp_role_proxy, smp_role_names, xftp_role_storage, xftp_role_proxy)
|
||||
VALUES (?,?,?,?,?,?,?,?,?,?)
|
||||
|]
|
||||
(operatorTag, tradeName, legalName, T.intercalate "," serverDomains, BI enabled, BI (storage smpRoles), BI (proxy smpRoles), BI (names smpRoles), BI (storage xftpRoles), BI (proxy xftpRoles))
|
||||
(operatorTag, tradeName, legalName, T.intercalate "," serverDomains, BI enabled, BI smpStorage, BI smpProxy, BI smpNames, BI xftpStorage, BI xftpProxy)
|
||||
opId <- insertedRowId db
|
||||
pure op {operatorId = DBEntityId opId}
|
||||
where
|
||||
ServerRoles {storage = smpStorage, proxy = smpProxy, names = smpNames} = smpRoles
|
||||
ServerRoles {storage = xftpStorage, proxy = xftpProxy} = xftpRoles
|
||||
autoAcceptConditions op UsageConditions {conditionsCommit} now =
|
||||
acceptConditions_ db op conditionsCommit now True
|
||||
$> op {conditionsAcceptance = CAAccepted (Just now) True}
|
||||
|
||||
Reference in new issue
Block a user