1
0
Fork 0
mirror of https://github.com/geometer/FBReaderJ.git synced 2025-10-04 02:09:35 +02:00

basic auth

This commit is contained in:
Nikolay Pultsin 2011-04-17 07:04:14 +01:00
parent 078a7fe21f
commit 295f2de3f0
19 changed files with 279 additions and 26 deletions

View file

@ -1,4 +1,5 @@
===== 1.0.7 (Apr ??, 2011) =====
* Basic authentication (for OPDS catalogs) has been implemented
* Fixed unexpected scrolling after brightness adjustment
* Fixed custom OPDS catalogs search
* Fixed freezes in library view

View file

@ -622,6 +622,7 @@
</node>
<node name="AuthenticationDialog">
<node name="title" value="Ověřování"/>
<node name="unencryptedWarning" value="Your password will be sent unencrypted" toBeTranslated="true"/>
<node name="login" value="Uživatelské jméno"/>
<node name="password" value="Heslo"/>
<node name="skipIP" value="Nevázat na IP adresu"/>

View file

@ -609,6 +609,7 @@
</node>
<node name="AuthenticationDialog">
<node name="title" value="Authentifizierung" />
<node name="unencryptedWarning" value="Your password will be sent unencrypted" toBeTranslated="true"/>
<node name="login" value="Benutzername" />
<node name="password" value="Passwort" />
<node name="skipIP" value="Nicht an IP-Adresse binden" />

View file

@ -621,6 +621,7 @@
</node>
<node name="AuthenticationDialog">
<node name="title" value="Authentication" />
<node name="unencryptedWarning" value="Your password will be sent unencrypted" />
<node name="login" value="Username" />
<node name="password" value="Password" />
<node name="skipIP" value="Don't bound to ip-address" />

View file

@ -611,6 +611,7 @@
</node>
<node name="AuthenticationDialog">
<node name="title" value="Authentification"/>
<node name="unencryptedWarning" value="Your password will be sent unencrypted" toBeTranslated="true"/>
<node name="login" value="Identifiant"/>
<node name="password" value="Mot de passe"/>
<node name="skipIP" value="Ne pas associer à l'adresse IP"/>

View file

@ -608,6 +608,7 @@
</node>
<node name="AuthenticationDialog">
<node name="title" value="Autenticación" />
<node name="unencryptedWarning" value="Your password will be sent unencrypted" toBeTranslated="true"/>
<node name="login" value="Nome de usuario" />
<node name="password" value="Contrasinal" />
<node name="skipIP" value="Non ligar o enderezo IP" />

View file

@ -608,6 +608,7 @@
</node>
<node name="AuthenticationDialog">
<node name="title" value="Bejelentkezés" />
<node name="unencryptedWarning" value="Your password will be sent unencrypted" toBeTranslated="true"/>
<node name="login" value="Felhasználónév" />
<node name="password" value="Jelszó" />
<node name="skipIP" value="IP-címhez kötés nem lehetséges" />

View file

@ -608,6 +608,7 @@
</node>
<node name="AuthenticationDialog">
<node name="title" value="Autenticazione" />
<node name="unencryptedWarning" value="Your password will be sent unencrypted" toBeTranslated="true"/>
<node name="login" value="Username" />
<node name="password" value="Password" />
<node name="skipIP" value="Non fornire indirizzo IP" />

View file

@ -608,6 +608,7 @@
</node>
<node name="AuthenticationDialog">
<node name="title" value="Authenticatie" />
<node name="unencryptedWarning" value="Your password will be sent unencrypted" toBeTranslated="true"/>
<node name="login" value="Gebruikersnaam" />
<node name="password" value="Wachtwoord" />
<node name="skipIP" value="Don't bound to ip-address" toBeTranslated="true" />

View file

@ -607,6 +607,7 @@
</node>
<node name="AuthenticationDialog">
<node name="title" value="Авторизация" />
<node name="unencryptedWarning" value="Пароль пересылается незашифрованным"/>
<node name="login" value="Имя пользователя" />
<node name="password" value="Пароль" />
<node name="skipIP" value="Не привязываться к ip-адресу" />

View file

@ -608,6 +608,7 @@
</node>
<node name="AuthenticationDialog">
<node name="title" value="การตรวจสอบสิทธิ์"/>
<node name="unencryptedWarning" value="Your password will be sent unencrypted" toBeTranslated="true"/>
<node name="login" value="ชื่อผู้ใช้"/>
<node name="password" value="รหัสผ่าน"/>
<node name="skipIP" value="ไม่ผูกกับไอพีนี้"/>

View file

@ -608,6 +608,7 @@
</node>
<node name="AuthenticationDialog">
<node name="title" value="Авторизація" />
<node name="unencryptedWarning" value="Your password will be sent unencrypted" toBeTranslated="true"/>
<node name="login" value="Ім’я користувача" />
<node name="password" value="Пароль" />
<node name="skipIP" value="Не прив’язуватись до ip-адреси" />

View file

@ -608,6 +608,7 @@
</node>
<node name="AuthenticationDialog">
<node name="title" value="Xác thực" />
<node name="unencryptedWarning" value="Your password will be sent unencrypted" toBeTranslated="true"/>
<node name="login" value="Người dùng" />
<node name="password" value="Mật khẩu" />
<node name="skipIP" value="Đừng giới hạn địa chỉ ip" />

View file

@ -608,6 +608,7 @@
</node>
<node name="AuthenticationDialog">
<node name="title" value="鉴定" />
<node name="unencryptedWarning" value="Your password will be sent unencrypted" toBeTranslated="true"/>
<node name="login" value="登录" />
<node name="password" value="密码" />
<node name="skipIP" value="不绑定到IP地址" />

View file

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:orientation="vertical"
>
<TextView
android:id="@+id/authentication_subtitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
/>
<TextView
android:id="@+id/authentication_unencrypted_warning"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textColor="#ff0000"
android:layout_marginBottom="10dp"
/>
<TextView
android:id="@+id/authentication_username_label"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true"
/>
<EditText
android:id="@+id/authentication_username"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true"
/>
<TextView
android:id="@+id/authentication_password_label"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:layout_marginTop="5dp"
/>
<EditText
android:id="@+id/authentication_password"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="true"
android:password="true"
/>
<TextView
android:id="@+id/network_authentication_error"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone"
android:textColor="#ff0000"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="20dp"
android:paddingBottom="10dp"
android:orientation="horizontal"
>
<Button
android:id="@+id/authentication_ok_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
/>
<Button
android:id="@+id/authentication_cancel_button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
/>
</LinearLayout>
</LinearLayout>
</ScrollView>

View file

@ -0,0 +1,113 @@
/*
* Copyright (C) 2010-2011 Geometer Plus <contact@geometerplus.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
package org.geometerplus.android.fbreader.network;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Button;
import org.geometerplus.zlibrary.core.options.ZLStringOption;
import org.geometerplus.zlibrary.core.resources.ZLResource;
import org.geometerplus.zlibrary.ui.android.R;
public class AuthenticationActivity extends Activity {
final static String AREA_KEY = "area";
final static String HOST_KEY = "host";
final static String SCHEME_KEY = "scheme";
final static String USERNAME_KEY = "username";
final static String PASSWORD_KEY = "password";
private ZLResource myResource;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
Thread.setDefaultUncaughtExceptionHandler(new org.geometerplus.zlibrary.ui.android.library.UncaughtExceptionHandler(this));
setContentView(R.layout.authentication);
final Intent intent = getIntent();
final String host = intent.getStringExtra(HOST_KEY);
final String area = intent.getStringExtra(AREA_KEY);
setTitle(area);
myResource = ZLResource.resource("dialog").getResource("AuthenticationDialog");
final ZLStringOption option = new ZLStringOption("username", host + ":" + area, "");
findTextView(R.id.authentication_subtitle).setText(host);
final TextView warningView = findTextView(R.id.authentication_unencrypted_warning);
if ("https".equalsIgnoreCase(intent.getStringExtra(SCHEME_KEY))) {
warningView.setVisibility(View.GONE);
} else {
warningView.setText(myResource.getResource("unencryptedWarning").getValue());
}
findTextView(R.id.authentication_username_label).setText(
myResource.getResource("login").getValue()
);
findTextView(R.id.authentication_password_label).setText(
myResource.getResource("password").getValue()
);
final TextView username = findTextView(R.id.authentication_username);
username.setText(option.getValue());
final ZLResource buttonResource = ZLResource.resource("dialog").getResource("button");
final Button okButton = findButton(R.id.authentication_ok_button);
okButton.setText(buttonResource.getResource("ok").getValue());
okButton.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
final Intent data = new Intent();
final String usernameString = username.getText().toString();
option.setValue(usernameString);
data.putExtra(
USERNAME_KEY,
usernameString
);
data.putExtra(
PASSWORD_KEY,
findTextView(R.id.authentication_password).getText().toString()
);
setResult(0, data);
finish();
}
});
final Button cancelButton = findButton(R.id.authentication_cancel_button);
cancelButton.setText(buttonResource.getResource("cancel").getValue());
cancelButton.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
finish();
}
});
}
private TextView findTextView(int resourceId) {
return (TextView)findViewById(resourceId);
}
private Button findButton(int resourceId) {
return (Button)findViewById(resourceId);
}
}

View file

@ -19,6 +19,8 @@
package org.geometerplus.android.fbreader.network;
import java.net.*;
import android.app.*;
import android.os.Bundle;
import android.view.*;
@ -44,6 +46,8 @@ import org.geometerplus.fbreader.network.tree.SearchItemTree;
import org.geometerplus.android.fbreader.tree.ZLAndroidTree;
abstract class NetworkBaseActivity extends ListActivity implements NetworkView.EventListener {
protected static final int AUTHENTICATION_CODE = 1;
protected final ZLResource myResource = ZLResource.resource("networkView");
public BookDownloaderServiceConnection Connection;
@ -61,15 +65,6 @@ abstract class NetworkBaseActivity extends ListActivity implements NetworkView.E
);
}
@Override
public void onDestroy() {
if (Connection != null) {
unbindService(Connection);
Connection = null;
}
super.onDestroy();
}
@Override
protected void onStart() {
super.onStart();
@ -81,6 +76,47 @@ abstract class NetworkBaseActivity extends ListActivity implements NetworkView.E
NetworkView.Instance().addEventListener(this);
}
private final class MyAuthenticator extends Authenticator {
private volatile String myUsername;
private volatile String myPassword;
@Override
protected PasswordAuthentication getPasswordAuthentication() {
final Intent intent = new Intent();
intent.setClass(NetworkBaseActivity.this, AuthenticationActivity.class);
intent.putExtra(AuthenticationActivity.AREA_KEY, getRequestingPrompt());
intent.putExtra(AuthenticationActivity.HOST_KEY, getRequestingSite().getHostName());
intent.putExtra(AuthenticationActivity.SCHEME_KEY, getRequestingProtocol());
startActivityForResult(intent, AUTHENTICATION_CODE);
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
}
}
System.err.println("auth thread: " + Thread.currentThread());
PasswordAuthentication result = null;
if (myUsername != null && myPassword != null) {
result = new PasswordAuthentication(myUsername, myPassword.toCharArray());
}
myUsername = null;
myPassword = null;
return result;
}
}
private final MyAuthenticator myAuthenticator = new MyAuthenticator();
@Override
public void onResume() {
super.onResume();
getListView().setOnCreateContextMenuListener(this);
onModelChanged(); // do the same update actions as upon onModelChanged
System.err.println("UI thread: " + Thread.currentThread());
Authenticator.setDefault(myAuthenticator);
}
@Override
protected void onStop() {
NetworkView.Instance().removeEventListener(this);
@ -88,12 +124,26 @@ abstract class NetworkBaseActivity extends ListActivity implements NetworkView.E
}
@Override
public void onResume() {
super.onResume();
getListView().setOnCreateContextMenuListener(this);
onModelChanged(); // do the same update actions as upon onModelChanged
public void onDestroy() {
if (Connection != null) {
unbindService(Connection);
Connection = null;
}
super.onDestroy();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == AUTHENTICATION_CODE) {
synchronized (myAuthenticator) {
if (data != null) {
myAuthenticator.myUsername = data.getStringExtra(AuthenticationActivity.USERNAME_KEY);
myAuthenticator.myPassword = data.getStringExtra(AuthenticationActivity.PASSWORD_KEY);
}
myAuthenticator.notify();
}
}
}
// method from NetworkView.EventListener
public void onModelChanged() {

View file

@ -92,6 +92,9 @@ public class NetworkCatalogActivity extends NetworkBaseActivity implements UserR
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
default:
super.onActivityResult(requestCode, resultCode, data);
break;
case USER_REGISTRATION_REQUEST_CODE:
if (myTree instanceof NetworkCatalogTree &&
resultCode == RESULT_OK &&

View file

@ -20,7 +20,6 @@
package org.geometerplus.android.fbreader.network;
import java.util.*;
import java.net.*;
import android.content.Context;
import android.content.Intent;
@ -40,18 +39,6 @@ class NetworkView {
public static NetworkView Instance() {
if (ourInstance == null) {
ourInstance = new NetworkView();
Authenticator.setDefault(new Authenticator() {
@Override
protected PasswordAuthentication getPasswordAuthentication() {
System.err.println("getPasswordAuthentication");
System.err.println(getRequestingSite().getHostName());
System.err.println(getRequestingPrompt());
System.err.println(getRequestingProtocol());
final String username = "geometer";
final String password = "XXXXXXXX";
return new PasswordAuthentication(username, password.toCharArray());
}
});
}
return ourInstance;
}