Я знаю, что это старый вопрос, но я сейчас пытаюсь разработать виджет Dashboard, и столкнулся с тем же вопросом. Я поделюсь тем, что я узнал.
Прежде всего, хорошая новость в том, что вам не обязательно нужен плагин; все, что вам нужно, это предоставить вашему виджету доступ к командной строке.
OS X на самом деле включает в себя утилиту командной строки под названием security
, которая позволяет вам выполнять любые действия, связанные с цепочкой для ключей. Вы можете прочитать об этом, введя info security
в Терминале. Я еще не дошел до того, что смог проверить это из самого виджета (только в терминале), но из того, что я почерпнул, я думаю, это то, что вы делаете. Любой, кто знает лучше, , пожалуйста, , не стесняйтесь вносить изменения.
Хранение пароля в связке ключей
Предполагая, что username
и password
являются переменными, которые мы уже настроили:
widget.system("/usr/bin/security add-generic-password -a \""+username+"\" -s \"My Awesome Widget\" -w \""+password+"\" -T \"/usr/bin/security\" -U);
Распределение команд
/usr/bin/security
: метод widget.system()
требует полного пути к команде, которую мы выполняем. Эта конкретная команда находится в /usr/bin.
add-generic-password
: одна из многих команд security
. Существуют и другие виды элементов паролей, которые можно добавить в связку ключей, например, интернет-пароли, но я думаю, что универсальный тип лучше всего подходит для этого случая.
-a
: «имя учетной записи» или имя пользователя, которое соответствует паролю, который мы хотим сохранить. Брелок, вероятно, не будет основным местом, в котором вы сохраняете имя пользователя, так как оно понадобится нам для просмотра пароля позже, но если у пользователя открыто несколько экземпляров нашего виджета, каждый с другим пользователем / pass combo, включая имя пользователя, позволит нам специально найти пароль , который , когда придет время. Кавычки не являются строго необходимыми, но вы должны включать их, если имена пользователей для вашего виджета могут содержать пробелы.
-s
: «имя службы» для создаваемого нами элемента цепочки для ключей - иными словами, подробное, понятное человеку имя. Имя вашего виджета, вероятно, будет наиболее подходящим здесь.
-w
: пароль. Опять же, рекомендуется использовать кавычки, если ваши пароли могут содержать пробелы.
-T
: путь (и) к любому приложению (ям), которому разрешен доступ к этому элементу цепочки для ключей без вопросов. Без этого флага любая попытка восстановить пароль позже приведет к тому, что пользователь увидит, что один из тех «защитников» хочет использовать ваши конфиденциальные данные, хранящиеся в «My Awesome Widget» в вашей цепочке для ключей », и есть вероятность, что они не будут знать, что это значит, и это будет пугать их. Здесь я предполагаю, что поскольку виджет использует security
для запроса пароля, security
(а не, скажем, DashboardClient
) - это программа, для которой требуется предоставить доступ.
-U
: говорит security
обновить этот элемент цепочки для ключей, если он уже существует, а не просто потерпеть неудачу.
Получение пароля обратно из цепочки для ключей
Это включает в себя дополнительный шаг после получения пароля, но он все равно не должен быть слишком плохим.
var messyPassword = widget.system("/usr/bin/security 2>&1 >/dev/null find-generic-password -ga \""+username+"\" -s \"My Awesome Widget\"").outputString;
scrubPassword(messyPassword);
Команда разбивки
/usr/bin/security
: снова привет, офицер. Какая у нас погода, а?
2>&1 >/dev/null
: вывод find-generic-password
включает пачки crap потенциально потенциально полезную информацию, которая нам не нужна в этом случае. К счастью, он выводит пароль отдельно от всего этого, поэтому его можно перехватить самостоятельно, используя этот дополнительный бит. (Спасибо Аллану Одгаарду из Macromates Ltd. за его сообщение в блоге, подробно описывающее этот трюк .)
find-generic-password
: аналог add-generic-password
. Следующие аргументы используются в качестве критериев поиска.
-g
: говорит security
на самом деле, вы знаете, вывести пароль. В противном случае, я думаю, это просто ... признает тот факт, что элемент существует, а затем выходит?
-a
: имя пользователя, которое идет вместе с паролем, который мы хотим получить.
-s
: удобочитаемое имя, которое мы выбрали для виджета, когда писали команду add-generic-password
.
Подождите, а что такое scrubPassword()
?
Хорошо, подвох в том, что даже после того, как все остальное было удалено из ответа security
, возвращаемая вами строка не просто пароль. Это больше похоже на:
password: "nobodywilleverguessthis"
Насколько я знаю, мы должны использовать регулярные выражения, чтобы взломать эту строку и добраться до блестящей жемчужины паролей внутри. Я не знаю как вы, но регулярные выражения - это для меня кошмарные кошмары, поэтому я очень обрадовался, обнаружив txt2re , онлайн-инструмент, который позволяет вам перепроектировать регулярные выражения из Строка, которой вы хотите манипулировать. Вы можете буквально просто вставить вывод security
в txt2re и получить фрагмент JavaScript, который извлечет из него пароль.
Примечание:
widget.system()
также позволяет использовать функцию-обработчик в качестве второго аргумента, так что вполне возможно, что вы могли бы вызвать вашу функцию scrubPassword()
прямо здесь и пропустить всю часть с помощью переменной messyPassword
. Как я уже сказал, я до сих пор пытался звонить security
из Терминала, поэтому у меня нет опыта работы с widget.system()
.
Снятие пароля с брелка
Когда экземпляр виджета закрыт, мы, вероятно, не хотим, чтобы связанный пароль загромождал цепочку для ключей пользователя, поэтому мы ответим на все вопросы и подберем мусор. Эта команда немного проще, чем две другие команды, поскольку нам не нужно ничего создавать или получать что-либо в ответ.
widget.system("/usr/bin/security delete-generic-password -a \""+username+"\" -s \"My Awesome Widget\"");
Распределение команд
/usr/bin/security
: обычный.
delete-generic-password
: делает то, что написано на коробке, используя следующие аргументы в качестве критериев поиска (или, скорее, поиска и уничтожения).
-a
: имя пользователя, соответствующее паролю, который вы хотите удалить.
-s
: удобочитаемое имя виджета.
Надеюсь, это поможет!