RejectedSoftware Forums

Sign up

Web interface inheritance and @before

Hi all

It seems that when attempting to put features common to my web interfaces in a base class, all kinds of horrible things are happening. The below is a slight modification of the examples/web

class BaseService {
	protected {
		SessionVar!(UserSettings, "settings") m_userSettings;
	}
	
	private enum auth = before!ensureAuth("_authUser");
	private string ensureAuth(HTTPServerRequest req, HTTPServerResponse res)
	{
		if (!SampleService.m_userSettings.loggedIn) redirect("/login");
		return SampleService.m_userSettings.userName;
		return "";
	}

	mixin PrivateAccessProxy; // adds support for using private member functions with "before"
}

class SampleService : BaseService {

	@path("/") void getHome()
	{
		auto settings = m_userSettings;
		render!("home.dt", settings);
	}

	void getLogin(string _error = null)
	{
		string error = _error;
		render!("login.dt", error);
	}

	@errorDisplay!getLogin
	void postLogin(ValidUsername user, string password)
	{
		enforce(password == "secret", "Invalid password.");

		UserSettings s;
		s.loggedIn = true;
		s.userName = user;
		s.someSetting = false;
		m_userSettings = s;
		redirect("./");
	}

	void postLogout(HTTPServerResponse res)
	{
		m_userSettings = UserSettings.init;
		res.terminateSession();
		redirect("./");
	}

	@auth
	void getSettings(string _authUser, string _error = null)
	{
		UserSettings settings = m_userSettings;
		auto error = _error;
		render!("settings.dt", error, settings);
	}

	@auth @errorDisplay!getSettings
	void postSettings(bool some_setting, ValidUsername user_name, string _authUser)
	{
		assert(m_userSettings.loggedIn);
		UserSettings s = m_userSettings;
		s.userName = user_name;
		s.someSetting = some_setting;
		m_userSettings = s;
		redirect("./");
	}
}

We have a largish app, with quite a few endpoints. I would really like to write the @auth methods once and reuse them throughout the application. The above code (when not attempting to access the session variable results in an error:

../../source/vibe/internal/meta/funcattr.d(189): Error: this for ensureAuth needs to be type BaseService not type InputAttribute!(ensureAuth)

This seems to come about purely because the definitions are in the parent class. Is there any way to achieve the simplicity of defining these filters once and using them many times? I'm sure I could do it with a mixin, but that would seem rather inefficient.

Cheers!

Re: Web interface inheritance and @before

On Thu, 04 Jun 2015 03:32:21 GMT, David Monagle wrote:

We have a largish app, with quite a few endpoints. I would really like to write the @auth methods once and reuse them throughout the application. The above code (when not attempting to access the session variable results in an error:

../../source/vibe/internal/meta/funcattr.d(189): Error: this for ensureAuth needs to be type BaseService not type InputAttribute!(ensureAuth)

This seems to come about purely because the definitions are in the parent class. Is there any way to achieve the simplicity of defining these filters once and using them many times? I'm sure I could do it with a mixin, but that would seem rather inefficient.

Cheers!

I'm not very familiar with the web interface, but given you code and the error message, I'd say, make it a mixin template instead of an inheritance.
Why would it be inefficient with a mixin ? Unless you're refering to string mixins ?
IMO, mixin template + final class might even give you a little more performance.