public override void HandlePresence(Streams.XmppStream stream, Presence presence, XmppHandlerContext context) { if (presence.Type == PresenceType.available || presence.Type == PresenceType.unavailable) { if (!ReferenceEquals(Member.Stream, stream)) { //Set stream Member.Stream = stream; if (presence.Type == PresenceType.available) { //If stream changed then we should broadcast presences Member.ReEnterRoom(); } } Member.ChangePesence(presence); } else { //Bad request presence.SwitchDirection(); presence.From = Member.RoomFrom; presence.Type = PresenceType.error; presence.Error = new Error(ErrorCondition.BadRequest); context.Sender.SendTo(stream, presence); } }
private void BroadcastPresence(Presence presence) { Debug.Assert(IsClientPresence(presence), "Can't set non client presence to server!!!"); //User send presence directly to server if (IsClientPresence(presence) && !string.IsNullOrEmpty(presence.From.User)) { foreach (var ri in storages.RosterStorage.GetRosterItems(presence.From)) { if (ri.Subscribtion == SubscriptionType.from || ri.Subscribtion == SubscriptionType.both) { sender.Broadcast(sessionManager.GetBareJidSessions(ri.Jid), presence); } } } }
private void SessionUnavailable(object sender, XmppSessionArgs e) { if (e.Session.Jid.Server == jid.Server) { try { offlineStore.SaveLastActivity(e.Session.Jid, new LastActivity(e.Session.Presence != null ? e.Session.Presence.Status : null)); } catch { } if (e.Session.Available) { var presence = new Presence() { Type = PresenceType.unavailable, From = e.Session.Jid, }; handlerManager.ProcessStreamElement(presence, e.Session.Stream); } } }
public override void HandlePresence(XmppStream stream, Presence presence, XmppHandlerContext context) { //Presence to open new room if (MucHelpers.IsJoinRequest(presence)) { //Register Service.CreateRoom(new Jid(presence.To.Bare), null); Service.HandlerManager.ProcessStreamElement(presence, stream);//Forward to room } else { //Return error presence.Type = PresenceType.error; presence.Error = new Error(ErrorType.cancel, ErrorCondition.NotAllowed); presence.SwitchDirection(); context.Sender.SendTo(stream, presence); } }
public override void HandlePresence(XmppStream stream, Presence presence, XmppHandlerContext context) { var session = sessionManager.GetSession(presence.From); if (session == null) { context.Sender.SendTo(stream, XmppStanzaError.ToNotFound(presence)); return; } if (presence.Type == PresenceType.available || presence.Type == PresenceType.invisible || presence.Type == PresenceType.unavailable) { sessionManager.SetSessionPresence(session, presence); } if (presence.HasTo && presence.To.ToString() != stream.Domain) { HandlePresence(presence, session);//Presence to one of contacts } else { BroadcastPresence(presence); } }
public override void HandlePresence(Streams.XmppStream stream, Presence presence, XmppHandlerContext context) { string userName = presence.To.Resource; if (!string.IsNullOrEmpty(userName) && presence.Type == PresenceType.available) { //New member MucRoomMember member = Room.GetRealMember(presence.From); if (member != null) { if (ReferenceEquals(stream, member.Stream)) { if (!Room.TryNickChange(presence)) { ErrorPresence(presence, ErrorCondition.NotAcceptable); context.Sender.SendTo(stream, presence); } } else { //Conflict. user with this jid already in room ErrorPresence(presence, ErrorCondition.Conflict); context.Sender.SendTo(stream, presence); } } else { //Doesn't exists MucRoomMember newMember = new MucRoomMember(Room, presence.To, presence.From, stream, context); Room.TryEnterRoom(newMember, presence); } } else { ErrorPresence(presence, ErrorCondition.BadRequest); context.Sender.SendTo(stream, presence); } }
private bool IsClientPresence(Presence presence) { return presence.Type == PresenceType.available || presence.Type == PresenceType.invisible || presence.Type == PresenceType.probe || presence.Type == PresenceType.unavailable; }
private bool IsAvailablePresence(Presence presence) { if (presence == null) return false; return presence.Type == PresenceType.available || presence.Type == PresenceType.invisible; }
private static void ErrorPresence(Presence presence, ErrorCondition condition) { presence.SwitchDirection(); presence.RemoveAllChildNodes(); presence.AddChild(new Muc()); presence.Type = PresenceType.error; presence.Error = new Error(condition); }
/// <summary> /// </summary> /// <param name="presence"> /// </param> /// <returns> /// </returns> public static Muc GetMuc(Presence presence) { return (Muc) presence.SelectSingleElement(typeof (Muc)); }
public static History GetHistroy(Presence presence) { Muc muc = GetMuc(presence); return muc != null ? muc.History : null; }
private void ErrorPresence(Presence presence, ErrorCondition condition) { ErrorPresence(presence, condition, -1); }
public bool TryNickChange(Presence presence) { MucRoomMember member = members.FindByRealJid(presence.From); if (!presence.To.Resource.Equals(member.Nick)) { if (!RoomSettings.UserNamesOnly) { //Nick change member.Nick = presence.To.Resource; return true; } } return false; }
void MemberPresenceBroadcasted(MucRoomMember member, Presence presence) { Broadcast(member, true, presence); }
private IQ SetRoster(XmppStream stream, IQ iq, XmppHandlerContext context) { var answer = new IQ(IqType.result); answer.Id = iq.Id; answer.To = iq.From; answer.From = iq.To; iq.Id = UniqueId.CreateNewId(); var roster = (Roster)iq.Query; UserRosterItem item = null; try { var rosterItems = roster.GetRoster(); if (rosterItems.Length != 1) throw new JabberException(ErrorCode.BadRequest); var rosterItem = rosterItems[0]; item = UserRosterItem.FromRosterItem(rosterItem); if (rosterItem.Subscription == SubscriptionType.remove) { context.StorageManager.RosterStorage.RemoveRosterItem(iq.From, item.Jid); //Send presences var unsubscribe = new Presence() { Type = PresenceType.unsubscribe, To = item.Jid, From = iq.From }; var unsubscribed = new Presence() { Type = PresenceType.unsubscribed, To = item.Jid, From = iq.From }; var unavailable = new Presence() { Type = PresenceType.unavailable, To = item.Jid, From = iq.From }; bool sended = false; foreach (var session in context.SessionManager.GetBareJidSessions(item.Jid)) { if (session.RosterRequested) { context.Sender.SendTo(session, unsubscribe); context.Sender.SendTo(session, unsubscribed); sended = true; } context.Sender.SendTo(session, unavailable); } if (!sended) { context.StorageManager.OfflineStorage.SaveOfflinePresence(unsubscribe); context.StorageManager.OfflineStorage.SaveOfflinePresence(unsubscribed); } } else { item = context.StorageManager.RosterStorage.SaveRosterItem(iq.From, item); roster.RemoveAllChildNodes(); roster.AddRosterItem(item.ToRosterItem()); } //send all available user's resources context.Sender.Broadcast(context.SessionManager.GetBareJidSessions(iq.From), iq); } catch (System.Exception) { roster.RemoveAllChildNodes(); item = context.StorageManager.RosterStorage.GetRosterItem(iq.From, item.Jid); if (item != null) { roster.AddRosterItem(item.ToRosterItem()); context.Sender.Broadcast(context.SessionManager.GetBareJidSessions(iq.From), iq); } throw; } return answer; }
private void SendRosterPresences(XmppSession session) { //It's correct! //Get other statuses foreach (var ri in rosterStore.GetRosterItems(session.Jid)) { //"none" -- the user does not have a subscription to the contact's presence information, and the contact does not have a subscription to the user's presence information //"to" -- the user has a subscription to the contact's presence information, but the contact does not have a subscription to the user's presence information //"from" -- the contact has a subscription to the user's presence information, but the user does not have a subscription to the contact's presence information //"both" -- both the user and the contact have subscriptions to each other's presence information if (ri.Subscribtion == SubscriptionType.to || ri.Subscribtion == SubscriptionType.both) { foreach (var contactSession in sessionManager.GetBareJidSessions(ri.Jid)) { if (contactSession.Presence != null) { //Send roster contact presence to newly availible session contactSession.Presence.To = null;//To no one sender.SendTo(session, contactSession.Presence); if (contactSession.GetRosterTime.AddMinutes(1) < DateTime.UtcNow) { //Send roster push var roster = new Roster(); roster.AddRosterItem(rosterStore.GetRosterItem(contactSession.Jid, session.Jid).ToRosterItem()); var iq = new IQ { Type = IqType.set, Namespace = Uri.SERVER, Id = UniqueId.CreateNewId(), To = contactSession.Jid, Query = roster }; sender.SendTo(contactSession, iq); } } } } } var server = new Presence() { Type = PresenceType.available, From = new Jid(session.Jid.Server) }; sender.SendTo(session, server); }
private void StoreOffline(Presence presence) { storages.OfflineStorage.SaveOfflinePresence(presence); }
private void UpdateItems(Presence presence, ref UserRosterItem fromRosterItem, ref UserRosterItem toRosterItem) { try { storages.RosterStorage.SaveRosterItem(presence.From, toRosterItem); storages.RosterStorage.SaveRosterItem(presence.To, fromRosterItem); } catch (JabberException) { //Load back toRosterItem = GetUserRosterItem(presence.From, presence.To); fromRosterItem = GetUserRosterItem(presence.To, presence.From); } }
public void TryEnterRoom(MucRoomMember member, Presence presence) { if (MucHelpers.IsJoinRequest(presence)) { if (CanEnterRoom(member, presence)) { if (RoomSettings.IsNew) { member.Affiliation = Affiliation.owner; member.Role = Role.moderator; } //enter members.Add(member); RoomSettings.UpdateMemberInfo(member.RealJid, member.Affiliation, member.Role);//Update settings on enter //subscribe to events SetMemberEvents(member); MemberEnter(member); } } else { ErrorPresence(presence, ErrorCondition.BadRequest); member.Send(presence); } }
private void HandlePresence(Presence presence, XmppSession session) { var toRosterItem = GetUserRosterItem(presence.From, presence.To); var fromRosterItem = GetUserRosterItem(presence.To, presence.From); var stateOut = GetState(fromRosterItem, toRosterItem); var stateIn = GetState(toRosterItem, fromRosterItem); bool bRoute = false; bool bAutoReply = false; bool bMutualCreating = (fromRosterItem.Subscribtion == SubscriptionType.to && toRosterItem.Subscribtion == SubscriptionType.from) || (fromRosterItem.Subscribtion == SubscriptionType.from && toRosterItem.Subscribtion == SubscriptionType.to); bool bMutualExists = (fromRosterItem.Subscribtion == SubscriptionType.both && toRosterItem.Subscribtion == SubscriptionType.both); var newType = presence.Type; if (newType == PresenceType.subscribe) { if (bMutualCreating) { if (toRosterItem.Subscribtion == SubscriptionType.from && toRosterItem.Ask == AskType.NONE) { //Push roster with ASK=subscribe toRosterItem.Ask = AskType.subscribe; UpdateItems(presence, ref fromRosterItem, ref toRosterItem); //Push sender.Broadcast( sessionManager.GetBareJidSessions(presence.From), toRosterItem.GetRosterIq(presence.From) ); //Forward presence.To = new Jid(presence.To.Bare); bool sended = sender.Broadcast(sessionManager.GetBareJidSessions(presence.To), presence); if (!sended) StoreOffline(presence); } } else { //it's inbound for user 'to' ChangeInboundPresence(stateIn, toRosterItem, fromRosterItem, newType, out bRoute, out bAutoReply); if (bAutoReply) { //Reply with 'subscribed' var autoPresence = new Presence(); autoPresence.To = presence.From; autoPresence.From = presence.To; autoPresence.Type = PresenceType.subscribed; sender.Broadcast(sessionManager.GetBareJidSessions(autoPresence.To), autoPresence); } else { if (bRoute) { //Send to 'to' user presence.To = new Jid(presence.To.Bare); bool sended = sender.Broadcast(sessionManager.GetBareJidSessions(presence.To), presence); if (!sended) StoreOffline(presence); //State is changed init roster push UpdateItems(presence, ref fromRosterItem, ref toRosterItem); sender.Broadcast( sessionManager.GetBareJidSessions(presence.From), toRosterItem.GetRosterIq(presence.From) ); //Send result stanza sender.SendTo(session, new IQ(IqType.result)); } } } } else if (newType == PresenceType.subscribed) { if (bMutualCreating) { if (fromRosterItem.Subscribtion == SubscriptionType.from && fromRosterItem.Ask == AskType.subscribe) { //Send roster to contact with both to 'from' //Create both subscription //Send subscribed back toRosterItem.Subscribtion = SubscriptionType.both; toRosterItem.Ask = AskType.NONE; UpdateItems(presence, ref fromRosterItem, ref toRosterItem); sender.Broadcast( sessionManager.GetBareJidSessions(presence.From), toRosterItem.GetRosterIq(presence.From) ); sender.SendTo(session, new IQ(IqType.result)); //fwd presence.To = new Jid(presence.To.Bare); if (!sender.Broadcast(sessionManager.GetBareJidSessions(presence.To), presence)) { StoreOffline(presence); } //Send contact with both fromRosterItem.Subscribtion = SubscriptionType.both; fromRosterItem.Ask = AskType.NONE; UpdateItems(presence, ref fromRosterItem, ref toRosterItem); sender.Broadcast( sessionManager.GetBareJidSessions(presence.To), fromRosterItem.GetRosterIq(presence.To) ); //Send to session presence if (session.Presence != null) { sender.Broadcast(sessionManager.GetBareJidSessions(presence.To), session.Presence); } } } else { //It's outbound for user 'from' ChangeOutboundPresence(stateOut, toRosterItem, fromRosterItem, newType, out bRoute); //Roster oush for 'from' if (bRoute) { //State is changed init roster push UpdateItems(presence, ref fromRosterItem, ref toRosterItem); sender.Broadcast( sessionManager.GetBareJidSessions(presence.From), toRosterItem.GetRosterIq(presence.From) ); //Send result stanza sender.SendTo(session, new IQ(IqType.result)); //dont send } //It's inbound for user 'to' if ((fromRosterItem.Subscribtion == SubscriptionType.none || fromRosterItem.Subscribtion == SubscriptionType.from) && fromRosterItem.Ask == AskType.subscribe) { ChangeInboundPresence(stateIn, fromRosterItem, toRosterItem, newType, out bRoute, out bAutoReply); if (bRoute) { presence.To = new Jid(presence.To.Bare); if (sender.Broadcast(sessionManager.GetBareJidSessions(presence.To), presence)) { StoreOffline(presence); } else { if (session.Presence != null) { sender.Broadcast(sessionManager.GetBareJidSessions(presence.To), session.Presence); } } //State is changed init roster push UpdateItems(presence, ref fromRosterItem, ref toRosterItem); sender.Broadcast( sessionManager.GetBareJidSessions(presence.To), fromRosterItem.GetRosterIq(presence.To)); } } } } else if (newType == PresenceType.unsubscribe) { //Get to roster //it's inbound for user 'to' ChangeInboundPresence(stateIn, toRosterItem, fromRosterItem, newType, out bRoute, out bAutoReply); if (bAutoReply) { //Reply with 'subscribed' Presence autoPresence = new Presence(); autoPresence.To = presence.From; autoPresence.From = presence.To; autoPresence.Type = PresenceType.unsubscribed; sender.Broadcast(sessionManager.GetBareJidSessions(autoPresence.To), autoPresence); //Route presence.To = new Jid(presence.To.Bare); if (!sender.Broadcast(sessionManager.GetBareJidSessions(presence.To), presence)) { StoreOffline(presence); } } } else if (newType == PresenceType.unsubscribed) { //It's outbound for user 'from' ChangeOutboundPresence(stateOut, toRosterItem, fromRosterItem, newType, out bRoute); //Roster oush for 'from' if (bRoute) { //State is changed init roster push UpdateItems(presence, ref fromRosterItem, ref toRosterItem); sender.Broadcast( sessionManager.GetBareJidSessions(presence.From), toRosterItem.GetRosterIq(presence.From)); //Send result stanza sender.SendTo(session, new IQ(IqType.result)); //dont send } ChangeInboundPresence(stateIn, fromRosterItem, toRosterItem, newType, out bRoute, out bAutoReply); if (bRoute) { presence.To = new Jid(presence.To.Bare); if (!sender.Broadcast(sessionManager.GetBareJidSessions(presence.To), presence)) { StoreOffline(presence); } else { sender.Broadcast( sessionManager.GetBareJidSessions(presence.To), new Presence() { Type = PresenceType.unavailable, From = presence.From }); } //State is changed init roster push UpdateItems(presence, ref fromRosterItem, ref toRosterItem); sender.Broadcast( sessionManager.GetBareJidSessions(presence.To), fromRosterItem.GetRosterIq(presence.To)); } } UpdateItems(presence, ref fromRosterItem, ref toRosterItem); }
private bool CanEnterRoom(MucRoomMember member, Presence presence) { if (RoomSettings.PasswordProtected) { string password = MucHelpers.GetPassword(presence); if (!RoomSettings.Password.Equals(password, StringComparison.Ordinal)) { // Return error ErrorPresence(presence, ErrorCondition.NotAuthorized, 401); member.Send(presence); return false; } } if (RoomSettings.UserNamesOnly) { if (!presence.From.User.Equals(presence.To.Resource)) { // username tries to enter with not his username ErrorPresence(presence, ErrorCondition.Conflict, 406); member.Send(presence); return false; } } // Check member if (RoomSettings.IsMember(presence.From)) { // Add new member.Affiliation = RoomSettings.GetMemeberAffilation(presence.From); member.Role = RoomSettings.GetMemeberRole(member.Affiliation); if (member.Affiliation == Affiliation.outcast) { ErrorPresence(presence, ErrorCondition.Conflict, 403); member.Send(presence); return false; } if (member.Role == Role.none) { ErrorPresence(presence, ErrorCondition.Conflict, 403); member.Send(presence); return false; } } else { // Return error ErrorPresence(presence, ErrorCondition.RegistrationRequired, 407); member.Send(presence); return false; } return true; }
public void SendPresenceToSignalR(Presence presence, XmppSessionManager sessionManager) { try { var state = SignalRHelper.GetState(presence.Show, presence.Type); if (state == SignalRHelper.USER_OFFLINE && sessionManager != null) { var jidSessions = sessionManager.GetBareJidSessions(presence.From). Where(s => !s.IsSignalRFake && s.Presence.Type != PresenceType.unavailable); if (jidSessions.Count() > 0) { int priority = jidSessions.First().Priority; var bestSession = jidSessions.First(); foreach (var session in jidSessions) { if (session.Priority > priority) { priority = session.Priority; bestSession = session; } } _reverseJabberServiceClient.SendState(bestSession.Presence.From.User.ToLowerInvariant(), SignalRHelper.GetState(bestSession.Presence.Show, bestSession.Presence.Type), -1, bestSession.Presence.From.Server); return; } } _reverseJabberServiceClient.SendState(presence.From.User.ToLowerInvariant(), state, -1, presence.From.Server); } catch (Exception e) { _log.ErrorFormat("Can not send to {0} to SignalR: {1} {2}", presence, e.Message, e.StackTrace); } }
private void ErrorPresence(Presence presence, ErrorCondition condition, int code) { presence.Type = PresenceType.error; presence.RemoveAllChildNodes(); presence.Error = new Error(condition); if (code != -1) { presence.Error.Code = (ErrorCode)code; } presence.SwitchDirection(); presence.From = Jid; }
public virtual void HandlePresence(XmppStream stream, Presence presence, XmppHandlerContext context) { }
private void DestroyRoom(Destroy destroy) { Presence offline = new Presence(); offline.Type = PresenceType.unavailable; User user = new User(); user.Item = new Item(Affiliation.none, Role.none); offline.AddChild(user); user.AddChild(destroy); destroy.Namespace = null; foreach (MucRoomMember member in members) { offline.From = member.Jid; member.Send(offline); } members.Clear(); mucService.RemoveRoom(this); }
public void AddXmppConnection(string connectionId, string userName, byte state, int tenantId) { try { _log.DebugFormat("Add Xmpp Connection: connectionId={0}, userName={1}, state={2}, tenantId={3}", connectionId, userName, state, tenantId); var jid = GetJid(userName, tenantId, SignalRHelper.SIGNALR_RESOURCE); var listener = (SignalRXmppListener)((XmppGateway)_xmppServer.GetService(typeof(IXmppReceiver))).GetXmppListener("SignalR Listener"); if (listener.GetXmppConnection(connectionId) != null) { RemoveXmppConnection(connectionId, userName, tenantId); } listener.AddXmppConnection(connectionId, _xmppServer); var xmppStream = ((XmppStreamManager)_xmppServer.GetService(typeof(XmppStreamManager))).GetOrCreateNewStream(connectionId); xmppStream.Authenticate(userName); string domain = CoreContext.TenantManager.GetTenant(tenantId).TenantDomain; if (fromTeamlabToOnlyOffice == "true" && domain.EndsWith(fromServerInJid)) { int place = domain.LastIndexOf(fromServerInJid); if (place >= 0) { domain = domain.Remove(place, fromServerInJid.Length).Insert(place, toServerInJid); } } xmppStream.Domain = domain; xmppStream.Connected = true; xmppStream.BindResource(SignalRHelper.SIGNALR_RESOURCE); var handler = _xmppServer.HandlerManager.HandlerStorage.GetStreamStartHandlers(jid)[0]; var stream = new Stream { To = new Jid(jid.Server), Namespace = "http://etherx.jabber.org/streams", Version = "1.6", Language = string.Empty }; handler.StreamStartHandle(xmppStream, stream, null); var session = new XmppSession(jid, xmppStream) { RosterRequested = false, Active = true, IsSignalRFake = true }; ((XmppSessionManager)_xmppServer.GetService(typeof(XmppSessionManager))).AddSession(session); var presence = new Presence(SignalRHelper.GetShowType(state), String.Empty, SignalRHelper.PRIORITY) { From = jid, Type = SignalRHelper.GetPresenceType(state) }; _xmppServer.SessionManager.SetSessionPresence(session, presence); var sender = (IXmppSender)_xmppServer.GetService(typeof(IXmppSender)); var sessions = _xmppServer.SessionManager.GetSessions().Where(s => s.Id != session.Id).ToArray(); sender.Broadcast(sessions, session.Presence); var offlineMessages = _xmppServer.StorageManager.OfflineStorage.GetOfflineMessages(jid); if (offlineMessages.Count > 0) { var users = new List<string>(); for (int i = 0; i < offlineMessages.Count; i++) { var from = offlineMessages[i].From; var name = from.User != null ? from.User.ToLowerInvariant() : string.Empty; if (!users.Contains(name)) { users.Add(name); } } _reverseJabberServiceClient.SendOfflineMessages(userName, users, tenantId); _xmppServer.StorageManager.OfflineStorage.RemoveAllOfflineMessages(jid); } } catch (Exception e) { _log.ErrorFormat("Unexpected error, userName = {0}, {1}, {2}, {3}", userName, e, e.StackTrace, e.InnerException != null ? e.InnerException.Message : string.Empty); } }
/// <summary> /// </summary> /// <param name="presence"> /// </param> /// <returns> /// </returns> public static string GetPassword(Presence presence) { Muc muc = GetMuc(presence); return muc != null ? muc.Password : null; }
private Presence GetNewPresence(byte state, Presence presence = null, Jid jid = null) { if (presence == null) { presence = new Presence(SignalRHelper.GetShowType(state), String.Empty) { From = jid, Priority = SignalRHelper.PRIORITY }; } presence.Show = SignalRHelper.GetShowType(state); presence.Type = SignalRHelper.GetPresenceType(state); return presence; }
/// <summary> /// </summary> /// <param name="presence"> /// </param> /// <returns> /// </returns> public static bool IsJoinRequest(Presence presence) { return presence.Type == PresenceType.available;//Group chat 1.0 and MUC }
public override void HandlePresence(XmppStream stream, Presence presence, XmppHandlerContext context) { HandleMulticastStanza(stream, presence, context); }