Repository: bokeh/bokeh

Issue:
Expose TextInput type as a property of widget. (For Password Typing)
Inspired by issue  [#5417](https://github.com/bokeh/bokeh/issues/5417) (which discusses the addition of placeholder on the TextInput widget) I think it is appropriate to expose also the **type** to the widget. 

One of the advantages of doing that should be to allow password input boxes. 

Currently, the Textinput does not allow to type a password without displaying what the user is typing. The only parameters allowed are "callback", "value", "placeholder" (see [bokeh doc](http://bokeh.pydata.org/en/latest/docs/reference/models/widgets.inputs.html#bokeh.models.widgets.inputs.TextInput)).

A quick inspection to a Bokeh generated page gives the following for an input text object:
```
<input class="bk-widget-form-input" **type="text"** id="f8c02d2b-0630-49b6-b01f-c8071c97370c" value="***" placeholder="">
```
However, if we could have the same with only the type edited to 'password', one could enter passwords with the default dots being displayed instead of the letters typed.
```
<input class="bk-widget-form-input" **type="password"** id="f8c02d2b-0630-49b6-b01f-c8071c97370c" value="***" placeholder="">
```
I believe this should be a simple addiction to bokeh, and I imagine I could do it myself if someone could point me on the right direction. I still did not fully understand how bokeh transform python into elements in HTML, so I got lost tracking the necessary changes. 


Discussion:
Hi @mauhcs  it would be great to have you work on this!

So the basic outline of work would be: Add a new class property here:

https://github.com/bokeh/bokeh/blob/master/bokeh/models/widgets/inputs.py#L36-L52

Add the corresponding property on the BokehJS side here:

https://github.com/bokeh/bokeh/blob/master/bokehjs/src/coffee/models/widgets/text_input.coffee#L37-L40

Then the `render` for text input seems to just pass all the prop attributes to the the template, so the last step would be to just update the template here:

https://github.com/bokeh/bokeh/blob/master/bokehjs/src/coffee/models/widgets/text_input_template.tsx

For an initial cut, the added property could be `String` (python) and `p.String` (BokehJS). For a final version we'd probably want to make corresponding "enum" types on both the python and JS side so that only valid input type values are allowed. 
Tho I guess its worth considering and discussing first, what is the list of valid types, and what do they do? If there are only two, e.g then it might make more sense to just add some boolean property. 
TL;DR: There are only Password and Text type (Maybe). I will add a property/parameter.

Long Version:
According to w3 there are a few types for the input tag in html:
https://www.w3schools.com/html/html_form_input_types.asp

The old ones (supported by all browsers) are 

Text (TextEntry in bokeh)
Password (What I want to add)
Submit (button)
Reset (button)
Radio (radio object in bokeh)
Checkbox (checkbox in bokeh)
Button (Button - Not sure what the difference between Submit, Reset and Button, but I don't think it matters here).

HTML5 still supports a number of different types.

If only the standard tags were to be considered, I would say that only Text and Password Types are similar enough to work as a flag. If HTML 5 were to be considered we could think about types Date, Number, month etc. As they are also text entry based. Also, we should note that HTML5 is not supported by all browsers yet. Not sure what should be Bokeh opnion about it. 

I will try to figure it out how to build bokeh from git and add the property (type_password=False). Wiith these links that @bryevdv sent it should be straightforward. 
There is an issue, though.

I have already a password entry field working that I made with using custom JS. It works how it should, but with a big pop-up on the browser reminding me that the connection is not secure. It clearly is not, I am even printing the 'password' for debugging. But I do not know how to remove this alert. 

This makes me wonder how useful such option would be in practice. 
Should we add this type even though the browser will keep reminding the user that it is not secure?

As a reference I am sending screen shots of the warnings:

Chrome:
![selection_053](https://user-images.githubusercontent.com/17294645/27323457-943bc39c-55dc-11e7-97e6-084709892667.png)

Firefox:
![selection_059](https://user-images.githubusercontent.com/17294645/27323659-434f5114-55dd-11e7-881c-9d93df79a840.png)

The link leads to his page: 
https://support.mozilla.org/en-US/kb/insecure-password-warning-firefox?as=u&utm_source=inproduct

The issue is caused if the field is passed through http instead of https. Not sure how comunication from the client to the server is made in bokeh. 

More importantly, if we were to change only the type of the button we could inspect the page and see the password in the value field. Here is the inspection of the field from the previous picture.

![selection_060](https://user-images.githubusercontent.com/17294645/27323942-600c9c7a-55de-11e7-9d80-a0d44f6cf09d.png)

Thoughts?
This is honestly an area outside of my expertise. A few things I can say:

* It's possible to serve Bokeh apps as HTTPS, but you have to run behind a reverse proxy such as NGinx that is configured to terminate the SSL, Bokeh itself does not currently know how to terminate SSL

* All actual communication between the browsers and the server apart from the first initial connection happens over a websocket.

* I'm truly surprised the password shows up in the inspection like that but OTOH that seems like a browser level problem? If I navigate to a login for my bank and inspect the password field element after I've typed in it, it's an input similar to that but there is no `value` displayed. 

So I'm not sure. If there are things to do better/differently I'd definitely appreciate guidance from anyone with the right expertise. 

I guess bottom line is I would not recommend using Bokeh inputs for transmitting secure inputs at this time. Apps can be embedded in other pages so I'd suggest handling any logins (either *for* the app, or *in* the app for something else) with more traditional and established web practices and embedded the bokeh portion alongside or behind it. 




It works! 

![screen shot 2017-06-25 at 1 43 26 am](https://user-images.githubusercontent.com/17294645/27510251-bb692658-5947-11e7-8d1a-86b296b39352.png)

Almost  >.<

I was able to build Bokeh for dev and do the song and dance with Gulp and a new coffee and ts file for a new widget called PasswordInput. In this way, the widget does not have a ''value'' attribute which hides the password from the inspection (mentioned in my last comment.)

My issue now is that I can make the object be recognized by Bokeh if I run with BOKEH_DEV=true.
But if I run without this variable I get a Bokeh Error: Model 'PasswordInput' does not exist.

I built gulp without the dev option (gulp build instead of gulp dev-built) but this did not solve the problem.

What am I missing?

Here are some images of the password field in action:
1. Having a successul login:
![screen shot 2017-06-25 at 1 41 22 am](https://user-images.githubusercontent.com/17294645/27510235-7953c372-5947-11e7-8469-2c969f0182a4.png)

2. Mistyping a password:
![screen shot 2017-06-25 at 1 43 17 am](https://user-images.githubusercontent.com/17294645/27510249-b9b3554a-5947-11e7-9813-a760996c2257.png)


For reference here is the code for this example:

> from bokeh.models.widgets import PasswordInput, TextInput, PreText, Button
> from bokeh.layouts import column, row
> from bokeh.plotting import show, output_file
> from bokeh.models.callbacks import CustomJS
> 
> ## Set User and Password:
> USER = "Mau"
> PASSWD = "Bok3h"
> 
> ## Create Texts, inputs and button
> text = PreText(text="LOGIN TO KNOW\nTHE SECRET:")
> user = TextInput(placeholder="username")#, title="(UserName: "+USER+")")
> pwd = PasswordInput(placeholder="password")#, title="(Password: "+PASSWD+")")
> btn = Button(label="GO!",width=150)
> 
> secret = PreText() # Secret information displayed if correct password entered
> 
> ## Verify if the password typed is bokeh using a JS script
> verify_pwd = CustomJS(args=dict(user=user, pwd=pwd, secret=secret),
>                       code=""" if (pwd.value == '"""+PASSWD+"""') {
>                                     if (user.value == '"""+USER+"""') {
>                                      secret.text = 'Right Password. The Secret is 42.';
>                                       return;
>                                      }
>                                } 
>                                secret.text = "Wrong Password."; """)
> #user.callback = verify_pwd # Check password pressing enter. -BUG Works also with tab :( 
> pwd.callback = verify_pwd # Check password pressing enter.  -BUG Works also with tab :( 
> btn.callback = verify_pwd # Check password clicking on the Button.
>         
> output_file("password.html", title="Password Field")   
> page = row(column(text,user, pwd,btn),secret)
> show(page)
> 
Just want to add that 

1. Since it is possible to connect through HTTPS using bokeh. And 
2.The issue with the value being displayed on inspection being solved,
I would like to see bokeh with a password field as default (so I can stop using this custom button). 


> But if I run without this variable I get a Bokeh Error: Model 'PasswordInput' does not exist. 

Right, this is expected. Things will never work with CDN resources until an new dev or full release is made, and the new version of BokehJS with this new feature is published to to CDN. Until then the only option are inline resources or local server resources (which is what `BOKEH_DEV` turns on). 

I'm not sure if this should be the default, or an other option. Maybe, just needs to be discussed. Can you open up a PR to focus the technical discussion? Thanks!
Sorry, I wasn't clear, by default I meant be part of bokeh, not only my folder in my computer. 
Making the PR.

Resolving patch:
diff --git a/bokeh/models/widgets/inputs.py b/bokeh/models/widgets/inputs.py
--- a/bokeh/models/widgets/inputs.py
+++ b/bokeh/models/widgets/inputs.py
@@ -51,6 +51,17 @@ class TextInput(InputWidget):
     """)
 
 
+class PasswordInput(TextInput):
+    ''' Single-line password input widget.
+        Note: Despite PasswordInput inheriting from TextInput the password
+        cannot be inspected on the field ``value``. Also, note that this field
+        functionally just hides the input on the browser, transmiting safely a
+        password as a callback, e.g., to the a bokeh server would require
+        some secure connection.
+
+    '''
+
+
 class AutocompleteInput(TextInput):
     ''' Single-line input widget with auto-completion.
 
diff --git a/examples/howto/using_password_input.py b/examples/howto/using_password_input.py
new file mode 100644
--- /dev/null
+++ b/examples/howto/using_password_input.py
@@ -0,0 +1,36 @@
+"""This example using a PasswordInput is purely for demonstration.
+
+Putting a password plaintext in a CustomJS is not advised since it would expose the password.
+"""
+
+from bokeh.models.widgets import PasswordInput, TextInput, PreText, Button
+from bokeh.layouts import column, row
+from bokeh.plotting import show, output_file
+from bokeh.models.callbacks import CustomJS
+
+USER = "Mau"
+PASSWD = "Bok3h"
+
+text = PreText(text="LOGIN TO KNOW\nTHE SECRET:")
+user = TextInput(placeholder="username", title="(UserName: "+USER+")")
+pwd = PasswordInput(placeholder="password", title="(Password: "+PASSWD+")")
+btn = Button(label="GO!",width=150)
+
+secret = PreText() # Secret information displayed if correct password entered
+
+## Verify if the password typed is bokeh using a JS script
+verify_pwd = CustomJS(args=dict(user=user, pwd=pwd, secret=secret),
+                      code=""" if (user.value = '{}') & (pwd.value == '{}') {{
+                                   secret.text = 'Right Password. The Secret is 42.';
+                                   return;
+                               }}
+                               secret.text = 'Wrong Password.';
+                               """.format(USER, PASSWD))
+
+#user.callback = verify_pwd # Check password pressing enter.
+pwd.callback = verify_pwd # Check password pressing enter.
+btn.callback = verify_pwd # Check password clicking on the Button.
+
+output_file("using_password_input.html", title="Password Field")
+page = row(column(text,user, pwd,btn),secret)
+show(page)


Test patch: