I have changed my Sphinx server to a Windows service and all works great. For use in my XData server (now a service application too), I have created an extended user entity (TSpinxUserEx) with an additional field.
As it is now a service, I am trying to build a simple VCL application that uses Aurelius to access the Sphinx database so that I can manage users from the backoffice. This too works OK (the newuser can enter user name and does receive the email confirmation token as designed/expected.
The final step is where the problem is: I cannot seem to find out how I can set an initial password for the user (only using Aurelius, i.e. not having an IUserManager available). Is this possible and if so/not how can I best achieve this?
Ideally you should use Sphinx classes, more specifically in this case, IUserManager, to handle the uses in the database.
You can use it from a VCL Aurelius application, you don't need to use from a Sphinx server. So my suggestion is that in your VCL application you simply use IUserManager to handle the user in a safer and higher-level way.
Clear, but how do get the IUserManager? If my memory serves me right, you normally get it from the SphinxContext (which obviously isn't there in a VCL Aurelius application)?
You can see that the only parameter that you might be wondering how to pass is the ICoreOptions interface. That you can obtain from an existing TSphinxConfig component (e.g., SphinxConfig1, this way:
uses {...}, Sphinx.ConfigCoreOptions;
var
CoreOptions: ICoreOptions;
begin
CoreOptions := TConfigCoreOptions.Create(SphinxConfig1);
We have added a service to the Sphinx Server application to allow us to manage users. Locked down with lots of attributes and secondary validation of course
What kind of service? Do you mean an XData service (interface) or a Windows service?
Are you willing to share some details on how you implemented it? I just need to manage users from the back office (direct access to server) so an Aurelius/VCL application - in principle - is sufficient for me. Nevertheless, I am curious to other "flavors" that could be applied...
function TsmxSphinxServerBase.GetSphinxContext: ISphinxContext;
begin
if not Assigned(FSphinxContext) then
begin
FSphinxContext := TSphinxContext.Create(TConfigCoreOptions.Create(FSphinxConfig),
TXDataOperationContext.Current.GetConnectionPool);
end;
Result := FSphinxContext;
end;
function TsmxSphinxServerBase.GetSphinxManager: TObjectManager;
begin
if not Assigned(FSphinxManager) then
begin
if FNeedsContext then
FSphinxManager := (SphinxContext as TSphinxContext).Manager
else
FSphinxManager := TObjectManager.Create(DBConnection, TMappingExplorer.Get(cSphinxModelName));
end;
Result := FSphinxManager;
end;
FSphinxConfig is a class var.
We also have another service for our multitenant systems that allows tenant admins to manage their own users.
In reaction to Wagner's example on creating the ICoreOptions, I found that some additional units are required in the uses clause. As it took some time to find them (), I am posting this - working - example. Perhaps it's of use for other users as a reference:
uses Sphinx.CoreOptions, Sphinx.ConfigCoreOptions, Sphinx.UserManager, Sphinx.UserManager.Impl,
Entities.SphinxUserEx; // Unit implementing an extended user class
procedure TForm1.MyButtonClick(Sender: TObject);
var
CoreOptions: ICoreOptions;
UsrMgr: IUserManager;
Usr: TSphinxUserEx;
begin
CoreOptions := TConfigCoreOptions.Create(SphinxConfig);
UsrMgr := TUserManager.Create(CoreOptions, FObjMgr, false);
Usr := UsrMgr.FindByEmail('name@domain.com') as TSphinxUserEx; // Cast to custom class!
if assigned(Usr) then
// Access_Level is property added in extended user class
showMessage('User: ' + Usr.UserName.Value + sLineBreak + 'Email: ' + Usr.Email.Value + sLineBreak + 'Access level: ' + Usr.Access_Level)
else
showMessage('User not found!');