<commit_before>/*
 * Copyright (c) 2013, Yubico AB.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 *  Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials provided
 *   with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

package com.yubico.yubioath.fragments;

import android.app.DialogFragment;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.yubico.yubioath.MainActivity;
import com.yubico.yubioath.R;
import com.yubico.yubioath.exc.StorageFullException;
import com.yubico.yubioath.model.KeyManager;
import com.yubico.yubioath.model.YubiKeyNeo;
import org.apache.commons.codec.binary.Base32;

import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: dain
 * Date: 8/28/13
 * Time: 10:16 AM
 * To change this template use File | Settings | File Templates.
 */
public class AddCodeFragment extends Fragment implements MainActivity.OnYubiKeyNeoListener {
    private static final String CODE_URI = "codeUri";
    private String name;
    private byte[] key;
    private byte oath_type;
    private byte algorithm_type;
    private int digits;
    private int counter;

    public static AddCodeFragment newInstance(String uri) {
        Bundle bundle = new Bundle();
        bundle.putString(CODE_URI, uri);
        AddCodeFragment fragment = new AddCodeFragment();
        fragment.setArguments(bundle);
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.add_code_fragment, container, false);
        Uri uri = Uri.parse(getArguments().getString(CODE_URI));
        if (parseUri(uri)) {
            ((TextView) view.findViewById(R.id.name)).setText(name);
        } else {
            Toast.makeText(getActivity(), R.string.invalid_barcode, Toast.LENGTH_LONG).show();
            view.post(new Runnable() {
                @Override
                public void run() {
                    ((MainActivity) getActivity()).openFragment(new SwipeListFragment());
                }
            });
        }

        return view;
    }

    private boolean parseUri(Uri uri) {
        String secret = uri.getQueryParameter("secret");
        if (secret == null || secret.isEmpty()) {
            return false;
        }
        Base32 base32 = new Base32();
        key = base32.decode(secret.toUpperCase());

        String path = uri.getPath(); // user name is stored in path...
        if (path.charAt(0) == '/') {
            path = path.substring(1);
        }
        if (path.length() > 64) {
            path = path.substring(0, 64);
        }
        name = path;

        String typeString = uri.getHost(); // type stored in host, totp/hotp
        if (typeString.equals("totp")) {
            oath_type = YubiKeyNeo.TOTP_TYPE;
        } else if (typeString.equals("hotp")) {
            oath_type = YubiKeyNeo.HOTP_TYPE;
        } else {
            return false;
        }

        String algorithm = uri.getQueryParameter("algorithm");
        if (algorithm == null || algorithm.isEmpty() || algorithm.equals("SHA1")) {
            algorithm_type = YubiKeyNeo.HMAC_SHA1;
        } else if (algorithm.equals("SHA256")) {<commit_msg>Check for hierarchical URI.<commit_after>/*
 * Copyright (c) 2013, Yubico AB.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 *  Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials provided
 *   with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

package com.yubico.yubioath.fragments;

import android.app.DialogFragment;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.yubico.yubioath.MainActivity;
import com.yubico.yubioath.R;
import com.yubico.yubioath.exc.StorageFullException;
import com.yubico.yubioath.model.KeyManager;
import com.yubico.yubioath.model.YubiKeyNeo;
import org.apache.commons.codec.binary.Base32;

import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: dain
 * Date: 8/28/13
 * Time: 10:16 AM
 * To change this template use File | Settings | File Templates.
 */
public class AddCodeFragment extends Fragment implements MainActivity.OnYubiKeyNeoListener {
    private static final String CODE_URI = "codeUri";
    private String name;
    private byte[] key;
    private byte oath_type;
    private byte algorithm_type;
    private int digits;
    private int counter;

    public static AddCodeFragment newInstance(String uri) {
        Bundle bundle = new Bundle();
        bundle.putString(CODE_URI, uri);
        AddCodeFragment fragment = new AddCodeFragment();
        fragment.setArguments(bundle);
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.add_code_fragment, container, false);
        Uri uri = Uri.parse(getArguments().getString(CODE_URI));
        if (parseUri(uri)) {
            ((TextView) view.findViewById(R.id.name)).setText(name);
        } else {
            Toast.makeText(getActivity(), R.string.invalid_barcode, Toast.LENGTH_LONG).show();
            view.post(new Runnable() {
                @Override
                public void run() {
                    ((MainActivity) getActivity()).openFragment(new SwipeListFragment());
                }
            });
        }

        return view;
    }

    private boolean parseUri(Uri uri) {
        if(!uri.isHierarchical() || !uri.getScheme().equals("otpauth")) {
            return false;
        }

        String secret = uri.getQueryParameter("secret");
        if (secret == null || secret.isEmpty()) {
            return false;
        }
        Base32 base32 = new Base32();
        key = base32.decode(secret.toUpperCase());

        String path = uri.getPath(); // user name is stored in path...
        if (path.charAt(0) == '/') {
            path = path.substring(1);
        }
        if (path.length() > 64) {
            path = path.substring(0, 64);
        }
        name = path;

        String typeString = uri.getHost(); // type stored in host, totp/hotp
        if (typeString.equals("totp")) {
            oath_type = YubiKeyNeo.TOTP_TYPE;
        } else if (typeString.equals("hotp")) {
            oath_type = YubiKeyNeo.HOTP_TYPE;
        } else {
            return false;
        }

        String algorithm = uri.getQueryParameter("algorithm");
        if (algorithm == null || algorithm.isEmpty() || algorithm.equals("SHA1")) {
            algorithm_type = YubiKeyNeo.HMAC_SHA1;
        } else if (algorithm.equals("SHA256")) {
{'fraction_non_alphanumeric': 0.09489204844655082, 'fraction_numerical': 0.00737230121116377, 'mean_word_length': 2.9899159663865547, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6125340', 'n_tokens_mistral': 2763, 'n_tokens_neox': 2569, 'n_words': 831}