/* * Copyright 2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.springsource.greenhouse.authorization; import java.util.Map; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.social.connect.Connection; import org.springframework.social.connect.ConnectionRepository; import org.springframework.social.connect.DuplicateConnectionException; import org.springframework.social.greenhouse.api.Greenhouse; import org.springframework.social.greenhouse.connect.GreenhouseConnectionFactory; import org.springframework.social.oauth2.AccessGrant; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.RestTemplate; import android.app.AlertDialog; import android.content.Intent; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.EditText; import com.springsource.greenhouse.AbstractGreenhouseActivity; import com.springsource.greenhouse.MainActivity; import com.springsource.greenhouse.R; /** * @author Roy Clarkson */ public class SignInActivity extends AbstractGreenhouseActivity { private static final String TAG = SignInActivity.class.getSimpleName(); //*************************************** // Activity methods //*************************************** @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.sign_in); findViewById(R.id.cancel_button).setOnClickListener(new OnClickListener() { @Override public void onClick(final View view) { finish(); } }); findViewById(R.id.sign_in_button).setOnClickListener(new OnClickListener() { @Override public void onClick(final View view) { if (validateFormData()) { new SignInTask().execute(); } else { displayAppAuthorizationError("Your email or password was entered incorrectly."); } } }); } // *************************************** // Private methods // *************************************** private boolean validateFormData() { EditText editText = (EditText) findViewById(R.id.username); String username = editText.getText().toString().trim(); editText = (EditText) findViewById(R.id.password); String password = editText.getText().toString().trim(); if (username.length() > 0 && password.length() > 0) { return true; } return false; } private void displayAppAuthorizationError(String message) { new AlertDialog.Builder(this).setMessage(message).setCancelable(false) .setPositiveButton("OK", null).create().show(); } private void displayGreenhouseOptions() { Intent intent = new Intent(); intent.setClass(this, MainActivity.class); startActivity(intent); setResult(RESULT_OK); finish(); } private AccessGrant extractAccessGrant(Map<String, Object> result) { return new AccessGrant((String) result.get("access_token"), (String) result.get("scope"), (String) result.get("refresh_token"), getIntegerValue(result, "expires_in")); } // Retrieves object from map into an Integer, regardless of the object's actual type. Allows for flexibility in object type (eg, "3600" vs 3600). private Integer getIntegerValue(Map<String, Object> map, String key) { try { return Integer.valueOf(String.valueOf(map.get(key))); // normalize to String before creating integer value; } catch (NumberFormatException e) { return null; } } //*************************************** // Private classes //*************************************** private class SignInTask extends AsyncTask<Void, Void, Void> { private MultiValueMap<String, String> formData; private Exception exception; @Override protected void onPreExecute() { showProgressDialog("Signing in..."); EditText editText = (EditText) findViewById(R.id.username); String username = editText.getText().toString().trim(); editText = (EditText) findViewById(R.id.password); String password = editText.getText().toString().trim(); formData = new LinkedMultiValueMap<String, String>(); formData.add("grant_type", "password"); formData.add("username", username); formData.add("password", password); formData.add("client_id", getApplicationContext().getClientId()); formData.add("client_secret", getApplicationContext().getClientSecret()); formData.add("scope", "read,write"); Log.d(TAG, formData.toString()); } @Override @SuppressWarnings("unchecked") protected Void doInBackground(Void... params) { try { final String url = getApplicationContext().getApiUrlBase() + "oauth/token"; Log.d(TAG, url); HttpHeaders requestHeaders = new HttpHeaders(); requestHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED); HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<MultiValueMap<String, String>>(formData, requestHeaders); RestTemplate restTemplate = new RestTemplate(true); Map<String, Object> responseBody = restTemplate.exchange(url, HttpMethod.POST, requestEntity, Map.class).getBody(); Log.d(TAG, responseBody.toString()); // Persist the connection and AccessGrant to the repository AccessGrant accessGrant = extractAccessGrant(responseBody); GreenhouseConnectionFactory connectionFactory = getApplicationContext().getConnectionFactory(); ConnectionRepository connectionRepository = getApplicationContext().getConnectionRepository(); Connection<Greenhouse> connection = connectionFactory.createConnection(accessGrant); connectionRepository.addConnection(connection); } catch (Exception e) { Log.e(TAG, e.getLocalizedMessage(), e); this.exception = e; } return null; } @Override protected void onPostExecute(Void v) { dismissProgressDialog(); if (exception != null) { String message; if (exception instanceof HttpClientErrorException && (((HttpClientErrorException) exception).getStatusCode() == HttpStatus.BAD_REQUEST) || ((HttpClientErrorException) exception).getStatusCode() == HttpStatus.UNAUTHORIZED) { message = "Your email or password was entered incorrectly."; } else if (exception instanceof DuplicateConnectionException) { message = "The connection already exists."; } else { Log.e(TAG, exception.getLocalizedMessage(), exception); message = "A problem occurred with the network connection. Please try again in a few minutes."; } displayAppAuthorizationError(message); } else { displayGreenhouseOptions(); } } } }