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

SPARK-1944 #346

Merged
merged 6 commits into from
Jun 30, 2017
Merged

SPARK-1944 #346

merged 6 commits into from
Jun 30, 2017

Conversation

Alameyo
Copy link
Member

@Alameyo Alameyo commented Jun 18, 2017

Implementation of uploading certificates into Truststore. I also changed some of access modifiers to private.
I am not sure if I am doing good use of text field next to choose file. Maybe it would be better if I put there text "Certificate has been uploaded" or delete that text field at all.

@Alameyo Alameyo requested review from speedy01 and guusdk and removed request for speedy01 June 18, 2017 19:41
Copy link
Member

@guusdk guusdk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It works! :)

I would make a couple of improvements:

  • I don't think you need the text field in front of the button. If someone wants to add a path to the file, they can do that in the file chooser dialog
  • When someone selects a file and presses OK, they should first see the content of the certificate, so that they can verify that they are indeed adding the certificate that they were planning to. There should also be a short explanation of what adding the certificate to the store means as well as a "ok" and "cancel" button. Something like: "Would you like to add this certificate to the keystore? By adding the certificate, Spark will agree to establish secured communications with servers that are identified by this certificate." (or, something better)
  • The UI asks for an alias, but it does not show these aliases anywhere. We should add them as the first column in the table (or: auto-generate aliases, and show them no-where).

certControll.addCertificateToKeystore(file, certAlias);
} catch (KeyStoreException | CertificateException | NoSuchAlgorithmException | IOException ex) {
Log.error("Cannot upload certificate file", ex);
} catch (IllegalArgumentException ex) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An IllegalArgumentException is a runtime exception - which is an exception that is intended to be used when something occurs that is considered to be a programming error (not user in put error). You should not use these for things like User-input validation. For that, use a checked exception instead.

Runtime exceptions are generally not 'catched', but bubble their way up all the way to a very core class, which generically processes them in a big 'catch-all' block.

For some background, read https://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we can prevent having an exception completely. When a user dies not fill out a correct alias, we could simply ask the user again, with some kind of warning (assuming that the user did not press 'cancel').

} catch (KeyStoreException | CertificateException | NoSuchAlgorithmException | IOException ex) {
Log.error("Cannot upload certificate file", ex);
} catch (IllegalArgumentException ex) {
Log.warning("Certificate alias cannot be null");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, always log the exception if you have one. Instead of Log.warning("blah") do Log.warning("blah",ex)

throw new IllegalArgumentException();
}
CertificateFactory cf = CertificateFactory.getInstance("X509");
InputStream inputStream = new FileInputStream(file);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use try-with-resources here, I think.

@Alameyo
Copy link
Member Author

Alameyo commented Jun 20, 2017

I have changed it as you requested. I am not sure what I should do about that IlegalArgumentException. Maybe I should make one, combined dialog asking about alias and showing certificate but I also want it easy distinguishable and not hidden somewhere among certificate options (which there might me more soon). I also moved showCertificate() methods to controller.

@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == okButton){
//controller should be passed to this class only if there is need to modification content of Keystore.
System.out.println(certControll);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

System.out? Booh!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shame...

@@ -46,7 +47,7 @@
private final static Insets DEFAULT_INSETS = new Insets(5, 5, 5, 5);
private final LocalPreferences localPreferences;
private CertificateController certControll;
private JTable certTable = new JTable();
private static JTable certTable = new JTable();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you make this static? It results that all instances of this Panel will share the same instance of the table. I'm not sure if that's desirable.

Copy link
Member Author

@Alameyo Alameyo Jun 21, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can attach only one Truststore and it is somehow direct representation of it so that shouldn't be a problem but real reason why I changed it into static is I wanted to do this:
public void showCertificate() { CertificateDialog certDialog = new CertificateDialog(localPreferences, certificates.get(CertificatesManagerSettingsPanel.getCertTable().getSelectedRow())); }

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now I left it as is but if you still feel that I should change it I will come back to this.

@@ -58,6 +63,8 @@ public CertificateController(LocalPreferences localPreferences) {
case 2:
return String.class;
case 3:
return String.class;
case 4:
return Boolean.class;
default:
return String.class;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have exactly 5 columns now, correct? The default block should never be executed, I think?

If that's correct, then instead of running a value, you should throw an unchecked exception, as it would clearly be a bug in the code if that state was reached!

Copy link
Member

@guusdk guusdk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is already a great improvement, but I think you need some more.

On the first screen, there is no real explanation of what is going on. There is a lot of that on the second screen (where you provide the alias). Perhaps that text should go to the first screen.

Also, the certificate screen looks weird for me:

certificate

  • The content is wider than the dialog itself. Try to make them fit - or, alternatively, use scrollbars, but that's ugly I think.
  • The "Distrust" label is not showing completely. It says "Dist..."
  • The OK and Cancel buttons are weirdly separated - it's quite different from other screens.

certControll.addCertificateToKeystore(file, certAlias);
} catch (KeyStoreException | CertificateException | NoSuchAlgorithmException | IOException ex) {
Log.error("Cannot upload certificate file", ex);
} catch (IllegalArgumentException ex) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we can prevent having an exception completely. When a user dies not fill out a correct alias, we could simply ask the user again, with some kind of warning (assuming that the user did not press 'cancel').

@guusdk
Copy link
Member

guusdk commented Jun 21, 2017

Also (I have not tried this), have you considered a user:

  • Adding the same certificate twice, using the same alias.
  • Adding the same certificate twice, using a different alias.
  • Adding two different certificates, but using the same alias.

What would happen in those cases? What should happen?

@Alameyo
Copy link
Member Author

Alameyo commented Jun 21, 2017

  • Adding new certificate with same alias will overwrite old one. I can add dialog asking if user is sure to overwrite.

  • Adding twice same certificate with different aliases for now cause no other issue than having same certificate with different alias.

  • Thing is that certificate dialog on your screen look different from what I see on mine (I don't see labels on the left on your screen for example), but I will try to fix that.

@guusdk
Copy link
Member

guusdk commented Jun 21, 2017

I don't think that overwriting is acceptable - at least not without a very clear warning. It will lead to very unexpected behavior otherwise. An alternative here might be to generate aliases automatically. If you do that, you can ensure that they're unique. Also, you then don't need to show them to the user at all.

It should not be possible to have two times the same certificate (with a different alias) either. Again, this will lead to a lot of confusion. People that remove one of the duplicates will think that the certificate now no longer is used - while in reality it still is.

Note that Spark is used by a lot of people, and that you're more of an expert on certificates than any of them. Even if things are obvious to you, you should always wonder if the average user (for example, think of your parents) can use the UI without your help.

@Alameyo
Copy link
Member Author

Alameyo commented Jun 21, 2017

I tested it more and the most of the certificates are shown perfectly fine.
obraz

While some are missing labels as on your screen and here:
obraz

I will look what cause it but now I have no idea.

… have alias as existing certificate/certificate is already in keystore/provided alias is empty.
@Alameyo
Copy link
Member Author

Alameyo commented Jun 22, 2017

  • Now certificate dialog show message on top when you add certificate.

  • Depending on user input there are 3 new dialogs which inform in user tries to use the same alias as is already used in Truststore, the same certificate as exist already in store or alias is empty name.

  • I changed all TextFields in certificate dialog to TextAreas which wrap lines at the end.

  • I changed a bit buttons/radio buttons but I don't have problem with not displaying "Distrust" so you have to check if problem still exist.

  • Default now returns RunetimeException.

  • I blocked resizing of dialog as it sometimes mess with placement of components.

  • Also I divided some of the code into functions to make it more clear and removed some unnecessary things.

@guusdk
Copy link
Member

guusdk commented Jun 22, 2017

Now we're getting somewhere! Here's a screenshot of your latest code, as how it showed for me:

image

There's a weird empty space on top - can you fix that? Also, the certificate wasn't scrolled to the top - that's odd too.

I was able to press "ok" without making a selection whether to trust or distrust the certificate.

When trying to test the error message for having no alias, I pressed "ok" without adding an alias. That, to my surprise, showed me "you already have this certificate" (which was true). Then I got back to the screen where I had to fill in an alias. Even when filling out an alias, I still got there. That's silly. When the user is adding a certificate that's already in the store, we can know this on the very first screen. There's no point in having the user to fill in an alias at all - it's going to fail anyway.

@Alameyo
Copy link
Member Author

Alameyo commented Jun 23, 2017

There's a weird empty space on top - can you fix that? Also, the certificate wasn't scrolled to the top - that's odd too.

I will try to fix that spacing at top , but that's problematic for me as I don't see it. This is how it appear for me.
obraz

I was able to press "ok" without making a selection whether to trust or distrust the certificate.

I think I can setup it so it will be by default set as trust when adding certificate (why someone would like add certificate that he distrust?) unless it's invalid. User will be able to change it to distrust during adding or at any point later.

When trying to test the error message for having no alias, I pressed "ok" without adding an alias. That, to my surprise, showed me "you already have this certificate" (which was true). Then I got back to the screen where I had to fill in an alias. Even when filling out an alias, I still got there. That's silly. When the user is adding a certificate that's already in the store, we can know this on the very first screen. There's no point in having the user to fill in an alias at all - it's going to fail anyway.

Ok, I will fix that.

@wrooot
Copy link
Contributor

wrooot commented Jun 23, 2017

You might tey to both use same skin. Also, it might look differently on different OS i suppose. Although that should be cross platform :)

…o set up certificate as trusted or distrusted depending on validity.
@Alameyo
Copy link
Member Author

Alameyo commented Jun 23, 2017

  • I use now subject's CN - common name for certificate alias. If the certificate with the same common name already exist in Truststore then I add number at the end.

  • ScrollPanel now is scrolled to the top.

  • I changed weighty of the infoLabel to 0.0 so that might help with that spacing but I cannot check it myself. I checked it with some different Spark's skins but it still work well for me.

  • Also that window showing certificate now is only window before adding where you have to confirm it. After that there is dialog that popup when certificate has been added and there is also dialog that shows up when certificate already exist within Truststore.

@guusdk
Copy link
Member

guusdk commented Jun 24, 2017

This looks good! The certificate is scrolled all the way to the top, and the weird empty space above the certificate is gone.

image

  • I see that a new certificate is "distrusted" by default. I think you wanted "trust" by default?
  • How do I delete a certificate?
  • The list of all certificates still shows the "alias". That now has no value for the user, so we can remove that column, I think.
  • Can we make the last few columns smaller? That would make the first few wider, and show more useful data, instead of empty space.

image

@guusdk
Copy link
Member

guusdk commented Jun 24, 2017

Oh, and I'd make the 'subject' column the first column, as that's more important than the issuer. Perhaps we shouldn't even show the issuer at all. That will only confuse people. What do you think?

@Alameyo
Copy link
Member Author

Alameyo commented Jun 24, 2017

I see that a new certificate is "distrusted" by default. I think you wanted "trust" by default?

I decided I will make it trusted/distrusted depending on it's validity (which I still need to implement). If user still want to trust it he can change it by clicking trust/adding it to the exception list. End user might doesn't know that his certificate is invalid, this way we will make him sure that it is. I might add dialog that will say "This certificate is invalid, if you still want to use it check "trust"."

How do I delete a certificate?

I am going to implement it with next PR, here is issue for that.

The list of all certificates still shows the "alias". That now has no value for the user, so we can remove that column, I think.

Maybe I should add it at least in certificate dialog?

Can we make the last few columns smaller? That would make the first few wider, and show more useful data, instead of empty space.

Ok, I will try to do it, but I see that whole dialog with table is more stretched for you than for me.

Oh, and I'd make the 'subject' column the first column, as that's more important than the issuer. Perhaps we shouldn't even show the issuer at all. That will only confuse people. What do you think?

I have no strong opinion which fields are the most important to show here, so if you think that I should remove issuer then I will do it.

@guusdk
Copy link
Member

guusdk commented Jun 24, 2017

I see that a new certificate is "distrusted" by default. I think you wanted "trust" by default?

I decided I will make it trusted/distrusted depending on it's validity (which I still need to implement). If user still want to trust it he can change it by clicking trust/adding it to the exception list. End user might doesn't know that his certificate is invalid, this way we will make him sure that it is. I might add dialog that will say "This certificate is invalid, if you still want to use it check "trust"."

I like that idea!

How do I delete a certificate?

I am going to implement it with next PR, here is issue for that.

Ok!

I have no strong opinion which fields are the most important to show here, so if you think that I should remove issuer then I will do it

If you don't have a strong opinion, that lets drop it from the table, and try to show the 'subject' better. Less is more! :)

@guusdk
Copy link
Member

guusdk commented Jun 24, 2017

Oh - and pressing the "Show Certificate" button gives a nullpointer when you don't have a certificate selected. Easy fix: don't allow the button to be pressed when there is no selection in the table.

@wrooot
Copy link
Contributor

wrooot commented Jun 24, 2017

Those buttons doesn't have to be so wide. This looks weird :) "Show certificate", "Choose file".

@Alameyo
Copy link
Member Author

Alameyo commented Jun 24, 2017

@wrooot For me it is wide but not as wide as on Guus's screenshot.

@wrooot
Copy link
Contributor

wrooot commented Jun 24, 2017

I don't have this PR branch merged, so can't test how it looks now, but in the previous PR maybe window was a bit narrower and buttons looked ok. It seems that the window is stretched now and buttons gridbags have been stretched along.

…ed show certificate button until user click on table. Added dialog that shows up when certificate is invalid.
@Alameyo
Copy link
Member Author

Alameyo commented Jun 24, 2017

So that's how it look like now for me:
obraz

@speedy01
Copy link
Contributor

looks nice. are the columns sort-able? that would be nice if they could be. That could save someone a lot of time having to look for exceptions or for a cert to make a change to.

@Alameyo
Copy link
Member Author

Alameyo commented Jun 24, 2017

This columns are sortable but currently after sorting there is displayed wrong certificate if you click on them.

@guusdk
Copy link
Member

guusdk commented Jun 27, 2017

There's something weird with the table. Its content does not use all space on the right side. Could you have a look at that?

image

Also, when a certificate has a "CN" value, I think we can show only that. So, instead of a list like this:

  • CN=Microsec e-Szigno Root CA,OU=e-Szigno CA,O=Microsec Ltd.,L=Budapest,C=HU
  • CN=CNNIC ROOT,O=CNNIC,C=CN
  • CN=Starfield Services Root Certificate Authority - G2,O=Starfield Technologies, Inc.,L=Scottsdale,ST=Arizona,C=US

We'd see a list like this:

  • Microsec e-Szigno Root CA
  • CNNIC ROOT
  • Starfield Services Root Certificate Authority - G2

That's a lot easier on the eyes. Obviously, when you open th certificate, you should still see everything. Also, certificates are not required to have a Common Name. In such case, let's still show everything.

Finally, in the 'valid' column, let's add a a description of why something is not valid (possibly in a different color - red or orange). Possible values:

  • valid (in normal color)
  • expired (in red, if the 'not after' date does not match)
  • not valid yet (in red, if the 'not before' date does not match)
  • ... others?

Oh, and could you center those values? That also looks a lot nicer, I think.

@wrooot
Copy link
Contributor

wrooot commented Jun 27, 2017

Guus are you using some unusual wide resolution?

@guusdk
Copy link
Member

guusdk commented Jun 27, 2017

Nope - but I'm using a non-Windows desktop manager, so that might account for some of the weirdness. This is actually good - Swing does allow the developer to prevent this, when applied properly. It's somewhat of a hassle to get it right, but we're better of seeing these issues now, than in production. :)

@wrooot
Copy link
Contributor

wrooot commented Jun 27, 2017

For me on Windows it opens without this gap on the right. But I'm not using this PR. Last one merged.

@Alameyo
Copy link
Member Author

Alameyo commented Jun 29, 2017

I hope now it stretching good (this took me to long). Validity cells are green if certificate is valid, red if invalid, grey if self signed (in some situations, for end certificates it's not fine, on the other hand root CA are self signed and it is fine so I give to it distinguished color). Validity column values are centered. I left Subject column as is because length of it's value can differ and when centered it is almost unreadable.

I also added some basic validation (by date and self signed) in CertificateModel and I done some changes in i18n values.

@guusdk
Copy link
Member

guusdk commented Jun 30, 2017

This is looking great! I have a couple of small remarks, but I'll raise them as JIRA issues. That will allow us to merge this PR.

Issues:

@guusdk guusdk merged commit 4ba7963 into igniterealtime:master Jun 30, 2017
@Alameyo Alameyo deleted the SPARK-1944 branch July 14, 2017 14:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants