Skip to content

Commit

Permalink
onepassword - Get first found config file (#4640)
Browse files Browse the repository at this point in the history
* Get first found configuration file

There are three valid places to get the configuration.

https://developer.1password.com/docs/cli/about-biometric-unlock#remove-old-account-information

* Use common config class

* Add changelog fragment

* Explicitly use new style classes for Python 2.7 compatibility

This shouldn’t matter for lookups, but does matter for module_utils
and modules since Python 2.7 is still supported on the managed node.

* Update changelogs/fragments/4065-onepassword-config.yml

Co-authored-by: Felix Fontein <[email protected]>
(cherry picked from commit 9e1af2d)
  • Loading branch information
samdoran authored and patchback[bot] committed May 9, 2022
1 parent 53f9958 commit f83acdc
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 7 deletions.
2 changes: 2 additions & 0 deletions changelogs/fragments/4065-onepassword-config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
bugfixes:
- onepassword - search all valid configuration locations and use the first found (https://github.com/ansible-collections/community.general/pull/4640).
13 changes: 8 additions & 5 deletions plugins/lookup/onepassword.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@
description: Vault containing the item to retrieve (case-insensitive). If absent will search all vaults.
notes:
- This lookup will use an existing 1Password session if one exists. If not, and you have already
performed an initial sign in (meaning C(~/.op/config exists)), then only the C(master_password) is required.
You may optionally specify C(subdomain) in this scenario, otherwise the last used subdomain will be used by C(op).
performed an initial sign in (meaning C(~/.op/config), C(~/.config/op/config) or C(~/.config/.op/config) exists), then only the
C(master_password) is required. You may optionally specify C(subdomain) in this scenario, otherwise the last used subdomain will be used by C(op).
- This lookup can perform an initial login by providing C(subdomain), C(username), C(secret_key), and C(master_password).
- Due to the B(very) sensitive nature of these credentials, it is B(highly) recommended that you only pass in the minimal credentials
needed at any given time. Also, store these credentials in an Ansible Vault using a key that is equal to or greater in strength
Expand Down Expand Up @@ -105,12 +105,12 @@
from ansible.errors import AnsibleLookupError
from ansible.module_utils.common.text.converters import to_bytes, to_text

from ansible_collections.community.general.plugins.module_utils.onepassword import OnePasswordConfig

class OnePass(object):

class OnePass(object):
def __init__(self, path='op'):
self.cli_path = path
self.config_file_path = os.path.expanduser('~/.op/config')
self.logged_in = False
self.token = None
self.subdomain = None
Expand All @@ -119,9 +119,11 @@ def __init__(self, path='op'):
self.secret_key = None
self.master_password = None

self._config = OnePasswordConfig()

def get_token(self):
# If the config file exists, assume an initial signin has taken place and try basic sign in
if os.path.isfile(self.config_file_path):
if os.path.isfile(self._config.config_file_path):

if not self.master_password:
raise AnsibleLookupError('Unable to sign in to 1Password. master_password is required.')
Expand Down Expand Up @@ -281,4 +283,5 @@ def run(self, terms, variables=None, **kwargs):
values = []
for term in terms:
values.append(op.get_field(term, field, section, vault))

return values
29 changes: 29 additions & 0 deletions plugins/module_utils/onepassword.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
# Simplified BSD License (see licenses/simplified_bsd.txt or https://opensource.org/licenses/BSD-2-Clause)

from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

import os


class OnePasswordConfig(object):
_config_file_paths = (
"~/.op/config",
"~/.config/op/config",
"~/.config/.op/config",
)

def __init__(self):
self._config_file_path = ""

@property
def config_file_path(self):
if self._config_file_path:
return self._config_file_path

for path in self._config_file_paths:
realpath = os.path.expanduser(path)
if os.path.exists(realpath):
self._config_file_path = realpath
return self._config_file_path
7 changes: 5 additions & 2 deletions plugins/modules/identity/onepassword_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@
from ansible.module_utils.common.text.converters import to_bytes, to_native
from ansible.module_utils.basic import AnsibleModule

from ansible_collections.community.general.plugins.module_utils.onepassword import OnePasswordConfig


class AnsibleModuleError(Exception):
def __init__(self, results):
Expand All @@ -179,14 +181,15 @@ class OnePasswordInfo(object):

def __init__(self):
self.cli_path = module.params.get('cli_path')
self.config_file_path = '~/.op/config'
self.auto_login = module.params.get('auto_login')
self.logged_in = False
self.token = None

terms = module.params.get('search_terms')
self.terms = self.parse_search_terms(terms)

self._config = OnePasswordConfig()

def _run(self, args, expected_rc=0, command_input=None, ignore_errors=False):
if self.token:
# Adds the session token to all commands if we're logged in.
Expand Down Expand Up @@ -299,7 +302,7 @@ def full_login(self):

def get_token(self):
# If the config file exists, assume an initial signin has taken place and try basic sign in
if os.path.isfile(self.config_file_path):
if os.path.isfile(self._config.config_file_path):

if self.auto_login is not None:

Expand Down

0 comments on commit f83acdc

Please sign in to comment.