mirror of https://github.com/bqv/weechat-xmpp
Registration
parent
5454169285
commit
4fde364512
@ -0,0 +1,6 @@
|
|||||||
|
[submodule "libwebsockets"]
|
||||||
|
path = libwebsockets
|
||||||
|
url = https://github.com/warmcat/libwebsockets
|
||||||
|
[submodule "json-c"]
|
||||||
|
path = json-c
|
||||||
|
url = https://github.com/json-c/json-c
|
@ -0,0 +1,42 @@
|
|||||||
|
CC=clang
|
||||||
|
CXX=clang++
|
||||||
|
RM=rm -f
|
||||||
|
CFLAGS=-fPIC -std=gnu99 -g -Wall -Wextra -Werror-implicit-function-declaration -I libwebsockets/include -I json-c
|
||||||
|
LDFLAGS=-shared -g
|
||||||
|
LDLIBS=-lssl
|
||||||
|
|
||||||
|
SRCS=slack.c \
|
||||||
|
slack-config.c \
|
||||||
|
slack-command.c \
|
||||||
|
slack-oauth.c \
|
||||||
|
slack-workspace.c
|
||||||
|
OBJS=$(subst .c,.o,$(SRCS)) libwebsockets/lib/libwebsockets.a json-c/libjson-c.a
|
||||||
|
|
||||||
|
all: weechat-slack
|
||||||
|
|
||||||
|
weechat-slack: $(OBJS)
|
||||||
|
$(CC) $(LDFLAGS) -o slack.so $(OBJS) $(LDLIBS)
|
||||||
|
|
||||||
|
libwebsockets/lib/libwebsockets.a:
|
||||||
|
cd libwebsockets && cmake -DLWS_STATIC_PIC=ON -DLWS_WITH_SHARED=OFF -DLWS_WITHOUT_TESTAPPS=ON -DLWS_WITH_LIBEV=OFF -DLWS_WITH_LIBUV=OFF -DLWS_WITH_LIBEVENT=OFF .
|
||||||
|
$(MAKE) -C libwebsockets
|
||||||
|
|
||||||
|
json-c/libjson-c.a:
|
||||||
|
cd json-c && cmake -DCMAKE_C_FLAGS=-fPIC .
|
||||||
|
$(MAKE) -C json-c json-c-static
|
||||||
|
|
||||||
|
depend: .depend
|
||||||
|
|
||||||
|
.depend: $(SRCS)
|
||||||
|
$(RM) ./.depend
|
||||||
|
$(CC) $(CFLAGS) -MM $^>>./.depend;
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(RM) $(OBJS)
|
||||||
|
$(MAKE) -C libwebsockets clean
|
||||||
|
$(MAKE) -C json-c clean
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
$(RM) *~ .depend
|
||||||
|
|
||||||
|
include .depend
|
@ -0,0 +1 @@
|
|||||||
|
Subproject commit c75ebe8973b1f03d3b3ef429c114e8d2192dc0c0
|
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 91a47f4fab4d74f49a341ce22954a563f6544446
|
@ -0,0 +1,186 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "weechat-plugin.h"
|
||||||
|
#include "slack.h"
|
||||||
|
#include "slack-command.h"
|
||||||
|
#include "slack-oauth.h"
|
||||||
|
#include "slack-workspace.h"
|
||||||
|
|
||||||
|
void slack_command_display_workspace(struct t_slack_workspace *workspace)
|
||||||
|
{
|
||||||
|
int num_channels, num_pv;
|
||||||
|
|
||||||
|
if (workspace->is_connected)
|
||||||
|
{
|
||||||
|
num_channels = 0;//slack_workspace_get_channel_count(workspace);
|
||||||
|
num_pv = 0;//slack_workspace_get_pv_count(workspace);
|
||||||
|
weechat_printf(
|
||||||
|
NULL,
|
||||||
|
" %s %s%s %s[%s%s%s]%s, %d %s, %d pv",
|
||||||
|
(workspace->is_connected) ? "*" : " ",
|
||||||
|
weechat_color("chat_workspace"),
|
||||||
|
workspace->name,
|
||||||
|
weechat_color("chat_delimiters"),
|
||||||
|
weechat_color("reset"),
|
||||||
|
(workspace->is_connected) ?
|
||||||
|
_("connected") : _("not connected"),
|
||||||
|
weechat_color("chat_delimiters"),
|
||||||
|
weechat_color("reset"),
|
||||||
|
num_channels,
|
||||||
|
NG_("channel", "channels", num_channels),
|
||||||
|
num_pv);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
weechat_printf(
|
||||||
|
NULL,
|
||||||
|
" %s%s%s",
|
||||||
|
weechat_color("chat_workspace"),
|
||||||
|
workspace->name,
|
||||||
|
weechat_color("reset"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void slack_command_workspace_list(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int i, one_workspace_found;
|
||||||
|
struct t_slack_workspace *ptr_workspace2;
|
||||||
|
char *workspace_name = NULL;
|
||||||
|
|
||||||
|
for (i = 2; i < argc; i++)
|
||||||
|
{
|
||||||
|
if (!workspace_name)
|
||||||
|
workspace_name = argv[i];
|
||||||
|
}
|
||||||
|
if (!workspace_name)
|
||||||
|
{
|
||||||
|
if (slack_workspaces)
|
||||||
|
{
|
||||||
|
weechat_printf(NULL, "");
|
||||||
|
weechat_printf(NULL, _("All workspaces:"));
|
||||||
|
for (ptr_workspace2 = slack_workspaces; ptr_workspace2;
|
||||||
|
ptr_workspace2 = ptr_workspace2->next_workspace)
|
||||||
|
{
|
||||||
|
slack_command_display_workspace(ptr_workspace2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
weechat_printf(NULL, _("No workspace"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
one_workspace_found = 0;
|
||||||
|
for (ptr_workspace2 = slack_workspaces; ptr_workspace2;
|
||||||
|
ptr_workspace2 = ptr_workspace2->next_workspace)
|
||||||
|
{
|
||||||
|
if (weechat_strcasestr(ptr_workspace2->name, workspace_name))
|
||||||
|
{
|
||||||
|
if (!one_workspace_found)
|
||||||
|
{
|
||||||
|
weechat_printf(NULL, "");
|
||||||
|
weechat_printf(NULL,
|
||||||
|
_("Servers with \"%s\":"),
|
||||||
|
workspace_name);
|
||||||
|
}
|
||||||
|
one_workspace_found = 1;
|
||||||
|
slack_command_display_workspace(ptr_workspace2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!one_workspace_found)
|
||||||
|
weechat_printf(NULL,
|
||||||
|
_("No workspace found with \"%s\""),
|
||||||
|
workspace_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void slack_command_add_workspace(char *token)
|
||||||
|
{
|
||||||
|
free(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
void slack_command_workspace_register(int argc, char **argv)
|
||||||
|
{
|
||||||
|
char *code;
|
||||||
|
|
||||||
|
if (argc > 2)
|
||||||
|
{
|
||||||
|
code = argv[2];
|
||||||
|
|
||||||
|
if (weechat_strncasecmp("xoxp", code, 4) == 0)
|
||||||
|
{
|
||||||
|
slack_command_add_workspace(strdup(code));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
slack_oauth_request_token(code, &slack_command_add_workspace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
weechat_printf(NULL,
|
||||||
|
_("\n#### Retrieving a Slack token via OAUTH ####\n"
|
||||||
|
"1) Paste this into a browser: https://slack.com/oauth/authorize?client_id=%s&scope=client\n"
|
||||||
|
"2) Select the team you wish to access from wee-slack in your browser.\n"
|
||||||
|
"3) Click \"Authorize\" in the browser **IMPORTANT: the redirect will fail, this is expected**\n"
|
||||||
|
"4) Copy the \"code\" portion of the URL to your clipboard\n"
|
||||||
|
"5) Return to weechat and run `/slack register [code]`\n"),
|
||||||
|
SLACK_CLIENT_ID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void slack_command_workspace_delete(int argc, char **argv)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int slack_command_slack(const void *pointer, void *data,
|
||||||
|
struct t_gui_buffer *buffer, int argc,
|
||||||
|
char **argv, char **argv_eol)
|
||||||
|
{
|
||||||
|
/* make C compiler happy */
|
||||||
|
(void) pointer;
|
||||||
|
(void) data;
|
||||||
|
(void) buffer;
|
||||||
|
|
||||||
|
if (argc > 1)
|
||||||
|
{
|
||||||
|
if (weechat_strcasecmp(argv[1], "list") == 0)
|
||||||
|
{
|
||||||
|
slack_command_workspace_list(argc, argv);
|
||||||
|
return WEECHAT_RC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weechat_strcasecmp(argv[1], "register") == 0)
|
||||||
|
{
|
||||||
|
slack_command_workspace_register(argc, argv);
|
||||||
|
return WEECHAT_RC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (weechat_strcasecmp(argv[1], "delete") == 0)
|
||||||
|
{
|
||||||
|
slack_command_workspace_delete(argc, argv);
|
||||||
|
return WEECHAT_RC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
WEECHAT_COMMAND_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return WEECHAT_RC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void slack_command_init()
|
||||||
|
{
|
||||||
|
weechat_hook_command(
|
||||||
|
"slack",
|
||||||
|
N_("slack control"),
|
||||||
|
N_("list"
|
||||||
|
" || register [token]"
|
||||||
|
" || delete <workspace>"),
|
||||||
|
N_(" list: list workspaces\n"
|
||||||
|
"register: add a slack workspace\n"
|
||||||
|
" delete: delete a slack workspace\n"),
|
||||||
|
"list"
|
||||||
|
" || register %(slack_token)"
|
||||||
|
" || delete %(slack_workspace)",
|
||||||
|
&slack_command_slack, NULL, NULL);
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _SLACK_COMMAND_H_
|
||||||
|
#define _SLACK_COMMAND_H_
|
||||||
|
|
||||||
|
extern void slack_command_init();
|
||||||
|
|
||||||
|
#endif /*SLACK_COMMAND_H*/
|
@ -0,0 +1,285 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "weechat-plugin.h"
|
||||||
|
#include "slack.h"
|
||||||
|
#include "slack-config.h"
|
||||||
|
#include "slack-workspace.h"
|
||||||
|
|
||||||
|
struct t_config_file *slack_config_file;
|
||||||
|
|
||||||
|
struct t_config_section *slack_config_section_workspace_default;
|
||||||
|
struct t_config_section *slack_config_section_workspace;
|
||||||
|
|
||||||
|
struct t_config_option *slack_config_workspace_default[SLACK_WORKSPACE_NUM_OPTIONS];
|
||||||
|
|
||||||
|
int slack_config_workspace_check_value_cb(const void *pointer, void *data,
|
||||||
|
struct t_config_option *option,
|
||||||
|
const char *value)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void slack_config_workspace_change_cb(const void *pointer, void *data,
|
||||||
|
struct t_config_option *option)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void slack_config_workspace_default_change_cb(const void *pointer, void *data,
|
||||||
|
struct t_config_option *option)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
struct t_config_option *
|
||||||
|
slack_config_workspace_new_option (struct t_config_file *config_file,
|
||||||
|
struct t_config_section *section,
|
||||||
|
int index_option,
|
||||||
|
const char *option_name,
|
||||||
|
const char *default_value,
|
||||||
|
const char *value,
|
||||||
|
int null_value_allowed,
|
||||||
|
int (*callback_check_value)(const void *pointer,
|
||||||
|
void *data,
|
||||||
|
struct t_config_option *option,
|
||||||
|
const char *value),
|
||||||
|
const void *callback_check_value_pointer,
|
||||||
|
void *callback_check_value_data,
|
||||||
|
void (*callback_change)(const void *pointer,
|
||||||
|
void *data,
|
||||||
|
struct t_config_option *option),
|
||||||
|
const void *callback_change_pointer,
|
||||||
|
void *callback_change_data)
|
||||||
|
{
|
||||||
|
struct t_config_option *new_option;
|
||||||
|
|
||||||
|
new_option = NULL;
|
||||||
|
|
||||||
|
switch (index_option)
|
||||||
|
{
|
||||||
|
case SLACK_WORKSPACE_OPTION_TOKEN:
|
||||||
|
new_option = weechat_config_new_option (
|
||||||
|
config_file, section,
|
||||||
|
option_name, "string",
|
||||||
|
N_("slack api token"),
|
||||||
|
NULL, 0, 0,
|
||||||
|
default_value, value,
|
||||||
|
null_value_allowed,
|
||||||
|
callback_check_value,
|
||||||
|
callback_check_value_pointer,
|
||||||
|
callback_check_value_data,
|
||||||
|
callback_change,
|
||||||
|
callback_change_pointer,
|
||||||
|
callback_change_data,
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
break;
|
||||||
|
case SLACK_WORKSPACE_NUM_OPTIONS:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new_option;
|
||||||
|
}
|
||||||
|
|
||||||
|
void slack_config_workspace_create_default_options(struct t_config_section *section)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < SLACK_WORKSPACE_NUM_OPTIONS; i++)
|
||||||
|
{
|
||||||
|
slack_config_workspace_default[i] = slack_config_workspace_new_option(
|
||||||
|
slack_config_file,
|
||||||
|
section,
|
||||||
|
i,
|
||||||
|
slack_workspace_options[i][0],
|
||||||
|
slack_workspace_options[i][1],
|
||||||
|
slack_workspace_options[i][1],
|
||||||
|
0,
|
||||||
|
&slack_config_workspace_check_value_cb,
|
||||||
|
slack_workspace_options[i][0],
|
||||||
|
NULL,
|
||||||
|
&slack_config_workspace_default_change_cb,
|
||||||
|
slack_workspace_options[i][0],
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int slack_config_reload (const void *pointer, void *data,
|
||||||
|
struct t_config_file *config_file)
|
||||||
|
{
|
||||||
|
/* make C compiler happy */
|
||||||
|
(void) pointer;
|
||||||
|
(void) data;
|
||||||
|
|
||||||
|
//weechat_config_section_free_options(slack_config_section_workspace_default);
|
||||||
|
//weechat_config_section_free_options(slack_config_section_workspace);
|
||||||
|
//slack_workspace_free_all();
|
||||||
|
|
||||||
|
return weechat_config_reload(config_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int slack_config_workspace_read_cb (const void *pointer, void *data,
|
||||||
|
struct t_config_file *config_file,
|
||||||
|
struct t_config_section *section,
|
||||||
|
const char *option_name, const char *value)
|
||||||
|
{
|
||||||
|
struct t_slack_workspace *ptr_workspace;
|
||||||
|
int index_option, rc, i;
|
||||||
|
char *pos_option, *workspace_name;
|
||||||
|
|
||||||
|
/* make C compiler happy */
|
||||||
|
(void) pointer;
|
||||||
|
(void) data;
|
||||||
|
(void) config_file;
|
||||||
|
(void) section;
|
||||||
|
|
||||||
|
rc = WEECHAT_CONFIG_OPTION_SET_ERROR;
|
||||||
|
|
||||||
|
if (option_name)
|
||||||
|
{
|
||||||
|
pos_option = strrchr(option_name, '.');
|
||||||
|
if (pos_option)
|
||||||
|
{
|
||||||
|
workspace_name = weechat_strndup(option_name,
|
||||||
|
pos_option - option_name);
|
||||||
|
pos_option++;
|
||||||
|
if (workspace_name)
|
||||||
|
{
|
||||||
|
index_option = slack_workspace_search_option(pos_option);
|
||||||
|
if (index_option >= 0)
|
||||||
|
{
|
||||||
|
ptr_workspace = slack_workspace_search(workspace_name);
|
||||||
|
if (!ptr_workspace)
|
||||||
|
ptr_workspace = slack_workspace_alloc(workspace_name);
|
||||||
|
if (ptr_workspace)
|
||||||
|
{
|
||||||
|
if (ptr_workspace->reloading_from_config
|
||||||
|
&& !ptr_workspace->reloaded_from_config)
|
||||||
|
{
|
||||||
|
for (i = 0; i < SLACK_WORKSPACE_NUM_OPTIONS; i++)
|
||||||
|
{
|
||||||
|
weechat_config_option_set(
|
||||||
|
ptr_workspace->options[i], NULL, 1);
|
||||||
|
}
|
||||||
|
ptr_workspace->reloaded_from_config = 1;
|
||||||
|
}
|
||||||
|
rc = weechat_config_option_set(
|
||||||
|
ptr_workspace->options[index_option], value, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
weechat_printf(
|
||||||
|
NULL,
|
||||||
|
_("%s%s: error adding workspace \"%s\""),
|
||||||
|
weechat_prefix("error"), SLACK_PLUGIN_NAME,
|
||||||
|
workspace_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(workspace_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rc == WEECHAT_CONFIG_OPTION_SET_ERROR)
|
||||||
|
{
|
||||||
|
weechat_printf(
|
||||||
|
NULL,
|
||||||
|
_("%s%s: error creating workspace option \"%s\""),
|
||||||
|
weechat_prefix("error"), SLACK_PLUGIN_NAME, option_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int slack_config_workspace_write_cb (const void *pointer, void *data,
|
||||||
|
struct t_config_file *config_file,
|
||||||
|
const char *section_name)
|
||||||
|
{
|
||||||
|
struct t_slack_workspace *ptr_workspace;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* make C compiler happy */
|
||||||
|
(void) pointer;
|
||||||
|
(void) data;
|
||||||
|
|
||||||
|
if (!weechat_config_write_line(config_file, section_name, NULL))
|
||||||
|
return WEECHAT_CONFIG_WRITE_ERROR;
|
||||||
|
|
||||||
|
for (ptr_workspace = slack_workspaces; ptr_workspace;
|
||||||
|
ptr_workspace = ptr_workspace->next_workspace)
|
||||||
|
{
|
||||||
|
for (i = 0; i < SLACK_WORKSPACE_NUM_OPTIONS; i++)
|
||||||
|
{
|
||||||
|
if (!weechat_config_write_option(config_file,
|
||||||
|
ptr_workspace->options[i]))
|
||||||
|
return WEECHAT_CONFIG_WRITE_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return WEECHAT_CONFIG_WRITE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int slack_config_init()
|
||||||
|
{
|
||||||
|
struct t_config_section *ptr_section;
|
||||||
|
|
||||||
|
slack_config_file = weechat_config_new(SLACK_CONFIG_NAME,
|
||||||
|
&slack_config_reload, NULL, NULL);
|
||||||
|
|
||||||
|
if(!slack_config_file)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ptr_section = weechat_config_new_section(
|
||||||
|
slack_config_file, "workspace_default",
|
||||||
|
0, 0,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
|
||||||
|
if (!ptr_section)
|
||||||
|
{
|
||||||
|
weechat_config_free(slack_config_file);
|
||||||
|
slack_config_file = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
slack_config_section_workspace_default = ptr_section;
|
||||||
|
|
||||||
|
slack_config_workspace_create_default_options(ptr_section);
|
||||||
|
|
||||||
|
ptr_section = weechat_config_new_section(
|
||||||
|
slack_config_file, "workspace",
|
||||||
|
0, 0,
|
||||||
|
&slack_config_workspace_read_cb, NULL, NULL,
|
||||||
|
&slack_config_workspace_write_cb, NULL, NULL,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL,
|
||||||
|
NULL, NULL, NULL);
|
||||||
|
|
||||||
|
if (!ptr_section)
|
||||||
|
{
|
||||||
|
weechat_config_free(slack_config_file);
|
||||||
|
slack_config_file = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
slack_config_section_workspace = ptr_section;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int slack_config_read()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int slack_config_write()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void slack_config_free()
|
||||||
|
{
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
#ifndef _SLACK_CONFIG_H_
|
||||||
|
#define _SLACK_CONFIG_H_
|
||||||
|
|
||||||
|
#define SLACK_CONFIG_NAME "slack"
|
||||||
|
|
||||||
|
extern struct t_config_file *slack_config_file;
|
||||||
|
|
||||||
|
extern struct t_config_section *slack_config_section_workspace_default;
|
||||||
|
extern struct t_config_section *slack_config_section_workspace;
|
||||||
|
|
||||||
|
extern struct t_config_option *slack_config_workspace_default[];
|
||||||
|
|
||||||
|
int slack_config_workspace_check_value_cb(const void *pointer, void *data,
|
||||||
|
struct t_config_option *option,
|
||||||
|
const char *value);
|
||||||
|
|
||||||
|
void slack_config_workspace_change_cb(const void *pointer, void *data,
|
||||||
|
struct t_config_option *option);
|
||||||
|
|
||||||
|
struct t_config_option *slack_config_workspace_new_option (struct t_config_file *config_file,
|
||||||
|
struct t_config_section *section,
|
||||||
|
int index_option,
|
||||||
|
const char *option_name,
|
||||||
|
const char *default_value,
|
||||||
|
const char *value,
|
||||||
|
int null_value_allowed,
|
||||||
|
int (*callback_check_value)(const void *pointer,
|
||||||
|
void *data,
|
||||||
|
struct t_config_option *option,
|
||||||
|
const char *value),
|
||||||
|
const void *callback_check_value_pointer,
|
||||||
|
void *callback_check_value_data,
|
||||||
|
void (*callback_change)(const void *pointer,
|
||||||
|
void *data,
|
||||||
|
struct t_config_option *option),
|
||||||
|
const void *callback_change_pointer,
|
||||||
|
void *callback_change_data);
|
||||||
|
|
||||||
|
extern int slack_config_init();
|
||||||
|
extern int slack_config_read();
|
||||||
|
extern int slack_config_write();
|
||||||
|
extern void slack_config_free();
|
||||||
|
|
||||||
|
#endif /*SLACK_CONFIG_H*/
|
@ -0,0 +1,233 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <libwebsockets.h>
|
||||||
|
#include <json.h>
|
||||||
|
|
||||||
|
#include "weechat-plugin.h"
|
||||||
|
#include "slack.h"
|
||||||
|
#include "slack-oauth.h"
|
||||||
|
|
||||||
|
static void (*weechat_callback)(char *token);
|
||||||
|
|
||||||
|
static const char *const endpoint = "/api/oauth.access?"
|
||||||
|
"client_id=%s&client_secret=%s&code=%s";
|
||||||
|
static char *uri;
|
||||||
|
|
||||||
|
static int n = 0;
|
||||||
|
static struct lws *client_wsi = NULL;
|
||||||
|
static struct lws_context *context = NULL;
|
||||||
|
|
||||||
|
static struct t_hook *slack_oauth_hook_timer = NULL;
|
||||||
|
|
||||||
|
static int json_valid(json_object *object)
|
||||||
|
{
|
||||||
|
if (!object)
|
||||||
|
{
|
||||||
|
weechat_printf(
|
||||||
|
NULL,
|
||||||
|
_("%s%s: Error retrieving token: unexpected response from server"),
|
||||||
|
weechat_prefix("error"), SLACK_PLUGIN_NAME);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int callback_http(struct lws *wsi, enum lws_callback_reasons reason,
|
||||||
|
void *user, void *in, size_t len)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
|
||||||
|
switch (reason)
|
||||||
|
{
|
||||||
|
/* because we are protocols[0] ... */
|
||||||
|
case LWS_CALLBACK_CLIENT_CONNECTION_ERROR:
|
||||||
|
weechat_printf(
|
||||||
|
NULL,
|
||||||
|
_("%s%s: error connecting to slack: %s"),
|
||||||
|
weechat_prefix("error"), SLACK_PLUGIN_NAME,
|
||||||
|
in ? (char *)in : "(null)");
|
||||||
|
client_wsi = NULL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP:
|
||||||
|
status = lws_http_client_http_response(wsi);
|
||||||
|
weechat_printf(
|
||||||
|
NULL,
|
||||||
|
_("%s%s: Retrieving token... (%d)"),
|
||||||
|
weechat_prefix("network"), SLACK_PLUGIN_NAME,
|
||||||
|
status);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* chunks of chunked content, with header removed */
|
||||||
|
case LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ:
|
||||||
|
{
|
||||||
|
char *json_string = weechat_strndup(in, (int)len);
|
||||||
|
json_object *response, *ok, *error, *token;
|
||||||
|
|
||||||
|
weechat_printf(
|
||||||
|
NULL,
|
||||||
|
_("%s%s: Got token: %s"),
|
||||||
|
weechat_prefix("network"), SLACK_PLUGIN_NAME,
|
||||||
|
json_string);
|
||||||
|
|
||||||
|
response = json_tokener_parse(json_string);
|
||||||
|
ok = json_object_object_get(response, "ok");
|
||||||
|
if (!json_valid(ok))
|
||||||
|
{
|
||||||
|
json_object_put(response);
|
||||||
|
free(json_string);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(json_object_get_boolean(ok))
|
||||||
|
{
|
||||||
|
token = json_object_object_get(response, "access_token");
|
||||||
|
if (!json_valid(token))
|
||||||
|
{
|
||||||
|
json_object_put(response);
|
||||||
|
free(json_string);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
weechat_printf(
|
||||||
|
NULL,
|
||||||
|
_("%s%s: Retrieved token: %s"),
|
||||||
|
weechat_prefix("network"), SLACK_PLUGIN_NAME,
|
||||||
|
json_object_get_string(token));
|
||||||
|
|
||||||
|
weechat_callback(strdup(json_object_get_string(token)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error = json_object_object_get(response, "error");
|
||||||
|
if (!json_valid(error))
|
||||||
|
{
|
||||||
|
json_object_put(response);
|
||||||
|
free(json_string);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
weechat_printf(
|
||||||
|
NULL,
|
||||||
|
_("%s%s: Failed to retrieve token: %s"),
|
||||||
|
weechat_prefix("error"), SLACK_PLUGIN_NAME,
|
||||||
|
json_object_get_string(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
json_object_put(response);
|
||||||
|
free(json_string);
|
||||||
|
}
|
||||||
|
return 0; /* don't passthru */
|
||||||
|
|
||||||
|
/* uninterpreted http content */
|
||||||
|
case LWS_CALLBACK_RECEIVE_CLIENT_HTTP:
|
||||||
|
{
|
||||||
|
char buffer[1024 + LWS_PRE];
|
||||||
|
char *px = buffer + LWS_PRE;
|
||||||
|
int lenx = sizeof(buffer) - LWS_PRE;
|
||||||
|
|
||||||
|
if (lws_http_client_read(wsi, &px, &lenx) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0; /* don't passthru */
|
||||||
|
|
||||||
|
case LWS_CALLBACK_COMPLETED_CLIENT_HTTP:
|
||||||
|
client_wsi = NULL;
|
||||||
|
lws_cancel_service(lws_get_context(wsi)); /* abort poll wait */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LWS_CALLBACK_CLOSED_CLIENT_HTTP:
|
||||||
|
client_wsi = NULL;
|
||||||
|
lws_cancel_service(lws_get_context(wsi)); /* abort poll wait */
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lws_callback_http_dummy(wsi, reason, user, in, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct lws_protocols protocols[] = {
|
||||||
|
{
|
||||||
|
"http",
|
||||||
|
callback_http,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
},
|
||||||
|
{ NULL, NULL, 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
int slack_oauth_timer_cb(const void *pointer, void *data, int remaining_calls)
|
||||||
|
{
|
||||||
|
if (n >= 0 && client_wsi)
|
||||||
|
{
|
||||||
|
n = lws_service(context, 0);
|
||||||
|
}
|
||||||
|
else if (context)
|
||||||
|
{
|
||||||
|
lws_context_destroy(context);
|
||||||
|
context = NULL;
|
||||||
|
free(uri);
|
||||||
|
|
||||||
|
if (slack_oauth_hook_timer)
|
||||||
|
weechat_unhook(slack_oauth_hook_timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return WEECHAT_RC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void slack_oauth_request_token(char *code, void (*callback)(char *token))
|
||||||
|
{
|
||||||
|
struct lws_context_creation_info info;
|
||||||
|
struct lws_client_connect_info i;
|
||||||
|
|
||||||
|
size_t urilen = snprintf(NULL, 0, endpoint, SLACK_CLIENT_ID, SLACK_CLIENT_SECRET, code) + 1;
|
||||||
|
uri = malloc(urilen);
|
||||||
|
snprintf(uri, urilen, endpoint, SLACK_CLIENT_ID, SLACK_CLIENT_SECRET, code);
|
||||||
|
|
||||||
|
lws_set_log_level(0, NULL);
|
||||||
|
|
||||||
|
memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */
|
||||||
|
info.options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
|
||||||
|
info.port = CONTEXT_PORT_NO_LISTEN; /* we do not run any server */
|
||||||
|
info.protocols = protocols;
|
||||||
|
|
||||||
|
context = lws_create_context(&info);
|
||||||
|
if (!context)
|
||||||
|
{
|
||||||
|
weechat_printf(
|
||||||
|
NULL,
|
||||||
|
_("%s%s: error connecting to slack: lws init failed"),
|
||||||
|
weechat_prefix("error"), SLACK_PLUGIN_NAME);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
weechat_printf(
|
||||||
|
NULL,
|
||||||
|
_("%s%s: Contacting slack.com:443"),
|
||||||
|
weechat_prefix("network"), SLACK_PLUGIN_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&i, 0, sizeof i); /* otherwise uninitialized garbage */
|
||||||
|
i.context = context;
|
||||||
|
i.ssl_connection = LCCSCF_USE_SSL;
|
||||||
|
i.port = 443;
|
||||||
|
i.address = "slack.com";
|
||||||
|
i.path = uri;
|
||||||
|
i.host = i.address;
|
||||||
|
i.origin = i.address;
|
||||||
|
i.method = "GET";
|
||||||
|
i.protocol = protocols[0].name;
|
||||||
|
i.pwsi = &client_wsi;
|
||||||
|
|
||||||
|
lws_client_connect_via_info(&i);
|
||||||
|
|
||||||
|
slack_oauth_hook_timer = weechat_hook_timer(1 * 1000, 0, 0,
|
||||||
|
&slack_oauth_timer_cb,
|
||||||
|
NULL, NULL);
|
||||||
|
|
||||||
|
weechat_callback = callback;
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _SLACK_OAUTH_H_
|
||||||
|
#define _SLACK_OAUTH_H_
|
||||||
|
|
||||||
|
extern void slack_oauth_request_token(char *code, void (*callback)(char *token));
|
||||||
|
|
||||||
|
#endif /*SLACK_OAUTH_H*/
|
@ -0,0 +1,142 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "weechat-plugin.h"
|
||||||
|
#include "slack.h"
|
||||||
|
#include "slack-config.h"
|
||||||
|
#include "slack-workspace.h"
|
||||||
|
|
||||||
|
struct t_slack_workspace *slack_workspaces = NULL;
|
||||||
|
struct t_slack_workspace *last_slack_workspace = NULL;
|
||||||
|
|
||||||
|
char *slack_workspace_options[SLACK_WORKSPACE_NUM_OPTIONS][2] =
|
||||||
|
{ { "token", "" },
|
||||||
|
};
|
||||||
|
|
||||||
|
struct t_slack_workspace *slack_workspace_search(const char *workspace_name)
|
||||||
|
{
|
||||||
|
struct t_slack_workspace *ptr_workspace;
|
||||||
|
|
||||||
|
if (!workspace_name)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (ptr_workspace = slack_workspaces; ptr_workspace;
|
||||||
|
ptr_workspace = ptr_workspace->next_workspace)
|
||||||
|
{
|
||||||
|
if (strcmp(ptr_workspace->name, workspace_name) == 0)
|
||||||
|
return ptr_workspace;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* workspace not found */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct t_slack_workspace *slack_workspace_casesearch (const char *workspace_name)
|
||||||
|
{
|
||||||
|
struct t_slack_workspace *ptr_workspace;
|
||||||
|
|
||||||
|
if (!workspace_name)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (ptr_workspace = slack_workspaces; ptr_workspace;
|
||||||
|
ptr_workspace = ptr_workspace->next_workspace)
|
||||||
|
{
|
||||||
|
if (weechat_strcasecmp (ptr_workspace->name, workspace_name) == 0)
|
||||||
|
return ptr_workspace;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* workspace not found */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int slack_workspace_search_option(const char *option_name)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!option_name)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (i = 0; i < SLACK_WORKSPACE_NUM_OPTIONS; i++)
|
||||||
|
{
|
||||||
|
if (weechat_strcasecmp(slack_workspace_options[i][0], option_name) == 0)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* workspace option not found */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct t_slack_workspace *slack_workspace_alloc(const char *name)
|
||||||
|
{
|
||||||
|
struct t_slack_workspace *new_workspace;
|
||||||
|
int i, length;
|
||||||
|
char *option_name;
|
||||||
|
|
||||||
|
if (slack_workspace_casesearch(name))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* alloc memory for new workspace */
|
||||||
|
new_workspace = malloc(sizeof(*new_workspace));
|
||||||
|
if (!new_workspace)
|
||||||
|
{
|
||||||
|
weechat_printf(NULL,
|
||||||
|
_("%s%s: error when allocating new workspace"),
|
||||||
|
weechat_prefix("error"), SLACK_PLUGIN_NAME);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add new workspace to queue */
|
||||||
|
new_workspace->prev_workspace = last_slack_workspace;
|
||||||
|
new_workspace->next_workspace = NULL;
|
||||||
|
if (last_slack_workspace)
|
||||||
|
last_slack_workspace->next_workspace = new_workspace;
|
||||||
|
else
|
||||||
|
slack_workspaces = new_workspace;
|
||||||
|
last_slack_workspace = new_workspace;
|
||||||
|
|
||||||
|
/* set name */
|
||||||
|
new_workspace->name = strdup(name);
|
||||||
|
|
||||||
|
/* internal vars */
|
||||||
|
new_workspace->reloading_from_config = 0;
|
||||||
|
new_workspace->reloaded_from_config = 0;
|
||||||
|
|
||||||
|
new_workspace->is_connected = 0;
|
||||||
|
|
||||||
|
/* create options with null value */
|
||||||
|
for (i = 0; i < SLACK_WORKSPACE_NUM_OPTIONS; i++)
|
||||||
|
{
|
||||||
|
length = strlen(new_workspace->name) + 1 +
|
||||||
|
strlen(slack_workspace_options[i][0]) +
|
||||||
|
512 + /* inherited option name(slack.workspace_default.xxx) */
|
||||||
|
1;
|
||||||
|
option_name = malloc(length);
|
||||||
|
if (option_name)
|
||||||
|
{
|
||||||
|
snprintf(option_name, length, "%s.%s << slack.workspace_default.%s",
|
||||||
|
new_workspace->name,
|
||||||
|
slack_workspace_options[i][0],
|
||||||
|
slack_workspace_options[i][0]);
|
||||||
|
new_workspace->options[i] = slack_config_workspace_new_option(
|
||||||
|
slack_config_file,
|
||||||
|
slack_config_section_workspace,
|
||||||
|
i,
|
||||||
|
option_name,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
1,
|
||||||
|
&slack_config_workspace_check_value_cb,
|
||||||
|
slack_workspace_options[i][0],
|
||||||
|
NULL,
|
||||||
|
&slack_config_workspace_change_cb,
|
||||||
|
slack_workspace_options[i][0],
|
||||||
|
NULL);
|
||||||
|
slack_config_workspace_change_cb(slack_workspace_options[i][0], NULL,
|
||||||
|
new_workspace->options[i]);
|
||||||
|
free(option_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new_workspace;
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
#ifndef _SLACK_WORKSPACE_H_
|
||||||
|
#define _SLACK_WORKSPACE_H_
|
||||||
|
|
||||||
|
extern struct t_slack_workspace *slack_workspaces;
|
||||||
|
extern struct t_slack_workspace *last_slack_workspace;
|
||||||
|
|
||||||
|
enum t_slack_workspace_option
|
||||||
|
{
|
||||||
|
SLACK_WORKSPACE_OPTION_TOKEN = 0,
|
||||||
|
SLACK_WORKSPACE_NUM_OPTIONS,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct t_slack_workspace
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
struct t_config_option *options[SLACK_WORKSPACE_NUM_OPTIONS];
|
||||||
|
|
||||||
|
int reloading_from_config;
|
||||||
|
int reloaded_from_config;
|
||||||
|
|
||||||
|
int is_connected;
|
||||||
|
|
||||||
|
struct t_slack_workspace *prev_workspace;
|
||||||
|
struct t_slack_workspace *next_workspace;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern char *slack_workspace_options[][2];
|
||||||
|
|
||||||
|
struct t_slack_workspace *slack_workspace_search(const char *workspace_name);
|
||||||
|
int slack_workspace_search_option(const char *option_name);
|
||||||
|
struct t_slack_workspace *slack_workspace_alloc(const char *name);
|
||||||
|
|
||||||
|
#endif /*SLACK_WORKSPACE_H*/
|
@ -0,0 +1,43 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include "weechat-plugin.h"
|
||||||
|
#include "slack.h"
|
||||||
|
#include "slack-config.h"
|
||||||
|
#include "slack-command.h"
|
||||||
|
|
||||||
|
|
||||||
|
WEECHAT_PLUGIN_NAME(SLACK_PLUGIN_NAME);
|
||||||
|
WEECHAT_PLUGIN_DESCRIPTION(N_("Slack (slack.com) protocol"));
|
||||||
|
WEECHAT_PLUGIN_AUTHOR("Tony Olagbaiye <frony0@gmail.com>");
|
||||||
|
WEECHAT_PLUGIN_VERSION(SLACK_PLUGIN_VERSION);
|
||||||
|
WEECHAT_PLUGIN_LICENSE("MPL2");
|
||||||
|
WEECHAT_PLUGIN_PRIORITY(6000);
|
||||||
|
|
||||||
|
struct t_weechat_plugin *weechat_slack_plugin = NULL;
|
||||||
|
|
||||||
|
int weechat_plugin_init(struct t_weechat_plugin *plugin, int argc, char *argv[])
|
||||||
|
{
|
||||||
|
(void) argc;
|
||||||
|
(void) argv;
|
||||||
|
|
||||||
|
weechat_plugin = plugin;
|
||||||
|
|
||||||
|
if (!slack_config_init())
|
||||||
|
return WEECHAT_RC_ERROR;
|
||||||
|
|
||||||
|
slack_config_read();
|
||||||
|
|
||||||
|
slack_command_init();
|
||||||
|
|
||||||
|
return WEECHAT_RC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int weechat_plugin_end(struct t_weechat_plugin *plugin)
|
||||||
|
{
|
||||||
|
/* make C compiler happy */
|
||||||
|
(void) plugin;
|
||||||
|
|
||||||
|
return WEECHAT_RC_OK;
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
#ifndef _SLACK_H_
|
||||||
|
#define _SLACK_H_
|
||||||
|
|
||||||
|
#define weechat_plugin weechat_slack_plugin
|
||||||
|
#define SLACK_PLUGIN_NAME "slack"
|
||||||
|
#define SLACK_PLUGIN_VERSION "0.1"
|
||||||
|
|
||||||
|
#define SLACK_CLIENT_ID "2468770254.51917335286"
|
||||||
|
#define SLACK_CLIENT_SECRET "dcb7fe380a000cba0cca3169a5fe8d70"
|
||||||
|
|
||||||
|
extern struct t_weechat_plugin *weechat_slack_plugin;
|
||||||
|
|
||||||
|
#endif /*SLACK_H*/
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue