Introduce credentials
This commit is contained in:
parent
87c8aef7d9
commit
b49da53962
@ -36,7 +36,7 @@ from _pygit2 import *
|
|||||||
from .repository import Repository
|
from .repository import Repository
|
||||||
from .version import __version__
|
from .version import __version__
|
||||||
from .settings import Settings
|
from .settings import Settings
|
||||||
|
from .credentials import *
|
||||||
|
|
||||||
def init_repository(path, bare=False):
|
def init_repository(path, bare=False):
|
||||||
"""
|
"""
|
||||||
|
52
pygit2/credentials.py
Normal file
52
pygit2/credentials.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# Copyright 2010-2014 The pygit2 contributors
|
||||||
|
#
|
||||||
|
# This file is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
|
# as published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# In addition to the permissions in the GNU General Public License,
|
||||||
|
# the authors give you unlimited permission to link the compiled
|
||||||
|
# version of this file into combinations with other programs,
|
||||||
|
# and to distribute those combinations without any restriction
|
||||||
|
# coming from the use of this file. (The General Public License
|
||||||
|
# restrictions do apply in other respects; for example, they cover
|
||||||
|
# modification of the file, and distribution when not linked into
|
||||||
|
# a combined executable.)
|
||||||
|
#
|
||||||
|
# This file 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; see the file COPYING. If not, write to
|
||||||
|
# the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||||
|
# Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
# Import from pygit2
|
||||||
|
from _pygit2 import CredUsernamePassword, CredSshKey
|
||||||
|
from _pygit2 import GIT_CREDTYPE_USERPASS_PLAINTEXT
|
||||||
|
|
||||||
|
class UserPass(CredUsernamePassword):
|
||||||
|
"""Username/Password credentials
|
||||||
|
|
||||||
|
This is an object suitable for passing to a remote's credentials
|
||||||
|
callback.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __call__(self, _url, _username, _allowed):
|
||||||
|
return self
|
||||||
|
|
||||||
|
class Keypair(CredSshKey):
|
||||||
|
"""SSH key pair credentials
|
||||||
|
|
||||||
|
This is an object suitable for passing to a remote's credentials
|
||||||
|
callback.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __call__(self, _url, _username, _allowed):
|
||||||
|
return self
|
225
src/credentials.c
Normal file
225
src/credentials.c
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2014 The pygit2 contributors
|
||||||
|
*
|
||||||
|
* This file is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License, version 2,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* In addition to the permissions in the GNU General Public License,
|
||||||
|
* the authors give you unlimited permission to link the compiled
|
||||||
|
* version of this file into combinations with other programs,
|
||||||
|
* and to distribute those combinations without any restriction
|
||||||
|
* coming from the use of this file. (The General Public License
|
||||||
|
* restrictions do apply in other respects; for example, they cover
|
||||||
|
* modification of the file, and distribution when not linked into
|
||||||
|
* a combined executable.)
|
||||||
|
*
|
||||||
|
* This file 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; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PY_SSIZE_T_CLEAN
|
||||||
|
#include <Python.h>
|
||||||
|
#include <structmember.h>
|
||||||
|
#include "error.h"
|
||||||
|
#include "types.h"
|
||||||
|
#include "utils.h"
|
||||||
|
#include "oid.h"
|
||||||
|
#include "refspec.h"
|
||||||
|
#include "remote.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
CredUsernamePassword_init(CredUsernamePassword *self, PyObject *args, PyObject *kwds)
|
||||||
|
{
|
||||||
|
char *username, *password;
|
||||||
|
|
||||||
|
if (kwds && PyDict_Size(kwds) > 0) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "CredUsernamePassword takes no keyword arguments");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "ss", &username, &password))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
self->parent.credtype = GIT_CREDTYPE_USERPASS_PLAINTEXT;
|
||||||
|
|
||||||
|
self->username = strdup(username);
|
||||||
|
if (!self->username) {
|
||||||
|
PyErr_NoMemory();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
self->password = strdup(password);
|
||||||
|
if (!self->password) {
|
||||||
|
free(self->username);
|
||||||
|
PyErr_NoMemory();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CredUsernamePassword_dealloc(CredUsernamePassword *self)
|
||||||
|
{
|
||||||
|
free(self->username);
|
||||||
|
free(self->password);
|
||||||
|
|
||||||
|
PyObject_Del(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyMemberDef CredUsernamePassword_members[] = {
|
||||||
|
MEMBER(CredUsernamePassword, username, T_STRING, "username"),
|
||||||
|
MEMBER(CredUsernamePassword, password, T_STRING, "password"),
|
||||||
|
{NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
PyDoc_STRVAR(CredUsernamePassword__doc__,
|
||||||
|
"Credential type for username/password combination");
|
||||||
|
|
||||||
|
PyTypeObject CredUsernamePasswordType = {
|
||||||
|
PyVarObject_HEAD_INIT(NULL, 0)
|
||||||
|
"_pygit2.CredUsernamePassword", /* tp_name */
|
||||||
|
sizeof(CredUsernamePassword), /* tp_basicsize */
|
||||||
|
0, /* tp_itemsize */
|
||||||
|
(destructor)CredUsernamePassword_dealloc, /* tp_dealloc */
|
||||||
|
0, /* tp_print */
|
||||||
|
0, /* tp_getattr */
|
||||||
|
0, /* tp_setattr */
|
||||||
|
0, /* tp_compare */
|
||||||
|
0, /* tp_repr */
|
||||||
|
0, /* tp_as_number */
|
||||||
|
0, /* tp_as_sequence */
|
||||||
|
0, /* tp_as_mapping */
|
||||||
|
0, /* tp_hash */
|
||||||
|
0, /* tp_call */
|
||||||
|
0, /* tp_str */
|
||||||
|
0, /* tp_getattro */
|
||||||
|
0, /* tp_setattro */
|
||||||
|
0, /* tp_as_buffer */
|
||||||
|
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
|
||||||
|
CredUsernamePassword__doc__, /* tp_doc */
|
||||||
|
0, /* tp_traverse */
|
||||||
|
0, /* tp_clear */
|
||||||
|
0, /* tp_richcompare */
|
||||||
|
0, /* tp_weaklistoffset */
|
||||||
|
0, /* tp_iter */
|
||||||
|
0, /* tp_iternext */
|
||||||
|
0, /* tp_methods */
|
||||||
|
CredUsernamePassword_members, /* tp_members */
|
||||||
|
0, /* tp_getset */
|
||||||
|
0, /* tp_base */
|
||||||
|
0, /* tp_dict */
|
||||||
|
0, /* tp_descr_get */
|
||||||
|
0, /* tp_descr_set */
|
||||||
|
0, /* tp_dictoffset */
|
||||||
|
(initproc)CredUsernamePassword_init, /* tp_init */
|
||||||
|
0, /* tp_alloc */
|
||||||
|
0, /* tp_new */
|
||||||
|
};
|
||||||
|
|
||||||
|
int
|
||||||
|
CredSshKey_init(CredSshKey *self, PyObject *args, PyObject *kwds)
|
||||||
|
{
|
||||||
|
char *username, *pubkey, *privkey, *passphrase;
|
||||||
|
|
||||||
|
if (kwds && PyDict_Size(kwds) > 0) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "CredSshKey takes no keyword arguments");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "ssss", &username, &pubkey,
|
||||||
|
&privkey, &passphrase))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
self->parent.credtype = GIT_CREDTYPE_SSH_KEY;
|
||||||
|
self->username = self->pubkey = self->privkey = self->passphrase = NULL;
|
||||||
|
|
||||||
|
self->username = strdup(username);
|
||||||
|
self->pubkey = strdup(pubkey);
|
||||||
|
self->privkey = strdup(privkey);
|
||||||
|
self->passphrase = strdup(passphrase);
|
||||||
|
|
||||||
|
if (!(self->username && self->pubkey && self->privkey && self->passphrase))
|
||||||
|
goto on_oom;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
on_oom:
|
||||||
|
free(self->username);
|
||||||
|
free(self->pubkey);
|
||||||
|
free(self->privkey);
|
||||||
|
free(self->passphrase);
|
||||||
|
PyErr_NoMemory();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CredSshKey_dealloc(CredSshKey *self)
|
||||||
|
{
|
||||||
|
free(self->username);
|
||||||
|
free(self->pubkey);
|
||||||
|
free(self->privkey);
|
||||||
|
free(self->passphrase);
|
||||||
|
|
||||||
|
PyObject_Del(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyMemberDef CredSshKey_members[] = {
|
||||||
|
MEMBER(CredSshKey, username, T_STRING, "username"),
|
||||||
|
MEMBER(CredSshKey, pubkey, T_STRING, "pubkey"),
|
||||||
|
MEMBER(CredSshKey, privkey, T_STRING, "privkey"),
|
||||||
|
MEMBER(CredSshKey, passphrase, T_STRING, "passphrase"),
|
||||||
|
{NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
PyDoc_STRVAR(CredSshKey__doc__,
|
||||||
|
"Credential type for an SSH keypair");
|
||||||
|
|
||||||
|
PyTypeObject CredSshKeyType = {
|
||||||
|
PyVarObject_HEAD_INIT(NULL, 0)
|
||||||
|
"_pygit2.CredSshKey", /* tp_name */
|
||||||
|
sizeof(CredSshKey), /* tp_basicsize */
|
||||||
|
0, /* tp_itemsize */
|
||||||
|
(destructor)CredSshKey_dealloc, /* tp_dealloc */
|
||||||
|
0, /* tp_print */
|
||||||
|
0, /* tp_getattr */
|
||||||
|
0, /* tp_setattr */
|
||||||
|
0, /* tp_compare */
|
||||||
|
0, /* tp_repr */
|
||||||
|
0, /* tp_as_number */
|
||||||
|
0, /* tp_as_sequence */
|
||||||
|
0, /* tp_as_mapping */
|
||||||
|
0, /* tp_hash */
|
||||||
|
0, /* tp_call */
|
||||||
|
0, /* tp_str */
|
||||||
|
0, /* tp_getattro */
|
||||||
|
0, /* tp_setattro */
|
||||||
|
0, /* tp_as_buffer */
|
||||||
|
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
|
||||||
|
CredSshKey__doc__, /* tp_doc */
|
||||||
|
0, /* tp_traverse */
|
||||||
|
0, /* tp_clear */
|
||||||
|
0, /* tp_richcompare */
|
||||||
|
0, /* tp_weaklistoffset */
|
||||||
|
0, /* tp_iter */
|
||||||
|
0, /* tp_iternext */
|
||||||
|
0, /* tp_methods */
|
||||||
|
CredSshKey_members, /* tp_members */
|
||||||
|
0, /* tp_getset */
|
||||||
|
0, /* tp_base */
|
||||||
|
0, /* tp_dict */
|
||||||
|
0, /* tp_descr_get */
|
||||||
|
0, /* tp_descr_set */
|
||||||
|
0, /* tp_dictoffset */
|
||||||
|
(initproc)CredSshKey_init, /* tp_init */
|
||||||
|
0, /* tp_alloc */
|
||||||
|
0, /* tp_new */
|
||||||
|
};
|
@ -74,6 +74,8 @@ extern PyTypeObject RefLogEntryType;
|
|||||||
extern PyTypeObject BranchType;
|
extern PyTypeObject BranchType;
|
||||||
extern PyTypeObject SignatureType;
|
extern PyTypeObject SignatureType;
|
||||||
extern PyTypeObject RemoteType;
|
extern PyTypeObject RemoteType;
|
||||||
|
extern PyTypeObject CredUsernamePasswordType;
|
||||||
|
extern PyTypeObject CredSshKeyType;
|
||||||
extern PyTypeObject RefspecType;
|
extern PyTypeObject RefspecType;
|
||||||
extern PyTypeObject TransferProgressType;
|
extern PyTypeObject TransferProgressType;
|
||||||
extern PyTypeObject NoteType;
|
extern PyTypeObject NoteType;
|
||||||
@ -444,14 +446,21 @@ moduleinit(PyObject* m)
|
|||||||
|
|
||||||
/* Remotes */
|
/* Remotes */
|
||||||
INIT_TYPE(RemoteType, NULL, NULL)
|
INIT_TYPE(RemoteType, NULL, NULL)
|
||||||
|
INIT_TYPE(CredUsernamePasswordType, NULL, PyType_GenericNew)
|
||||||
|
INIT_TYPE(CredSshKeyType, NULL, PyType_GenericNew)
|
||||||
INIT_TYPE(RefspecType, NULL, NULL)
|
INIT_TYPE(RefspecType, NULL, NULL)
|
||||||
INIT_TYPE(TransferProgressType, NULL, NULL)
|
INIT_TYPE(TransferProgressType, NULL, NULL)
|
||||||
ADD_TYPE(m, Remote)
|
ADD_TYPE(m, Remote)
|
||||||
|
ADD_TYPE(m, CredUsernamePassword)
|
||||||
|
ADD_TYPE(m, CredSshKey)
|
||||||
ADD_TYPE(m, Refspec)
|
ADD_TYPE(m, Refspec)
|
||||||
ADD_TYPE(m, TransferProgress)
|
ADD_TYPE(m, TransferProgress)
|
||||||
/* Direction for the refspec */
|
/* Direction for the refspec */
|
||||||
ADD_CONSTANT_INT(m, GIT_DIRECTION_FETCH)
|
ADD_CONSTANT_INT(m, GIT_DIRECTION_FETCH)
|
||||||
ADD_CONSTANT_INT(m, GIT_DIRECTION_PUSH)
|
ADD_CONSTANT_INT(m, GIT_DIRECTION_PUSH)
|
||||||
|
/* Credential types */
|
||||||
|
ADD_CONSTANT_INT(m, GIT_CREDTYPE_USERPASS_PLAINTEXT)
|
||||||
|
ADD_CONSTANT_INT(m, GIT_CREDTYPE_SSH_KEY)
|
||||||
|
|
||||||
/* Blame */
|
/* Blame */
|
||||||
INIT_TYPE(BlameType, NULL, NULL)
|
INIT_TYPE(BlameType, NULL, NULL)
|
||||||
|
77
src/remote.c
77
src/remote.c
@ -39,6 +39,8 @@
|
|||||||
extern PyObject *GitError;
|
extern PyObject *GitError;
|
||||||
extern PyTypeObject RepositoryType;
|
extern PyTypeObject RepositoryType;
|
||||||
extern PyTypeObject TransferProgressType;
|
extern PyTypeObject TransferProgressType;
|
||||||
|
extern PyTypeObject CredUsernamePasswordType;
|
||||||
|
extern PyTypeObject CredSshKeyType;
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
wrap_transfer_progress(const git_transfer_progress *stats)
|
wrap_transfer_progress(const git_transfer_progress *stats)
|
||||||
@ -156,6 +158,78 @@ progress_cb(const char *str, int len, void *data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
py_cred_to_git_cred(git_cred **out, PyObject *py_cred, unsigned int allowed)
|
||||||
|
{
|
||||||
|
Cred *base_cred;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (!PyObject_TypeCheck(py_cred, &CredUsernamePasswordType) &&
|
||||||
|
!PyObject_TypeCheck(py_cred, &CredSshKeyType)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "unkown credential type");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
base_cred = (Cred *) py_cred;
|
||||||
|
|
||||||
|
/* Sanity check, make sure we're given credentials we can use */
|
||||||
|
if (!(allowed & base_cred->credtype)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "invalid credential type");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (base_cred->credtype) {
|
||||||
|
case GIT_CREDTYPE_USERPASS_PLAINTEXT:
|
||||||
|
{
|
||||||
|
CredUsernamePassword *cred = (CredUsernamePassword *) base_cred;
|
||||||
|
err = git_cred_userpass_plaintext_new(out, cred->username, cred->password);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GIT_CREDTYPE_SSH_KEY:
|
||||||
|
{
|
||||||
|
CredSshKey *cred = (CredSshKey *) base_cred;
|
||||||
|
err = git_cred_ssh_key_new(out, cred->username, cred->pubkey, cred->privkey, cred->passphrase);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
PyErr_SetString(PyExc_TypeError, "unsupported credential type");
|
||||||
|
err = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
credentials_cb(git_cred **out, const char *url, const char *username_from_url, unsigned int allowed_types, void *data)
|
||||||
|
{
|
||||||
|
Remote *remote = (Remote *) data;
|
||||||
|
PyObject *arglist, *py_cred;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (remote->credentials == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!PyCallable_Check(remote->credentials)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "credentials callback is not callable");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
arglist = Py_BuildValue("(szI)", url, username_from_url, allowed_types);
|
||||||
|
py_cred = PyObject_CallObject(remote->credentials, arglist);
|
||||||
|
Py_DECREF(arglist);
|
||||||
|
|
||||||
|
if (!py_cred)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
err = py_cred_to_git_cred(out, py_cred, allowed_types);
|
||||||
|
|
||||||
|
|
||||||
|
Py_DECREF(py_cred);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
transfer_progress_cb(const git_transfer_progress *stats, void *data)
|
transfer_progress_cb(const git_transfer_progress *stats, void *data)
|
||||||
{
|
{
|
||||||
@ -631,6 +705,7 @@ PyGetSetDef Remote_getseters[] = {
|
|||||||
|
|
||||||
PyMemberDef Remote_members[] = {
|
PyMemberDef Remote_members[] = {
|
||||||
MEMBER(Remote, progress, T_OBJECT_EX, "Progress output callback"),
|
MEMBER(Remote, progress, T_OBJECT_EX, "Progress output callback"),
|
||||||
|
MEMBER(Remote, credentials, T_OBJECT_EX, "Credentials callback"),
|
||||||
MEMBER(Remote, transfer_progress, T_OBJECT_EX, "Transfer progress callback"),
|
MEMBER(Remote, transfer_progress, T_OBJECT_EX, "Transfer progress callback"),
|
||||||
MEMBER(Remote, update_tips, T_OBJECT_EX, "update tips callback"),
|
MEMBER(Remote, update_tips, T_OBJECT_EX, "update tips callback"),
|
||||||
{NULL},
|
{NULL},
|
||||||
@ -691,10 +766,12 @@ wrap_remote(git_remote *c_remote, Repository *repo)
|
|||||||
py_remote->repo = repo;
|
py_remote->repo = repo;
|
||||||
py_remote->remote = c_remote;
|
py_remote->remote = c_remote;
|
||||||
py_remote->progress = NULL;
|
py_remote->progress = NULL;
|
||||||
|
py_remote->credentials = NULL;
|
||||||
py_remote->transfer_progress = NULL;
|
py_remote->transfer_progress = NULL;
|
||||||
py_remote->update_tips = NULL;
|
py_remote->update_tips = NULL;
|
||||||
|
|
||||||
callbacks.progress = progress_cb;
|
callbacks.progress = progress_cb;
|
||||||
|
callbacks.credentials = credentials_cb;
|
||||||
callbacks.transfer_progress = transfer_progress_cb;
|
callbacks.transfer_progress = transfer_progress_cb;
|
||||||
callbacks.update_tips = update_tips_cb;
|
callbacks.update_tips = update_tips_cb;
|
||||||
callbacks.payload = py_remote;
|
callbacks.payload = py_remote;
|
||||||
|
20
src/types.h
20
src/types.h
@ -202,10 +202,30 @@ typedef struct {
|
|||||||
git_remote *remote;
|
git_remote *remote;
|
||||||
/* Callbacks for network events */
|
/* Callbacks for network events */
|
||||||
PyObject *progress;
|
PyObject *progress;
|
||||||
|
PyObject *credentials;
|
||||||
PyObject *transfer_progress;
|
PyObject *transfer_progress;
|
||||||
PyObject *update_tips;
|
PyObject *update_tips;
|
||||||
} Remote;
|
} Remote;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PyObject_HEAD
|
||||||
|
git_credtype_t credtype;
|
||||||
|
} Cred;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Cred parent;
|
||||||
|
char *username;
|
||||||
|
char *password;
|
||||||
|
} CredUsernamePassword;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Cred parent;
|
||||||
|
char *username;
|
||||||
|
char *pubkey;
|
||||||
|
char *privkey;
|
||||||
|
char *passphrase;
|
||||||
|
} CredSshKey;
|
||||||
|
|
||||||
/* git_refspec */
|
/* git_refspec */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
|
98
test/test_credentials.py
Normal file
98
test/test_credentials.py
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
# -*- coding: UTF-8 -*-
|
||||||
|
#
|
||||||
|
# Copyright 2010-2014 The pygit2 contributors
|
||||||
|
#
|
||||||
|
# This file is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License, version 2,
|
||||||
|
# as published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# In addition to the permissions in the GNU General Public License,
|
||||||
|
# the authors give you unlimited permission to link the compiled
|
||||||
|
# version of this file into combinations with other programs,
|
||||||
|
# and to distribute those combinations without any restriction
|
||||||
|
# coming from the use of this file. (The General Public License
|
||||||
|
# restrictions do apply in other respects; for example, they cover
|
||||||
|
# modification of the file, and distribution when not linked into
|
||||||
|
# a combined executable.)
|
||||||
|
#
|
||||||
|
# This file 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; see the file COPYING. If not, write to
|
||||||
|
# the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
||||||
|
# Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
"""Tests for credentials"""
|
||||||
|
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
import pygit2
|
||||||
|
from pygit2 import CredUsernamePassword, CredSshKey
|
||||||
|
from pygit2 import GIT_CREDTYPE_USERPASS_PLAINTEXT
|
||||||
|
from pygit2 import UserPass, Keypair
|
||||||
|
from . import utils
|
||||||
|
|
||||||
|
REMOTE_NAME = 'origin'
|
||||||
|
REMOTE_URL = 'git://github.com/libgit2/pygit2.git'
|
||||||
|
REMOTE_FETCHSPEC_SRC = 'refs/heads/*'
|
||||||
|
REMOTE_FETCHSPEC_DST = 'refs/remotes/origin/*'
|
||||||
|
REMOTE_REPO_OBJECTS = 30
|
||||||
|
REMOTE_REPO_BYTES = 2758
|
||||||
|
|
||||||
|
ORIGIN_REFSPEC = '+refs/heads/*:refs/remotes/origin/*'
|
||||||
|
|
||||||
|
class CredentialCreateTest(utils.NoRepoTestCase):
|
||||||
|
def test_userpass(self):
|
||||||
|
username = "git"
|
||||||
|
password = "sekkrit"
|
||||||
|
|
||||||
|
cred = CredUsernamePassword(username, password)
|
||||||
|
self.assertEqual(username, cred.username)
|
||||||
|
self.assertEqual(password, cred.password)
|
||||||
|
|
||||||
|
def test_ssh_key(self):
|
||||||
|
username = "git"
|
||||||
|
pubkey = "id_rsa.pub"
|
||||||
|
privkey = "id_rsa"
|
||||||
|
passphrase = "bad wolf"
|
||||||
|
|
||||||
|
cred = CredSshKey(username, pubkey, privkey, passphrase)
|
||||||
|
self.assertEqual(username, cred.username)
|
||||||
|
self.assertEqual(pubkey, cred.pubkey)
|
||||||
|
self.assertEqual(privkey, cred.privkey)
|
||||||
|
self.assertEqual(passphrase, cred.passphrase)
|
||||||
|
|
||||||
|
class CredentialCallback(utils.RepoTestCase):
|
||||||
|
def test_callback(self):
|
||||||
|
def credentials_cb(url, username, allowed):
|
||||||
|
self.assertTrue(allowed & GIT_CREDTYPE_USERPASS_PLAINTEXT)
|
||||||
|
raise Exception("I don't know the password")
|
||||||
|
|
||||||
|
remote = self.repo.create_remote("github", "https://github.com/github/github")
|
||||||
|
remote.credentials = credentials_cb
|
||||||
|
|
||||||
|
self.assertRaises(Exception, remote.fetch)
|
||||||
|
|
||||||
|
def test_bad_cred_type(self):
|
||||||
|
def credentials_cb(url, username, allowed):
|
||||||
|
self.assertTrue(allowed & GIT_CREDTYPE_USERPASS_PLAINTEXT)
|
||||||
|
return CredSshKey("git", "foo.pub", "foo", "sekkrit")
|
||||||
|
|
||||||
|
remote = self.repo.create_remote("github", "https://github.com/github/github")
|
||||||
|
remote.credentials = credentials_cb
|
||||||
|
|
||||||
|
self.assertRaises(TypeError, remote.fetch)
|
||||||
|
|
||||||
|
class CallableCredentialTest(utils.RepoTestCase):
|
||||||
|
|
||||||
|
def test_user_pass(self):
|
||||||
|
remote = self.repo.create_remote("bb", "https://bitbucket.org/libgit2/testgitrepository.git")
|
||||||
|
remote.credentials = UserPass("libgit2", "libgit2")
|
||||||
|
|
||||||
|
remote.fetch()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
Loading…
Reference in New Issue
Block a user