/*! * Добавление канала. * Если канал уже добавлен, он будет обновлён. * * \param channel Указатель на канал. * \return Ключ в таблице \b channels или -1 в случае ошибки. * * \sa update(). */ qint64 DataBase::add(ChatChannel channel) { qint64 key = channel->key(); if (key <= 0) key = channelKey(channel->id(), channel->type()); if (key > 0) { if (channel->key() != key) channel->setKey(key); update(channel); return key; } QSqlQuery query; query.prepare(LS("INSERT INTO channels (channel, normalized, type, gender, name, data, date) " "VALUES (:channel, :normalized, :type, :gender, :name, :data, :date);")); query.bindValue(LS(":channel"), SimpleID::encode(channel->id())); query.bindValue(LS(":normalized"), SimpleID::encode(channel->normalized())); query.bindValue(LS(":type"), channel->type()); query.bindValue(LS(":gender"), channel->gender().raw()); query.bindValue(LS(":name"), channel->name()); query.bindValue(LS(":data"), JSON::generate(channel->data())); query.bindValue(LS(":date"), channel->date()); query.exec(); if (query.numRowsAffected() <= 0) { LOG_N6011 return -1; }
ChannelIndexData::ChannelIndexData(ChatChannel channel) : count(0) , options(NoOptions) , visibility(0) , name(channel->name()) { FeedPtr feed = channel->feed(FEED_NAME_INFO, false); if (!feed) return; visibility = feed->data().value(INFO_FEED_VISIBILITY_KEY, 0).toInt(); if (visibility < 0) return; if (channel->permanent()) options |= Permanent; id = channel->id(); count = channel->channels().size(); title = feed->data().value(INFO_FEED_TITLE_KEY).toMap().value(INFO_FEED_TEXT_KEY).toString(); if (feed->data().value(INFO_FEED_PINNED_KEY, false).toBool()) options |= Pinned; FeedPtr acl = channel->feed(FEED_NAME_ACL, false); if (acl && AclValue::match(acl.data(), 0) == 0) options |= Private; }
/*! * Внутренняя функция публикации изменений. */ void Net::pub(ChatChannel channel, const QString &path, const NetRecord &record) { const ChatId id(channel->id()); NetRecordMap &map = m_data[id]; if (map.value(path).date == record.date) return; map.insert(path, record); broadcast(channel, path, record); }
/*! * Универсальный метод для отдачи тела фида. */ bool FeedHandler::serveFeed(ChatChannel channel, const QString &feedName) { if (!ifMethodAllowed()) return true; if (!channel || !channel->feeds().all().contains(feedName)) { setNoStore(); m_response->writeHead(Tufao::HttpServerResponse::NOT_FOUND); m_response->end(); return true; } FeedPtr feed = channel->feed(feedName); qint64 date = feed->head().date(); RestReplyCache &cache = m_cache[channel->id() + feedName.toUtf8()]; if (cache.date != date) { cache.date = date; cache.etag = etag(date, m_path.toUtf8()); cache.body = JSON::generate(feed->feed()); } setLastModified(date); setETag(cache.etag); setNoCache(); if (!ifModified(cache.etag)) { m_response->writeHead(Tufao::HttpServerResponse::NOT_MODIFIED); m_response->end(); return true; } m_response->writeHead(Tufao::HttpServerResponse::OK); if (m_request->method() != "HEAD") { setContentLength(cache.body.size()); m_response->end(cache.body); } else m_response->end(); return true; }
/*! * Авторизация пользователя, если пользователь не существует, будет создан новый. */ AuthResult ExternalAuthTask::auth(const QVariantMap &data) { QByteArray id = SimpleID::decode(data.value(LS("id")).toByteArray()); if (SimpleID::typeOf(id) != SimpleID::UserId) return AuthResult(Notice::Forbidden, m_data.id); AuthResult result = AnonymousAuth::isCollision(id, m_data.nick, m_data.id, Storage::value(STORAGE_NICK_OVERRIDE).toBool()); if (result.action == AuthResult::Reject) { if (result.status == Notice::NickAlreadyUse) m_cache[m_data.id + m_data.cookie] = data; return result; } ChatChannel channel = Ch::channel(id, SimpleID::UserId); bool created = false; if (!channel) { channel = ChatChannel(new ServerChannel(id, m_data.nick)); created = true; channel->setAccount(); channel->account()->provider = data.value(LS("provider")).toString(); channel->account()->groups += LS("registered"); channel->account()->setDate(DateTime::utc()); channel->setName(m_data.nick); channel->gender().setRaw(m_data.gender); channel->user()->set(User(data.value(LS("user")).toMap())); } if (channel->status().value() == Status::Offline) { channel->setDate(); channel->status().set(m_data.status); } if (!channel->isValid()) return AuthResult(Notice::BadRequest, m_data.id); Core::add(channel); Ch::userChannel(channel, m_data, m_host, created, m_socket); LOG_INFO("N3010", "Core/ExternalAuth", channel->name() << "@" << m_host + "/" + ChatId(channel->id()).toString() << ", " << m_data.host) m_cache.remove(m_data.id + m_data.cookie); return AuthResult(id, m_data.id); }