mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-04 04:32:43 +01:00
1329b7b51e
Summary: Ref T1536. Ref T1930. Code is not reachable. This provides password authentication and registration on the new provider/adapter framework. I sort of cheated a little bit and don't really route any password logic through the adapter (instead, this provider uses an empty adapter and just sets the type/domain on it). I think the right way to do this //conceptually// is to treat username/passwords as an external black box which the adapter communicates with. However, this creates a lot of practical implementation and UX problems: - There would basically be two steps -- in the first one, you interact with the "password black box", which behaves like an OAuth provider. This produces some ExternalAccount associated with the username/password pair, then we go into normal registration. - In normal registration, we'd proceed normally. This means: - The registration flow would be split into two parts, one where you select a username/password (interacting with the black box) and one where you actually register (interacting with the generic flow). This is unusual and probably confusing for users. - We would need to do a lot of re-hashing of passwords, since passwords currently depend on the username and user PHID, which won't exist yet during registration or the "black box" phase. This is a big mess I don't want to deal with. - We hit a weird condition where two users complete step 1 with the same username but don't complete step 2 yet. The box knows about two different copies of the username, with two different passwords. When we arrive at step 2 the second time we have a lot of bad choices about how to reoslve it, most of which create security problems. The most stragihtforward and "pure" way to resolve the issues is to put password-auth usernames in a separate space, but this would be incredibly confusuing to users (your login name might not be the same as your username, which is bizarre). - If we change this, we need to update all the other password-related code, which I don't want to bother with (at least for now). Instead, let registration know about a "default" registration controller (which is always password, if enabled), and let it require a password. This gives us a much simpler (albeit slightly less pure) implementation: - All the fields are on one form. - Password adapter is just a shell. - Password provider does the heavy lifting. We might make this more pure at some point, but I'm generally pretty satisfied with this. This doesn't implement the brute-force CAPTCHA protection, that will be coming soon. Test Plan: Registered with password only and logged in with a password. Hit various error conditions. Reviewers: btrahan Reviewed By: btrahan CC: aran, chad Maniphest Tasks: T1536, T1930 Differential Revision: https://secure.phabricator.com/D6164
443 lines
7.9 KiB
CSS
443 lines
7.9 KiB
CSS
/**
|
|
* @provides aphront-form-view-css
|
|
*/
|
|
|
|
/**
|
|
* These styles are overrides for .aphront-form-view
|
|
*/
|
|
.aphront-form-view-shaded {
|
|
border: 1px solid #d4dae0;
|
|
background: #f4f5f8;
|
|
}
|
|
|
|
.aphront-form-view-padded {
|
|
padding: 1em;
|
|
}
|
|
|
|
.aphront-form-view label.aphront-form-label {
|
|
padding-top: 5px;
|
|
width: 19%;
|
|
float: left;
|
|
text-align: right;
|
|
font-weight: bold;
|
|
font-size: 13px;
|
|
color: #757c88;
|
|
text-shadow: 0 1px rgba(255,255,255,1);
|
|
}
|
|
|
|
.device-phone .aphront-form-view label.aphront-form-label,
|
|
.aphront-form-full-width.aphront-form-view label.aphront-form-label {
|
|
display: block;
|
|
float: none;
|
|
text-align: left;
|
|
width: 100%;
|
|
margin-bottom: 3px;
|
|
}
|
|
|
|
.aphront-form-input {
|
|
margin-left: 20%;
|
|
margin-right: 20%;
|
|
width: 60%;
|
|
}
|
|
|
|
.device-phone .aphront-form-input,
|
|
.aphront-form-full-width .aphront-form-input {
|
|
margin-left: 0%;
|
|
margin-right: 0%;
|
|
width: 100%;
|
|
}
|
|
|
|
.aphront-form-error {
|
|
width: 18%;
|
|
float: right;
|
|
color: #aa0000;
|
|
font-weight: bold;
|
|
padding-top: 4px;
|
|
}
|
|
|
|
.aphront-dialog-body .aphront-form-full-width {
|
|
margin-top: -10px;
|
|
}
|
|
|
|
.device-phone .aphront-form-error,
|
|
.aphront-form-full-width .aphront-form-error {
|
|
float: none;
|
|
width: 100%;
|
|
}
|
|
|
|
.device-phone .aphront-form-drag-and-drop-upload {
|
|
display: none;
|
|
}
|
|
|
|
.aphront-form-required {
|
|
font-weight: normal;
|
|
color: #888888;
|
|
font-size: 11px;
|
|
}
|
|
|
|
.aphront-form-input input {
|
|
width: 100%;
|
|
}
|
|
|
|
.aphront-form-input textarea {
|
|
display: block;
|
|
width: 100%;
|
|
box-sizing: border-box;
|
|
height: 12em;
|
|
}
|
|
|
|
.aphront-form-control {
|
|
padding: 4px;
|
|
}
|
|
|
|
.aphront-form-full-width .aphront-form-control {
|
|
padding: 4px 0;
|
|
}
|
|
|
|
.aphront-form-control-submit button,
|
|
.aphront-form-control-submit a.button {
|
|
float: right;
|
|
margin: 0.5em 0 0 2%;
|
|
}
|
|
|
|
.phui-form-control-multi-submit input {
|
|
float: right;
|
|
margin: 0.5em 0 0em 2%;
|
|
width: auto;
|
|
}
|
|
|
|
.aphront-form-control-textarea textarea.aphront-textarea-very-short {
|
|
height: 44px;
|
|
}
|
|
|
|
.aphront-form-control-textarea textarea.aphront-textarea-very-tall {
|
|
height: 24em;
|
|
}
|
|
|
|
.aphront-form-control-select .aphront-form-input {
|
|
padding-top: 2px;
|
|
}
|
|
|
|
.aphront-form-view .aphront-form-caption {
|
|
font-size: 12px;
|
|
color: #888;
|
|
padding: 2px;
|
|
text-align: right;
|
|
margin-right: 20%;
|
|
margin-left: 20%;
|
|
}
|
|
|
|
.device-phone .aphront-form-view .aphront-form-caption,
|
|
.aphront-form-full-width .aphront-form-view .aphront-form-caption {
|
|
margin-right: 0%;
|
|
}
|
|
|
|
/* override for when inside an aphront-panel-view */
|
|
.aphront-panel-view .aphront-form-view h1 {
|
|
padding: 0em 0em .8em 0em;
|
|
}
|
|
|
|
.aphront-form-instructions {
|
|
width: 60%;
|
|
margin-left: 20%;
|
|
padding: 10px 4px;
|
|
}
|
|
|
|
|
|
|
|
.device .aphront-form-instructions,
|
|
.aphront-form-full-width .aphront-form-instructions {
|
|
width: 100%;
|
|
margin: 0;
|
|
}
|
|
|
|
.aphront-form-important {
|
|
margin: .5em 0;
|
|
background: #ffffdd;
|
|
padding: .5em 1em;
|
|
}
|
|
.aphront-form-important code {
|
|
display: block;
|
|
padding: .25em;
|
|
margin: .5em 2em;
|
|
}
|
|
|
|
.aphront-form-control-static .aphront-form-input,
|
|
.aphront-form-control-markup .aphront-form-input {
|
|
padding-top: 6px;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.aphront-form-control-togglebuttons .aphront-form-input {
|
|
padding: 2px 0 0 0;
|
|
}
|
|
|
|
table.aphront-form-control-radio-layout,
|
|
table.aphront-form-control-checkbox-layout {
|
|
margin-top: 3px;
|
|
font-size: 13px;
|
|
}
|
|
|
|
table.aphront-form-control-radio-layout th,
|
|
table.aphront-form-control-checkbox-layout th {
|
|
padding-top: 2px;
|
|
padding-left: 0.35em;
|
|
padding-bottom: 4px;
|
|
}
|
|
|
|
.aphront-form-control-radio-layout td input,
|
|
.aphront-form-control-checkbox-layout td input {
|
|
margin-top: 4px;
|
|
width: auto;
|
|
}
|
|
|
|
.aphront-form-radio-caption {
|
|
font-size: 11px;
|
|
color: #444444;
|
|
max-width: 400px;
|
|
}
|
|
|
|
.aphront-form-control-image span {
|
|
margin: 0px 4px 0px 2px;
|
|
}
|
|
|
|
.aphront-form-control-image .default-image {
|
|
display: inline;
|
|
width: 12px;
|
|
}
|
|
|
|
.aphront-form-input hr {
|
|
border: none;
|
|
background: #bbbbbb;
|
|
height: 1px;
|
|
position: relative;
|
|
}
|
|
|
|
.aphront-form-inset {
|
|
margin: 0 0 10px;
|
|
padding: 10px;
|
|
background: #fff;
|
|
border: 1px solid #d4dae0;
|
|
}
|
|
|
|
.aphront-form-inset h1 {
|
|
color: #777;
|
|
font-weight: normal;
|
|
padding-bottom: 10px;
|
|
}
|
|
|
|
.aphront-form-drag-and-drop-file-list {
|
|
width: 400px;
|
|
}
|
|
|
|
.drag-and-drop-instructions {
|
|
color: #333333;
|
|
font-size: 11px;
|
|
padding: 6px 8px;
|
|
}
|
|
|
|
.drag-and-drop-file-target {
|
|
border: 1px dashed #bfbfbf;
|
|
padding-top: 10px;
|
|
padding-bottom: 10px;
|
|
}
|
|
|
|
.aphront-textarea-drag-and-drop {
|
|
background: #99ff99;
|
|
border-color: #669966;
|
|
}
|
|
|
|
.aphront-form-crop .crop-box {
|
|
cursor: move;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.aphront-form-crop .crop-box .crop-image {
|
|
position: relative;
|
|
top: 0px;
|
|
left: 0px;
|
|
}
|
|
|
|
|
|
.calendar-button {
|
|
display: inline;
|
|
background: url(/rsrc/image/icon/fatcow/calendar_edit.png)
|
|
no-repeat center center;
|
|
padding: 8px 12px;
|
|
margin: 2px 8px 2px 2px;
|
|
position: relative;
|
|
border: 1px solid transparent;
|
|
}
|
|
|
|
.aphront-form-date-container {
|
|
position: relative;
|
|
display: inline;
|
|
}
|
|
|
|
.aphront-form-date-container select {
|
|
margin: 2px;
|
|
display: inline;
|
|
}
|
|
.aphront-form-date-container input.aphront-form-date-enabled-input {
|
|
width: auto;
|
|
display: inline;
|
|
margin-right: 8px;
|
|
font-size: 16px;
|
|
}
|
|
|
|
.aphront-form-date-container input.aphront-form-date-time-input {
|
|
width: 7em;
|
|
display: inline;
|
|
}
|
|
|
|
.fancy-datepicker {
|
|
position: absolute;
|
|
width: 240px;
|
|
}
|
|
|
|
.fancy-datepicker-core {
|
|
padding: 1px;
|
|
font-size: 11px;
|
|
font-family: Verdana;
|
|
text-align: center;
|
|
}
|
|
|
|
.fancy-datepicker-core .month-table,
|
|
.fancy-datepicker-core .day-table {
|
|
margin: 0 auto;
|
|
border-collapse: separate;
|
|
border-spacing: 1px;
|
|
width: 100%;
|
|
}
|
|
|
|
.fancy-datepicker-core .month-table {
|
|
margin-bottom: 6px;
|
|
}
|
|
|
|
.fancy-datepicker-core .month-table td.lrbutton {
|
|
width: 20%;
|
|
}
|
|
|
|
.fancy-datepicker-core .month-table td {
|
|
padding: 4px;
|
|
font-weight: bold;
|
|
color: #444444;
|
|
}
|
|
|
|
.fancy-datepicker-core .month-table td.lrbutton {
|
|
background: #e6e6e6;
|
|
border: 1px solid;
|
|
border-color: #a6a6a6 #969696 #868686 #a6a6a6;
|
|
}
|
|
|
|
.fancy-datepicker-core .day-table td {
|
|
overflow: hidden;
|
|
background: #f6f6f6;
|
|
vertical-align: center;
|
|
text-align: center;
|
|
border: 1px solid #d6d6d6;
|
|
padding: 4px 0;
|
|
}
|
|
|
|
.fancy-datepicker-core .day-table td.day-placeholder {
|
|
border-color: transparent;
|
|
background: transparent;
|
|
}
|
|
|
|
.fancy-datepicker-core .day-table td.weekend {
|
|
color: #666666;
|
|
border-color: #e6e6e6;
|
|
}
|
|
|
|
.fancy-datepicker-core .day-table td.day-name {
|
|
background: transparent;
|
|
border: 1px transparent;
|
|
vertical-align: bottom;
|
|
color: #888888;
|
|
}
|
|
|
|
.fancy-datepicker-core .day-table td.today {
|
|
background: #eeee99;
|
|
border-color: #aaaa66;
|
|
}
|
|
|
|
.fancy-datepicker-core .day-table td.datepicker-selected {
|
|
background: #0099ff;
|
|
border-color: #0066cc;
|
|
}
|
|
|
|
.fancy-datepicker-core td {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.fancy-datepicker-core td.novalue {
|
|
cursor: inherit;
|
|
}
|
|
|
|
.picker-open .calendar-button,
|
|
.fancy-datepicker-core {
|
|
background-color: white;
|
|
border: 1px solid #777777;
|
|
|
|
box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.25);
|
|
}
|
|
|
|
.picker-open .calendar-button {
|
|
border-left: 1px solid white;
|
|
}
|
|
|
|
.login-to-comment {
|
|
padding: 12px;
|
|
float: right;
|
|
}
|
|
|
|
.aphront-form-control-counted-togglebuttons {
|
|
padding-top: 7px;
|
|
}
|
|
|
|
.aphront-form-control-counted-togglebuttons .toggle {
|
|
position: relative;
|
|
}
|
|
|
|
.aphront-form-control-counted-togglebuttons .toggle-fixed {
|
|
cursor: pointer;
|
|
}
|
|
|
|
.aphront-form-control-counted-togglebuttons .toggle .counter {
|
|
font-size: smaller;
|
|
display: none;
|
|
position: absolute;
|
|
top: -9px;
|
|
right: -8px;
|
|
padding: 0px 3px;
|
|
border-radius: 3px;
|
|
}
|
|
|
|
.aphront-form-control-counted-togglebuttons:hover .toggle .counter {
|
|
display: block;
|
|
}
|
|
|
|
.aphront-form-control-counted-togglebuttons .toggle .counter {
|
|
background: gray;
|
|
color: #ddd;
|
|
}
|
|
|
|
.aphront-form-control-counted-togglebuttons .toggle-selected .counter {
|
|
color: white;
|
|
}
|
|
|
|
.aphront-form-control-counted-togglebuttons .toggle.disabled:hover {
|
|
background-color: #a7a7a7;
|
|
}
|
|
|
|
.phui-form-divider hr {
|
|
height: 1px;
|
|
border: 0;
|
|
background: #c0c0c0;
|
|
width: 85%;
|
|
margin: 15px auto;
|
|
}
|
|
|
|
.recaptcha_only_if_privacy {
|
|
display: none;
|
|
}
|