Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bring 'Stocks' to the app store (Depot / BeSly or create a new repo) #39

Open
tclaus opened this issue Aug 7, 2023 · 11 comments
Open
Assignees
Labels
enhancement New feature or request

Comments

@tclaus
Copy link
Owner

tclaus commented Aug 7, 2023

No, not via a receipe - the internal API key should stay as a secret. The package should be added to a repository.

Whats about to create an own repo - server?

@tclaus tclaus self-assigned this Aug 7, 2023
@hfsfox
Copy link
Contributor

hfsfox commented Aug 7, 2023

@tclaus tclaus changed the title Bring 'Stocks' to the app store (Haiku depot) Bring 'Stocks' to the app store (Depot / BeSly or create a new repo) Aug 11, 2023
@Briseur
Copy link

Briseur commented Aug 22, 2023

I think that Haikuports will require a recipe. I think that BeSly is already hosting some 'closed' sources software with permissions of their authors though I'm not sure if they need to be able to build them. You may contact Lelldorin or Lorglas for more infos.

@lonemadmax
Copy link

the internal API key should stay as a secret.

It's impossible to both be a secret and be distributed in an app, even if only in binary form. Much less so when it is part of the URL in HTTP requests. The only way would be to make it a setting and that every user (or group of users) got their own. Or set up a proxy that would add the key and relay the requests to the real server, but that would be open to the same abuse as sharing the key.

@cafeina-software
Copy link

No, not via a receipe - the internal API key should stay as a secret. The package should be added to a repository.

Whats about to create an own repo - server?

Why not make it easier? The api key not being compiled into the binaries, and instead upon the first launch (or as long as there isn't a saved key) the user is asked to input his/her own API key in a dialog box. If an API key was provided, then the app goes on, otherwise it should quit. The key will not be provided in the package, and instead saved in UserSetupEnvironment or else it could be saved into the keystore using the Key Storage API (https://www.haiku-os.org/docs/api/app_keystore.html).

@cafeina-software
Copy link

Mockup

I made a mock-up to depict what I was saying in the previous comment.

@tclaus
Copy link
Owner Author

tclaus commented Apr 10, 2024

Oh.
Cool.
I already thought about bringing up my own repo. But for just one App I am not sure if it's worth the effort.
Like also the mockup. Can you provide a PR for this?
(And keep the version with included api key)?

@hfsfox
Copy link
Contributor

hfsfox commented Apr 10, 2024

I have an idea about mockup above

``
#include <Catalog.h>
#include <Button.h>
#include <TextControl.h>
#include <StringView.h>
#include <KeyStore.h>
#include <LayoutBuilder.h>
#include <Screen.h>
...
BStringView* WinLabel = new BStringView("label",
B_TRANSLATE("This application need an API key to acces the data \n"
"from the data provider \nservice ***** in order to network."));
WinLabel->SetAlignment(B_ALIGN_LEFT);

BTextControl* APIInput = new BTextControl(NULL,NULL, NULL);
APIInput->SetAlignment(B_ALIGN_RIGHT,B_ALIGN_CENTER);
APIInput->SetText(NULL);

BLayoutBuilder::Group<>(this, B_VERTICAL, 0)
.SetInsets(B_USE_DEFAULT_SPACING)
.AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING, 0)
.Add(WinLabel)
.End()
.AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING, 0)
.Add(APIInput)
.End()
.AddGroup(B_HORIZONTAL, B_USE_HALF_ITEM_SPACING, 0)
.SetExplicitAlignment(BAlignment(B_ALIGN_CENTER, B_ALIGN_BOTTOM))
.Add(new BButton("SaveButton", "Save API key", new BMessage()))
.Add(new BButton("QuitButton", "Quit", new BMessage(B_QUIT_REQUESTED)))
.End()
.End();
GetLayout()->SetExplicitMinSize(BSize(120, 110));

CenterOnScreen();
...
if(APIInput == NULL)
return;
BPasswordKey key(APIInput->Text(), B_KEY_PURPOSE_KEYRING, "");

``

@cafeina-software
Copy link

I was also working on an implementation of that mock-up, but with an approach that allows the usage of one or several API keys (perhaps for some strange reason, the user has 2 api keys, one personal free-tiered and another from an enterprise subscription provided by his/her company). I will post the code as soon as I get it done to know how it works.

@tclaus tclaus added the enhancement New feature or request label Apr 11, 2024
@cafeina-software
Copy link

cafeina-software commented Apr 12, 2024

I made this mockup app: KeyStoreTest to preview how could my approach work if it is implemented.

(The test app could contain dirty code and some unsafe ways to deal with the secrets, but it was made as a concept test, not as a real world app).

Although KeyStorage APi is not currently secure, it is better just to make use of the API thinking in the future, when it becomes more secure by default, rather than saving the code in an unencrypted form in UserSetupEnvironment or in a flattened BMessage. But by accessing the KeyStore, at least we are adding an additional dialog box to the user (besides the dialog box asking for the key), and if we add additional features to manage multiple keys, then we could ending up being asked several times by the keystore server for permission for different kind of operations, and that could annoy (or else scare) the user if the api key management is not performed with "just enough calls and no more". Using the other two approaches (saving the key as a environment variable or in a flattened BMessage as an app's settings could then become easier.

This is how it is seen:

  1. API Keys manager dialog (within the app). It can add (summons the "Add key" dialog), set as default key, copy the key to the clipboard and remove the selected key.
    screenshot1
  2. "Add key" dialog (the buttons' labels change when it is summoned at start and not from the Key Manager dialog). Although not in the example, it should contain an additional button to check the validity of the key with the service provider API before allowing the user to save the written key.
    screenshot2
  3. "Select key" dialog (it appears when it detected several keys and none is the default)
    screenshot3

At start, it tries to access the keystore and the app's keyring (if it does not exist, it creates one). If the user denies access to the keystore, the app shows an error and the user can only quit. If it allows the access, then it searches for any keys. It shows the "Add key" if the app's keyring in the keystore is empty, otherwise it tries to retrieve the default key (from the settings). If there is no default key (none was configured as such or the user previously deleted the key marked as default) it prompts the user to start with any of the keys. The app starts normally when there is a key and it was set as default.

If it is too complicated, the example from hfsfox for a single key could be just enough.

@cafeina-software
Copy link

cafeina-software commented May 8, 2024

Sorry for the delay.

This is the initial version of the changes proposed:

cafeina-software@34d971f

I decided (at least by now) to drop the multi-key approach and follow the initial idea of using a single key. This is how it works:

  1. If the user starts the app using the flag --use-api-key <APIKEY>, the app starts right away with the provided key, overriding both UBS and the keystore. The current implementation of this test does not save the key provided via this method anywhere, but adding code to allow that is almost trivial.
  2. If the user did not provide a key via command line (and not summoned the app using any command line options that I added to get help or any additional or future usage that does not need to summon the GUI), then the app will start and check first if there is a key saved in the keystore (if there is no key under its own keyring, or if the app's keyring does not even exist yet), and if there is none, it tries to retrieve it from the environment variable STOCKS_APP_API_KEY (whether it was manually set or it was saved in the UBS), and thus keeping the compatibility of using the UBS. If there is a key in the keystore or the environment (via UBS or manually set in the terminal), it opens the main window.
  3. Not found anywhere, then the app summons a special dialog box to create a key and adding it to the keystore. If it was saved correctly, it starts the main window, otherwise it quits the application. The user here can also opt to cancel the creation and quit.

The add key dialog box could also allow the user to choose the saving location, being the keystore or the UBS for more freedom.

I disabled the automatic creation of ./source/api/FinancialmodelingApiKey.h, and instead I make it to build at compile time, allowing to not only get but also set and validate (is empty or not) the key.

Some additional changes not related to the issue:

  • I added the option to call the app with command line arguments. I configured some of them to end the application if it was not needed to open the whole gui: help usage and version. The api key provision option will call the gui. If the app was called without command line arguments, it opens its gui normally. But if it's ran again while it's opened (given that it is a B_SINGLE_LAUNCH), the arguments will be dealt in BApplication::ArgvReceived() as always.
  • I found out that there are some settings that are saved in ~/config/settings/Stocks/config (is a data file). To not corrupt the file and to not have to deal with the json messy-ness, I added the option to save the GUI data (for now the window location) in a flattened BMessage, to be stored in the same folder as config.

Please tell me what do you think about the main changes.

@tclaus
Copy link
Owner Author

tclaus commented May 8, 2024

Looks good so far - thank you for your effort.
I have to tell you that I am currently very busy with private tasks. But I will check this in detail, soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants