AutomatedArchitecture / TheShameWhisperer-Jenkins

Sends CI events to a Siren of Shame server for distribution, gamification, and siren sounding.
sirenofshame.com
Apache License 2.0
0 stars 0 forks source link

As a dev I want to be able to enter a username and password and have it validate my credentials so the plugin can sync build info to my account #1

Open lprichar opened 10 years ago

lprichar commented 10 years ago

See https://github.com/AutomatedArchitecture/SirenOfShame/search?q=ApiV1%2FVerifyCredentials for how to call the server and https://github.com/AutomatedArchitecture/SirenOfShame/blob/d4e93c258a520a9f1d70d898e791a87b0ae36ded/SirenOfShame.Lib/Settings/TripleDESStringEncryptor.cs for how to encrypt the password and https://github.com/AutomatedArchitecture/SirenOfShame/blob/becb7f4f0fa734be4e8c59af83a81f4c5cf3aa11/SirenOfShame.Test.Unit/Settings/TripleDESStringEncryptorTest.cs for some encryption unit tests.

mightymuke commented 10 years ago

"I want the app to prompt for..." - I presume having them as global settings would do the trick? I wonder if we can hook it up to the credential manager (eg, Global Credentials).

lprichar commented 10 years ago

Are global settings the sections you see when you click "Manage Jenkins"?

I feel the same way about Manage Credentials as I do about putting configuration fields in jobs: https://github.com/AutomatedArchitecture/TheShameWhisperer-Jenkins/issues/2#issuecomment-45337487. Basically they would be great in addition to a config screen, but ideally not instead of one.

Again, the goal is to make it possible to get up and running with the plugin without reading a single line of documentation, with an absolute minimum number of clicks, and without having to go and find the location to put your credentials info.

So in other words ideally after you've clicked the install button for the plugin you are presented with a config screen where you put in all your details, click save, and it just starts working.

Make sense? Is it even possible?

lprichar commented 10 years ago

By the way here is some Android code I use to perform the encryption and such. Not sure if it's helpful for Jenkins-world or not:

package com.automatedarchitecture.sirenofshame.sosonline;

import android.annotation.SuppressLint; import android.util.Base64; import android.util.Log; import com.automatedarchitecture.sirenofshame.MainActivity;

import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.io.UnsupportedEncodingException; import java.net.URLEncoder;

@SuppressLint("NewApi") public class Credentials { private String username; private String password;

public String getUsername() {
    return username;
}

public void setUsername(String username) {
    this.username = username;
}

public String getPassword() {
    return password;
}

public void setPassword(String password) {
    this.password = password;
}

private String key = "GSYAHAGCBDUUADIADKOPAAAW";
private String iv = "USAZBGAW";

private String encryptPassword(String plainText) {
    try {
        //----  Use specified 3DES key and IV from other source -------------------------
        byte[] plaintext = plainText.getBytes();
        byte[] tdesKeyData = key.getBytes();
        byte[] tdesIv = iv.getBytes();

        System.out.println("plain text length: " + plaintext.length);
        System.out.println("key length: " + tdesKeyData.length);

        Cipher c3des = Cipher.getInstance("DESede/CBC/PKCS5Padding");
        SecretKeySpec    myKey = new SecretKeySpec(tdesKeyData, "DESede");
        IvParameterSpec ivspec = new IvParameterSpec(tdesIv);

        c3des.init(Cipher.ENCRYPT_MODE, myKey, ivspec);
        byte[] cipherText = c3des.doFinal(plaintext);

        return Base64.encodeToString(cipherText, Base64.DEFAULT);
    } catch (Exception ex) {
        Log.e(MainActivity.tag, "Error encoding password", ex);
        return null;
    }
}

protected String urlEncode(String input) throws UnsupportedEncodingException {
    return URLEncoder.encode(input, "utf-8");
}

public String getAsParamString() {
    try {
        String username = getUsername();
        if (username == null || "".equals(username)) return "";
        String password = encryptPassword(getPassword());
        String userNameEncoded = urlEncode(username);
        String passwordEncoded = urlEncode(password.trim());
        return "UserName=" + userNameEncoded + "&Password=" + passwordEncoded;
    } catch (UnsupportedEncodingException e) {
        Log.e(MainActivity.tag, "Error encoding credentials", e);
        return "Unsupported encoding";
    }
}

}

mightymuke commented 10 years ago

I don't think it can do exactly what you want.

The SoS URL and credentials are fine - they can be in the "Manage Jenkins" configuration (although I suggest we also provide an override in the job configuration). The credentials kind of plug into the configuration section, and can be configured there without the need to go hunting for the correct place to do it. To see an example, check out a svn or git configuration in a job (I'd provide a screenshot, but I isn't in the office - and it will need to be a fairly recent version of Jenkins).

As for putting all job information into a central configuration location - I don't think its advisable as this isn't the way Jenkins has been structured. Saying that though, I don't see why we technically couldn't create a page that goes through all the job configurations, pulls out the appropriate information and allows the user to manipulate it. However, I'd do this in addition to (and after) the job specific configuration, so we do keep a consistent Jenkins feel to the plugin.

This plugin is essentially a build notifier so should work in a similar fashion to the others: https://wiki.jenkins-ci.org/display/JENKINS/Plugins#Plugins-Buildnotifiers Unfortunately the documentation for most of those plugins is sadly lacking.

lprichar commented 10 years ago

I see what you're saying about putting which jobs to monitor in job configuration. I guess as long as we account for users that have 500 Jenkins builds and they want to watch 300 of them. The ones they want to watch have a common naming convention (they all start with the same prefix). These numbers and requirements are from an actual customer btw.

Putting credentials in the job configuration seems a little odd. Doesn't it imply that each job could have different credentials?

mightymuke commented 10 years ago

Those number seem to be an anomaly - that's a lot of projects. Not sure of the value of creating an admin page it if its just for 1 (or a few) user (The needs of the many outweigh the needs of the few, or the one). Happy to do it (sounds like fun), but would a groovy script suit better? cf https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+Script+Console

And use case for the credentials: Where I work we have 3 developer departments. We all share the same Jenkins server, but all our projects are completely separate. We may what to provide different credentials for each department.

lprichar commented 10 years ago

Well, they may be an anomaly, but they may also be the first EnterpriseCi customer (aka TeamCi on-premise). So they're opinion is important. But that doesn't make it a high priority. I'll add another user story to accommodate that but set it as low priority.

Great example of use case for credentials: sold.