예제 #1
0
def main():
    if DEBUG:
        logging.basicConfig(level=logging.DEBUG,
                            format='%(asctime)s %(name)-18s %(levelname)-8s '
                                   '%(message)s',
                            datefmt='%m-%d %H:%M',
                            filename='rbssh.log',
                            filemode='w')

        logging.debug('%s' % sys.argv)
        logging.debug('PID %s' % os.getpid())

    ch = logging.StreamHandler()
    ch.setLevel(logging.INFO)
    ch.setFormatter(logging.Formatter('%(message)s'))
    ch.addFilter(logging.Filter('root'))
    logging.getLogger('').addHandler(ch)

    path, command = parse_options(sys.argv[1:])

    if '://' not in path:
        path = 'ssh://' + path

    username, hostname = SCMTool.get_auth_from_uri(path, options.username)

    if username is None:
        username = getpass.getuser()

    logging.debug('!!! %s, %s, %s' % (hostname, username, command))

    client = sshutils.get_ssh_client(options.local_site_name)
    client.set_missing_host_key_policy(paramiko.WarningPolicy())

    attempts = 0
    password = None

    key = sshutils.get_user_key(options.local_site_name)

    while True:
        try:
            client.connect(hostname, username=username, password=password,
                           pkey=key, allow_agent=options.allow_agent)
            break
        except paramiko.AuthenticationException, e:
            if attempts == 3 or not sys.stdin.isatty():
                logging.error('Too many authentication failures for %s' %
                              username)
                sys.exit(1)

            attempts += 1
            password = getpass.getpass("%s@%s's password: " %
                                       (username, hostname))
        except paramiko.SSHException, e:
            logging.error('Error connecting to server: %s' % e)
            sys.exit(1)
예제 #2
0
    def __init__(self, *args, **kwargs):
        super(RepositoryForm, self).__init__(*args, **kwargs)

        self.hostkeyerror = None
        self.certerror = None
        self.userkeyerror = None

        self.public_key = sshutils.get_public_key(sshutils.get_user_key())

        self._populate_hosting_service_fields()
        self._populate_bug_tracker_fields()
예제 #3
0
def ssh_settings(request, template_name='admin/ssh_settings.html'):
    key = sshutils.get_user_key()

    if request.method == 'POST':
        form = SSHSettingsForm(request.POST, request.FILES)

        if form.is_valid():
            try:
                form.create(request.FILES)
                return HttpResponseRedirect('.')
            except Exception, e:
                # Fall through. It will be reported inline and in the log.
                logging.error('Uploading SSH key failed: %s' % e)
예제 #4
0
def ssh_settings(request, template_name='admin/ssh_settings.html'):
    key = sshutils.get_user_key()

    if request.method == 'POST':
        form = SSHSettingsForm(request.POST, request.FILES)

        if form.is_valid():
            try:
                form.create(request.FILES)
                return HttpResponseRedirect('.')
            except Exception, e:
                # Fall through. It will be reported inline and in the log.
                logging.error('Uploading SSH key failed: %s' % e)
예제 #5
0
파일: forms.py 프로젝트: cluon/reviewboard
    def __init__(self, *args, **kwargs):
        super(RepositoryForm, self).__init__(*args, **kwargs)

        self.hostkeyerror = None
        self.certerror = None
        self.userkeyerror = None

        local_site_name = None

        if self.instance and self.instance.local_site:
            local_site_name = self.instance.local_site.name
        elif self.fields['local_site'].initial:
            local_site_name = self.fields['local_site'].initial.name

        self.public_key = \
            sshutils.get_public_key(sshutils.get_user_key(local_site_name))

        self._populate_hosting_service_fields()
        self._populate_bug_tracker_fields()
예제 #6
0
    def __init__(self, *args, **kwargs):
        super(RepositoryForm, self).__init__(*args, **kwargs)

        self.hostkeyerror = None
        self.certerror = None
        self.userkeyerror = None

        local_site_name = None

        if self.instance and self.instance.local_site:
            local_site_name = self.instance.local_site.name
        elif self.fields['local_site'].initial:
            local_site_name = self.fields['local_site'].initial.name

        self.public_key = \
            sshutils.get_public_key(sshutils.get_user_key(local_site_name))

        self._populate_hosting_service_fields()
        self._populate_bug_tracker_fields()
예제 #7
0
class RepositoryForm(forms.ModelForm):
    """A form for creating and updating repositories.

    This form provides an interface for creating and updating repositories,
    handling the association with hosting services, linking accounts,
    dealing with SSH keys and SSL certificates, and more.
    """
    REPOSITORY_INFO_FIELDSET = _('Repository Information')
    BUG_TRACKER_FIELDSET = _('Bug Tracker')

    NO_HOSTING_SERVICE_ID = 'custom'
    NO_HOSTING_SERVICE_NAME = _('(None - Custom Repository)')

    NO_BUG_TRACKER_ID = 'none'
    NO_BUG_TRACKER_NAME = _('(None)')

    CUSTOM_BUG_TRACKER_ID = 'custom'
    CUSTOM_BUG_TRACKER_NAME = _('(Custom Bug Tracker)')

    IGNORED_SERVICE_IDS = ('none', 'custom')

    DEFAULT_PLAN_ID = 'default'
    DEFAULT_PLAN_NAME = _('Default')

    # Host trust state
    reedit_repository = forms.BooleanField(label=_("Re-edit repository"),
                                           required=False)

    trust_host = forms.BooleanField(label=_("I trust this host"),
                                    required=False)

    # Repository Hosting fields
    hosting_type = forms.ChoiceField(label=_("Hosting service"),
                                     required=True,
                                     initial=NO_HOSTING_SERVICE_ID)

    hosting_account = forms.ModelChoiceField(
        label=_('Account'),
        required=True,
        empty_label=_('<Link a new account>'),
        help_text=_("Link this repository to an account on the hosting "
                    "service. This username may be used as part of the "
                    "repository URL, depending on the hosting service and "
                    "plan."),
        queryset=HostingServiceAccount.objects.none())

    hosting_account_username = forms.CharField(
        label=_('Account username'),
        required=True,
        widget=forms.TextInput(attrs={
            'size': 30,
            'autocomplete': 'off'
        }))

    hosting_account_password = forms.CharField(
        label=_('Account password'),
        required=True,
        widget=forms.PasswordInput(attrs={
            'size': 30,
            'autocomplete': 'off'
        }))

    # Repository Information fields
    tool = forms.ModelChoiceField(label=_("Repository type"),
                                  required=True,
                                  empty_label=None,
                                  queryset=Tool.objects.all())

    repository_plan = forms.ChoiceField(
        label=_('Repository plan'),
        required=True,
        help_text=_('The plan for your repository on this hosting service. '
                    'This must match what is set for your repository.'))

    # Bug Tracker fields
    bug_tracker_use_hosting = forms.BooleanField(
        label=_("Use hosting service's bug tracker"),
        initial=False,
        required=False)

    bug_tracker_type = forms.ChoiceField(label=_("Type"),
                                         required=True,
                                         initial=NO_BUG_TRACKER_ID)

    bug_tracker_plan = forms.ChoiceField(label=_('Bug tracker plan'),
                                         required=True)

    bug_tracker_hosting_account_username = forms.CharField(
        label=_('Account username'),
        required=True,
        widget=forms.TextInput(attrs={
            'size': 30,
            'autocomplete': 'off'
        }))

    bug_tracker = forms.CharField(
        label=_("Bug tracker URL"),
        max_length=256,
        required=False,
        widget=forms.TextInput(attrs={'size': '60'}),
        help_text=_("The optional path to the bug tracker for this "
                    "repository."))

    def __init__(self, *args, **kwargs):
        self.local_site_name = kwargs.pop('local_site_name', None)

        super(RepositoryForm, self).__init__(*args, **kwargs)

        self.hostkeyerror = None
        self.certerror = None
        self.userkeyerror = None
        self.hosting_account_linked = False
        self.local_site = None
        self.repository_forms = {}
        self.bug_tracker_forms = {}
        self.hosting_service_info = {}
        self.validate_repository = True

        # Determine the local_site that will be associated with any
        # repository coming from this form.
        #
        # We're careful to disregard any local_sites that are specified
        # from the form data. The caller needs to pass in a local_site_name
        # to ensure that it will be used.
        if self.local_site_name:
            self.local_site = LocalSite.objects.get(name=self.local_site_name)
        elif self.instance and self.instance.local_site:
            self.local_site = self.instance.local_site
            self.local_site_name = self.local_site.name
        elif self.fields['local_site'].initial:
            self.local_site = self.fields['local_site'].initial
            self.local_site_name = self.local_site.name

        # Grab the entire list of HostingServiceAccounts that can be
        # used by this form. When the form is actually being used by the
        # user, the listed accounts will consist only of the ones available
        # for the selected hosting service.
        hosting_accounts = HostingServiceAccount.objects.accessible(
            local_site=self.local_site)
        self.fields['hosting_account'].queryset = hosting_accounts

        # Standard forms don't support 'instance', so don't pass it through
        # to any created hosting service forms.
        if 'instance' in kwargs:
            kwargs.pop('instance')

        # Load the list of repository forms and hosting services.
        hosting_service_choices = []
        bug_tracker_choices = []

        for hosting_service_id, hosting_service in get_hosting_services():
            if hosting_service.supports_repositories:
                hosting_service_choices.append(
                    (hosting_service_id, hosting_service.name))

            if hosting_service.supports_bug_trackers:
                bug_tracker_choices.append(
                    (hosting_service_id, hosting_service.name))

            self.bug_tracker_forms[hosting_service_id] = {}
            self.repository_forms[hosting_service_id] = {}
            self.hosting_service_info[hosting_service_id] = {
                'scmtools':
                hosting_service.supported_scmtools,
                'plans': [],
                'planInfo': {},
                'needs_authorization':
                hosting_service.needs_authorization,
                'supports_bug_trackers':
                hosting_service.supports_bug_trackers,
                'accounts': [{
                    'pk': account.pk,
                    'username': account.username,
                    'is_authorized': account.is_authorized,
                } for account in hosting_accounts
                             if account.service_name == hosting_service_id],
            }

            try:
                if hosting_service.plans:
                    for type_id, info in hosting_service.plans:
                        form = info.get('form', None)

                        if form:
                            self._load_hosting_service(hosting_service_id,
                                                       hosting_service,
                                                       type_id, info['name'],
                                                       form, *args, **kwargs)
                elif hosting_service.form:
                    self._load_hosting_service(hosting_service_id,
                                               hosting_service,
                                               self.DEFAULT_PLAN_ID,
                                               self.DEFAULT_PLAN_NAME,
                                               hosting_service.form, *args,
                                               **kwargs)
            except Exception, e:
                logging.error('Error loading hosting service %s: %s' %
                              (hosting_service_id, e),
                              exc_info=1)

        # Build the list of hosting service choices, sorted, with
        # "None" being first.
        hosting_service_choices.sort(key=lambda x: x[1])
        hosting_service_choices.insert(
            0, (self.NO_HOSTING_SERVICE_ID, self.NO_HOSTING_SERVICE_NAME))
        self.fields['hosting_type'].choices = hosting_service_choices

        # Now do the same for bug trackers, but have separate None and Custom
        # entries.
        bug_tracker_choices.sort(key=lambda x: x[1])
        bug_tracker_choices.insert(
            0, (self.NO_BUG_TRACKER_ID, self.NO_BUG_TRACKER_NAME))
        bug_tracker_choices.insert(
            1, (self.CUSTOM_BUG_TRACKER_ID, self.CUSTOM_BUG_TRACKER_NAME))
        self.fields['bug_tracker_type'].choices = bug_tracker_choices

        # Get the current SSH public key that would be used for repositories,
        # if one has been created.
        self.public_key = \
            sshutils.get_public_key(sshutils.get_user_key(self.local_site_name))

        if self.instance:
            self._populate_hosting_service_fields()
            self._populate_bug_tracker_fields()
예제 #8
0
파일: rbssh.py 프로젝트: nzhuk/reviewboard
def main():
    if DEBUG:
        pid = os.getpid()
        log_filename = 'rbssh-%s.log' % pid

        if DEBUG_LOGDIR:
            log_path = os.path.join(DEBUG_LOGDIR, log_filename)
        else:
            log_path = log_filename

        logging.basicConfig(level=logging.DEBUG,
                            format='%(asctime)s %(name)-18s %(levelname)-8s '
                            '%(message)s',
                            datefmt='%m-%d %H:%M',
                            filename=log_path,
                            filemode='w')

        logging.debug('%s' % sys.argv)
        logging.debug('PID %s' % pid)

    ch = logging.StreamHandler()
    ch.setLevel(logging.INFO)
    ch.setFormatter(logging.Formatter('%(message)s'))
    ch.addFilter(logging.Filter('root'))
    logging.getLogger('').addHandler(ch)

    path, command = parse_options(sys.argv[1:])

    if '://' not in path:
        path = 'ssh://' + path

    username, hostname = SCMTool.get_auth_from_uri(path, options.username)

    if username is None:
        username = getpass.getuser()

    logging.debug('!!! %s, %s, %s' % (hostname, username, command))

    client = sshutils.get_ssh_client(options.local_site_name)
    client.set_missing_host_key_policy(paramiko.WarningPolicy())

    attempts = 0
    password = None

    key = sshutils.get_user_key(options.local_site_name)

    while True:
        try:
            client.connect(hostname,
                           username=username,
                           password=password,
                           pkey=key,
                           allow_agent=options.allow_agent)
            break
        except paramiko.AuthenticationException, e:
            if attempts == 3 or not sys.stdin.isatty():
                logging.error('Too many authentication failures for %s' %
                              username)
                sys.exit(1)

            attempts += 1
            password = getpass.getpass("%s@%s's password: " %
                                       (username, hostname))
        except paramiko.SSHException, e:
            logging.error('Error connecting to server: %s' % e)
            sys.exit(1)