Changeset - 8df5cd7d1b47
[Not reviewed]
0 8 0
Jan Kaluza - 9 years ago 2016-01-07 18:32:17
jkaluza@redhat.com
Spectrum2 manager server: Allow registration of users
8 files changed with 89 insertions and 43 deletions:
0 comments (0 inline, 0 general)
include/transport/Frontend.h
Show inline comments
 
@@ -90,12 +90,13 @@ class Frontend {
 

	
 
		virtual void clearRoomList() = 0;
 
		virtual void addRoomToRoomList(const std::string &handle, const std::string &name) = 0;
 

	
 
		virtual std::string setOAuth2Code(const std::string &code, const std::string &state) { return "OAuth2 code is not needed for this frontend."; }
 
		virtual std::string getOAuth2URL(const std::vector<std::string> &args) { return ""; }
 
		virtual std::string getRegistrationFields() { return "Jabber ID\n3rd-party network username\n3rd-party network password"; }
 

	
 
		boost::signal<void (User *, const std::string &name, unsigned int id)> onVCardRequired;
 
		boost::signal<void (User *, boost::shared_ptr<Swift::VCard> vcard)> onVCardUpdated;
 
		boost::signal<void (Buddy *, const Swift::RosterItemPayload &item)> onBuddyUpdated;
 
		boost::signal<void (Buddy *)> onBuddyRemoved;
 
		boost::signal<void (Buddy *, const Swift::RosterItemPayload &item)> onBuddyAdded;
include/transport/UserRegistration.h
Show inline comments
 
@@ -47,13 +47,13 @@ class UserRegistration {
 
		/// Destroys UserRegistration.
 
		virtual ~UserRegistration();
 

	
 
		/// Registers new user. This function stores user into database and subscribe user to transport.
 
		/// \param userInfo UserInfo struct with informations about registered user
 
		/// \return false if user is already registered
 
		bool registerUser(const UserInfo &userInfo);
 
		bool registerUser(const UserInfo &userInfo, bool allowPasswordChange = false);
 

	
 
		/// Unregisters user. This function removes all data about user from databa, unsubscribe all buddies
 
		/// managed by this transport and disconnects user if he's connected.
 
		/// \param barejid bare JID of user to unregister
 
		/// \return false if there is no such user registered
 
		bool unregisterUser(const std::string &barejid);
libtransport/AdminInterface.cpp
Show inline comments
 
@@ -322,12 +322,16 @@ void AdminInterface::handleQuery(Swift::Message::ref message) {
 
			message->setBody(url);
 
		}
 
		else {
 
			message->setBody("Bad argument count. See 'help'.");
 
		}
 
	}
 
	else if (message->getBody() == "registration_fields") {
 
		std::string fields = m_component->getFrontend()->getRegistrationFields();
 
		message->setBody(fields);
 
	}
 
	else if (message->getBody().find("help") == 0) {
 
		std::string help;
 
		help += "General:\n";
 
		help += "    status - shows instance status\n";
 
		help += "    reload - Reloads config file\n";
 
		help += "    uptime - returns ptime in seconds\n";
 
@@ -360,13 +364,13 @@ void AdminInterface::handleQuery(Swift::Message::ref message) {
 
		help += "    average_memory_per_user_per_backend - (memory_used_without_any_user - res_memory) per backend\n";
 
		
 
		
 
		message->setBody(help);
 
	}
 
	else {
 
		message->setBody("Unknown command. Try \"help\"");
 
		message->setBody("Unknown command \"" + message->getBody() + "\". Try \"help\"");
 
	}
 
}
 

	
 
void AdminInterface::handleMessageReceived(Swift::Message::ref message) {
 
	if (!message->getTo().getNode().empty())
 
		return;
libtransport/UserRegistration.cpp
Show inline comments
 
@@ -44,19 +44,21 @@ UserRegistration::UserRegistration(Component *component, UserManager *userManage
 
	m_userManager = userManager;
 
}
 

	
 
UserRegistration::~UserRegistration(){
 
}
 

	
 
bool UserRegistration::registerUser(const UserInfo &row) {
 
bool UserRegistration::registerUser(const UserInfo &row, bool allowPasswordChange) {
 
	UserInfo dummy;
 
	bool registered = m_storageBackend->getUser(row.jid, dummy);
 

	
 
	m_storageBackend->setUser(row);
 
	doUserRegistration(row);
 
	onUserRegistered(row);
 
	if (registered && !allowPasswordChange) {
 
		m_storageBackend->setUser(row);
 
		doUserRegistration(row);
 
		onUserRegistered(row);
 
	}
 

	
 
	return !registered;
 
}
 

	
 
bool UserRegistration::unregisterUser(const std::string &barejid) {
 
	UserInfo userInfo;
spectrum/src/frontends/slack/SlackFrontend.cpp
Show inline comments
 
@@ -119,11 +119,15 @@ std::string SlackFrontend::setOAuth2Code(const std::string &code, const std::str
 
}
 

	
 
std::string SlackFrontend::getOAuth2URL(const std::vector<std::string> &args) {
 
	return static_cast<SlackUserManager *>(m_userManager)->getOAuth2URL(args);
 
}
 

	
 
std::string SlackFrontend::getRegistrationFields() {
 
	return "Slack team name\n3rd-party network username\n3rd-party network password";
 
}
 

	
 
void SlackFrontend::disconnectFromServer() {
 

	
 
}
 

	
 
}
spectrum/src/frontends/slack/SlackFrontend.h
Show inline comments
 
@@ -64,12 +64,13 @@ namespace Transport {
 
			virtual UserManager *createUserManager(Component *component, UserRegistry *userRegistry, StorageBackend *storageBackend = NULL);
 
			virtual boost::shared_ptr<Swift::DiscoInfo> sendCapabilitiesRequest(Swift::JID to);
 
			virtual void clearRoomList();
 
			virtual void addRoomToRoomList(const std::string &handle, const std::string &name);
 
			virtual std::string setOAuth2Code(const std::string &code, const std::string &state);
 
			virtual std::string getOAuth2URL(const std::vector<std::string> &args);
 
			virtual std::string getRegistrationFields();
 
		
 
			void handleMessage(boost::shared_ptr<Swift::Message> message);
 

	
 
			ThreadPool *getThreadPool() {
 
				return m_tp;
 
			}
spectrum_manager/src/html/login/index.html
Show inline comments
 
@@ -31,12 +31,13 @@
 
    </div>
 

	
 
    <!-- MAIN CONTENT -->
 
    <div id="main_content_wrap" class="outer">
 
      <section id="main_content" class="inner">
 

	
 
      <p>If you don't have Spectrum 2 master account yet, you can <a href="/users">Register it here</a>. You will be able to manager your Spectrum 2 IM transports after that.</p>
 

	
 
<form action="/authorize" class="basic-grey" method="POST">
 
    <h1>Login form
 
        <span>Use your username and password to login to Spectrum 2 Manager.</span>
 
    </h1>
 
    <label>
spectrum_manager/src/server.cpp
Show inline comments
 
@@ -186,12 +186,14 @@ bool Server::is_authorized(const struct mg_connection *conn, struct http_message
 
	// Always authorize accesses to login page and to authorize URI
 
	if (!mg_vcmp(&hm->uri, "/login") ||
 
		!mg_vcmp(&hm->uri, "/login/") ||
 
		!mg_vcmp(&hm->uri, "/form.css") ||
 
		!mg_vcmp(&hm->uri, "/style.css") ||
 
		!mg_vcmp(&hm->uri, "/logo.png") ||
 
		!mg_vcmp(&hm->uri, "/users") ||
 
		!mg_vcmp(&hm->uri, "/users/add") ||
 
		!mg_vcmp(&hm->uri, "/authorize")) {
 
		return true;
 
	}
 

	
 
	if ((session = get_session(hm)) != NULL) {
 
		generate_session_id(valid_id, session->random, session->user);
 
@@ -312,30 +314,32 @@ void Server::serve_logout(struct mg_connection *conn, struct http_message *hm) {
 

	
 
	sessions.erase(session->session_id);
 
	delete session;
 
}
 

	
 
void Server::serve_users_add(struct mg_connection *conn, struct http_message *hm) {
 
	Server:session *session = get_session(hm);
 
	if (!session->admin) {
 
		redirect_to(conn, hm, "/");
 
		return;
 
	}
 

	
 
	std::string user = get_http_var(hm, "user");
 
	std::string password = get_http_var(hm, "password");
 

	
 
	if (!user.empty() && !password.empty()) {
 
		UserInfo info;
 
		info.jid = user;
 
		info.password = password;
 
		if (m_storage) {
 
			m_storage->setUser(info);
 
			UserInfo dummy;
 
			bool registered = m_storage->getUser(user, dummy);
 
			if (!registered) {
 
				UserInfo info;
 
				info.jid = user;
 
				info.password = password;
 
				m_storage->setUser(info);
 
			}
 
			else {
 
				redirect_to(conn, hm, "/users?error=This+username+is+already+registered");
 
				return;
 
			}
 
		}
 
	}
 
	redirect_to(conn, hm, "/users");
 
	redirect_to(conn, hm, "/users?ok=1");
 
}
 

	
 
void Server::serve_users_remove(struct mg_connection *conn, struct http_message *hm) {
 
	Server:session *session = get_session(hm);
 
	if (!session->admin) {
 
		redirect_to(conn, hm, "/");
 
@@ -351,34 +355,50 @@ void Server::serve_users_remove(struct mg_connection *conn, struct http_message
 
	m_storage->getUser(user, info);
 
	m_storage->removeUser(info.id);
 
	redirect_to(conn, hm, "/users");
 
}
 

	
 
void Server::serve_users(struct mg_connection *conn, struct http_message *hm) {
 
	std::string html = "<h2>Spectrum 2 manager users</h2>";
 

	
 
	std::string html;
 
	Server:session *session = get_session(hm);
 
	if (!session->admin) {
 
		html += "<p>Only Spectrum 2 manager administrator can access this page.</p>";
 
		print_html(conn, hm, html);
 
		return;
 
	if (!session) {
 
		std::string ok = get_http_var(hm, "ok");
 
		if (!ok.empty()) {
 
			redirect_to(conn, hm, "/");
 
			return;
 
		}
 
		html += "<h2>Register new Spectrum 2 master account</h2>";
 
	}
 
	else {
 
		html += "<h2>Spectrum 2 manager users</h2>";
 

	
 
	html += "<p>Here, you can add new users who will have access to this web interface. "
 
			"These users will be able to register new accounts on all Spectrum 2 instances "
 
			"running on these server. They won't be able to change any Spectrum 2 instance "
 
			"configuration influencing other users.</p>";
 
		if (!session->admin) {
 
			html += "<p>Only Spectrum 2 manager administrator can access this page.</p>";
 
			print_html(conn, hm, html);
 
			return;
 
		}
 

	
 
		html += "<p>Here, you can add new users who will have access to this web interface. "
 
				"These users will be able to register new accounts on all Spectrum 2 instances "
 
				"running on these server. They won't be able to change any Spectrum 2 instance "
 
				"configuration influencing other users.</p>";
 
	}
 

	
 
	std::string error = get_http_var(hm, "error");
 
	if (!error.empty()) {
 
		html += "<p><b>Error: " + error +  "</b></p>";
 
	}
 

	
 
	if (!m_storage) {
 
		print_html(conn, hm, html);
 
		return;
 
	}
 

	
 
	html += "<form action=\"/users/add\" class=\"basic-grey\" method=\"POST\"> \
 
	<h1>Add user \
 
		<span>Add new user to Spectrum 2 manager web interface.</span> \
 
	<h1>Register user \
 
		<span>Register new user to Spectrum 2 manager web interface.</span> \
 
	</h1> \
 
	<label> \
 
		<span>Username:</span> \
 
		<input type=\"text\" id=\"user\" name=\"user\"placeholder=\"Username\"></textarea> \
 
	</label> \
 
	<label><span>Password:</span> \
 
@@ -389,20 +409,22 @@ void Server::serve_users(struct mg_connection *conn, struct http_message *hm) {
 
		<input type=\"submit\" class=\"button\" value=\"Add user\" />\
 
	</label> \
 
</form><br/>";
 
	std::vector<std::string> users;
 
	m_storage->getUsers(users);
 

	
 
	html += "<table><tr><th>User<th>Action</th></tr>";
 
	BOOST_FOREACH(std::string &user, users) {
 
		html += "<tr>";
 
		html += "<td><a href=\"/users?jid=" + user + "\">" + user + "</a></td>";
 
		html += "<td><a href=\"/users/remove?user=" + user + "\">Remove</a></td>";
 
		html += "</tr>";
 
	if (session) {
 
		html += "<table><tr><th>User<th>Action</th></tr>";
 
		BOOST_FOREACH(std::string &user, users) {
 
			html += "<tr>";
 
			html += "<td><a href=\"/users?jid=" + user + "\">" + user + "</a></td>";
 
			html += "<td><a href=\"/users/remove?user=" + user + "\">Remove</a></td>";
 
			html += "</tr>";
 
		}
 
		html += "</table>";
 
	}
 
	html += "</table>";
 

	
 
	print_html(conn, hm, html);
 
}
 

	
 
void Server::serve_instances_start(struct mg_connection *conn, struct http_message *hm) {
 
	Server:session *session = get_session(hm);
 
@@ -484,27 +506,38 @@ void Server::serve_instances_register(struct mg_connection *conn, struct http_me
 
	std::string password = get_http_var(hm, "password");
 
	Server:session *session = get_session(hm);
 
	UserInfo info;
 
	m_storage->getUser(session->user, info);
 

	
 
	if (jid.empty() || uin.empty() || password.empty()) {
 
		std::string response = send_command(instance, "registration_fields");
 
		std::vector<std::string> fields;
 
		boost::split(fields, response, boost::is_any_of("\n"));
 

	
 
		if (fields.size() < 3) {
 
			fields.clear();
 
			fields.push_back("Jabber ID");
 
			fields.push_back("3rd-party network username");
 
			fields.push_back("3rd-party network password");
 
		}
 

	
 
		std::string html = "<h2>Register Spectrum 2 instance</h2>";
 
		html += "<form action=\"/instances/register\" class=\"basic-grey\" method=\"POST\"> \
 
			<h1>Register Spectrum 2 instance \
 
				<span>Write the Slack team name, 3rd-party network username and password.</span> \
 
				<span>Write the " + fields[0] + ", " + fields[1] + " and " + fields[2] + ".</span> \
 
			</h1> \
 
			<label> \
 
				<span>Slack team name:</span> \
 
				<input type=\"text\" id=\"jid\" name=\"jid\" placeholder=\"Slack team name\"></textarea> \
 
				<span>" + fields[0] + ":</span> \
 
				<input type=\"text\" id=\"jid\" name=\"jid\" placeholder=\""+ fields[0] +"\"></textarea> \
 
			</label> \
 
			<label> \
 
				<span>3rd-party network username:</span> \
 
				<input type=\"text\" id=\"uin\" name=\"uin\" placeholder=\"3rd-party network username\"></textarea> \
 
				<span>" + fields[1] + ":</span> \
 
				<input type=\"text\" id=\"uin\" name=\"uin\" placeholder=\"" + fields[1] + "\"></textarea> \
 
			</label> \
 
			<label><span>Password:</span> \
 
				<input type=\"password\" id=\"password\" name=\"password\" placeholder=\"3rd-party network password\"></textarea> \
 
			<label><span>" + fields[2] + ":</span> \
 
				<input type=\"password\" id=\"password\" name=\"password\" placeholder=\"" + fields[2] + "\"></textarea> \
 
			</label> \
 
			<label> \
 
				<span>&nbsp;</span> \
 
				<input type=\"submit\" class=\"button\" value=\"Register\" />\
 
			</label> \
 
			<input type=\"hidden\" name=\"instance\" value=\"" + instance + "\"></input> \
0 comments (0 inline, 0 general)