]> Pileus Git - ~andy/freeotp/blob - src/org/fedorahosted/freeotp/ManualDialogFragment.java
Migrate Manual token entry to use a DialogFragment
[~andy/freeotp] / src / org / fedorahosted / freeotp / ManualDialogFragment.java
1 /*
2  * FreeOTP
3  *
4  * Authors: Nathaniel McCallum <npmccallum@redhat.com>
5  *
6  * Copyright (C) 2013  Nathaniel McCallum, Red Hat
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20
21 package org.fedorahosted.freeotp;
22
23 import java.util.Locale;
24
25 import android.app.AlertDialog;
26 import android.content.DialogInterface;
27 import android.net.Uri;
28 import android.text.TextWatcher;
29 import android.view.View;
30 import android.widget.AdapterView;
31 import android.widget.AdapterView.OnItemSelectedListener;
32 import android.widget.EditText;
33 import android.widget.RadioButton;
34 import android.widget.Spinner;
35 import android.widget.TextView;
36
37 public class ManualDialogFragment extends BaseAlertDialogFragment implements OnItemSelectedListener {
38         public static final String FRAGMENT_TAG = "fragment_camera";
39         private static final String DEFAULT_INTERVAL = "30";
40         private static final String DEFAULT_COUNTER = "0";
41
42         private final int SHA1_OFFSET = 1;
43         private final int TOTP_OFFSET = 0;
44         private EditText mIssuer;
45         private EditText mLabel;
46         private EditText mSecret;
47         private EditText mInterval;
48         private Spinner mAlgorithm;
49         private Spinner mType;
50
51         public ManualDialogFragment() {
52                 super(R.string.add_token, R.layout.manual, android.R.string.cancel, 0, R.string.add);
53         }
54
55         @Override
56         protected void onViewInflated(View view) {
57                 mIssuer = (EditText) view.findViewById(R.id.issuer);
58                 mLabel = (EditText) view.findViewById(R.id.label);
59                 mSecret = (EditText) view.findViewById(R.id.secret);
60                 mInterval = (EditText) view.findViewById(R.id.interval);
61                 mAlgorithm = (Spinner) view.findViewById(R.id.algorithm);
62                 mType = (Spinner) view.findViewById(R.id.type);
63
64                 // Select the default algorithm
65                 mAlgorithm.setSelection(SHA1_OFFSET);
66
67                 // Setup the Interval / Counter toggle
68                 mType.setOnItemSelectedListener(this);
69         }
70
71         @Override
72         public void onStart() {
73                 super.onStart();
74
75                 AlertDialog ad = (AlertDialog) getDialog();
76
77                 // Disable the Add button
78                 ad.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
79
80                 // Set constraints on when the Add button is enabled
81                 TextWatcher tw = new ManualTextWatcher(ad);
82                 mIssuer.addTextChangedListener(tw);
83                 mLabel.addTextChangedListener(tw);
84                 mSecret.addTextChangedListener(new ManualSecretTextWatcher(ad));
85                 mInterval.addTextChangedListener(tw);
86         }
87
88         @Override
89         public void onClick(DialogInterface dialog, int which) {
90                 if (which != AlertDialog.BUTTON_POSITIVE)
91                         return;
92
93                 // Get the fields
94                 String issuer = Uri.encode(mIssuer.getText().toString());
95                 String label = Uri.encode(mLabel.getText().toString());
96                 String secret = Uri.encode(mSecret.getText().toString());
97                 String type = mType.getSelectedItemId() == TOTP_OFFSET ? "totp" : "hotp";
98                 String algorithm = mAlgorithm.getSelectedItem().toString().toLowerCase(Locale.US);
99                 int interval = Integer.parseInt(mInterval.getText().toString());
100                 int digits = ((RadioButton) getDialog().findViewById(R.id.digits6)).isChecked() ? 6 : 8;
101
102                 // Create the URI
103                 String uri = String.format(Locale.US, "otpauth://%s/%s:%s?secret=%s&algorithm=%s&digits=%d",
104                                    type, issuer, label, secret, algorithm, digits);
105                 if (type.equals("totp"))
106                         uri = uri.concat(String.format("&period=%d", interval));
107                 else
108                         uri = uri.concat(String.format("&counter=%d", interval));
109
110                 // Add the token
111                 if (uri != null)
112                         ((MainActivity) getActivity()).tokenURIReceived(uri);
113         }
114
115         @Override
116         public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
117                 TextView tv = (TextView) getDialog().findViewById(R.id.interval_label);
118                 if (position == 0) {
119                         tv.setText(R.string.interval);
120                         mInterval.setText(DEFAULT_INTERVAL);
121                 } else {
122                         tv.setText(R.string.counter);
123                         mInterval.setText(DEFAULT_COUNTER);
124                 }
125         }
126
127         @Override
128         public void onNothingSelected(AdapterView<?> parent) {
129         }
130 }