diff options
Diffstat (limited to 'core/sessionmanager.lua')
-rw-r--r-- | core/sessionmanager.lua | 81 |
1 files changed, 68 insertions, 13 deletions
diff --git a/core/sessionmanager.lua b/core/sessionmanager.lua index f8279bb4..750007fb 100644 --- a/core/sessionmanager.lua +++ b/core/sessionmanager.lua @@ -10,20 +10,20 @@ local tostring, setmetatable = tostring, setmetatable; local pairs, next= pairs, next; -local hosts = prosody.hosts; +local prosody, hosts = prosody, prosody.hosts; local full_sessions = prosody.full_sessions; local bare_sessions = prosody.bare_sessions; -local logger = require "util.logger"; +local logger = require "prosody.util.logger"; local log = logger.init("sessionmanager"); -local rm_load_roster = require "core.rostermanager".load_roster; -local config_get = require "core.configmanager".get; -local resourceprep = require "util.encodings".stringprep.resourceprep; -local nodeprep = require "util.encodings".stringprep.nodeprep; -local generate_identifier = require "util.id".short; -local sessionlib = require "util.session"; - -local initialize_filters = require "util.filters".initialize; +local rm_load_roster = require "prosody.core.rostermanager".load_roster; +local config_get = require "prosody.core.configmanager".get; +local resourceprep = require "prosody.util.encodings".stringprep.resourceprep; +local nodeprep = require "prosody.util.encodings".stringprep.nodeprep; +local generate_identifier = require "prosody.util.id".short; +local sessionlib = require "prosody.util.session"; + +local initialize_filters = require "prosody.util.filters".initialize; local gettime = require "socket".gettime; local _ENV = nil; @@ -92,6 +92,51 @@ local function retire_session(session) return setmetatable(session, resting_session); end +-- Update a session with a new one (transplanting connection, filters, etc.) +-- new_session should be discarded after this call returns +local function update_session(to_session, from_session) + to_session.log("debug", "Updating with parameters from session %s", from_session.id); + from_session.log("debug", "Session absorbed into %s", to_session.id); + + local replaced_conn = to_session.conn; + if replaced_conn then + to_session.conn = nil; + end + + to_session.since = from_session.since; + to_session.ip = from_session.ip; + to_session.conn = from_session.conn; + to_session.rawsend = from_session.rawsend; + to_session.rawsend.session = to_session; + to_session.rawsend.conn = to_session.conn; + to_session.send = from_session.send; + to_session.send.session = to_session; + to_session.close = from_session.close; + to_session.filter = from_session.filter; + to_session.filter.session = to_session; + to_session.filters = from_session.filters; + to_session.send.filter = to_session.filter; + to_session.sasl_handler = from_session.sasl_handler; + to_session.stream = from_session.stream; + to_session.secure = from_session.secure; + to_session.hibernating = nil; + to_session.resumption_counter = (to_session.resumption_counter or 0) + 1; + from_session.log = to_session.log; + from_session.type = to_session.type; + -- Inform xmppstream of the new session (passed to its callbacks) + to_session.stream:set_session(to_session); + + -- Notify modules, allowing them to copy further fields or update state + prosody.events.fire_event("c2s-session-updated", { + session = to_session; + from_session = from_session; + replaced_conn = replaced_conn; + }); + + -- Retire the session we've pulled from, to avoid two sessions on the same connection + retire_session(from_session); +end + local function destroy_session(session, err) if session.destroyed then return; end @@ -130,15 +175,24 @@ local function destroy_session(session, err) retire_session(session); end -local function make_authenticated(session, username, scope) +local function make_authenticated(session, username, role_name) username = nodeprep(username); if not username or #username == 0 then return nil, "Invalid username"; end session.username = username; if session.type == "c2s_unauthed" then session.type = "c2s_unbound"; end - session.auth_scope = scope; - session.log("info", "Authenticated as %s@%s", username, session.host or "(unknown)"); + + local role; + if role_name then + role = hosts[session.host].authz.get_role_by_name(role_name); + else + role = hosts[session.host].authz.get_user_role(username); + end + if role then + sessionlib.set_role(session, role); + end + session.log("info", "Authenticated as %s@%s [%s]", username, session.host or "(unknown)", role and role.name or "no role"); return true; end @@ -265,6 +319,7 @@ end return { new_session = new_session; retire_session = retire_session; + update_session = update_session; destroy_session = destroy_session; make_authenticated = make_authenticated; bind_resource = bind_resource; |