summaryrefslogtreecommitdiffabout
path: root/lib/ax.cc
Unidiff
Diffstat (limited to 'lib/ax.cc') (more/less context) (ignore whitespace changes)
-rw-r--r--lib/ax.cc135
1 files changed, 135 insertions, 0 deletions
diff --git a/lib/ax.cc b/lib/ax.cc
new file mode 100644
index 0000000..ccdb706
--- a/dev/null
+++ b/lib/ax.cc
@@ -0,0 +1,135 @@
1#include <opkele/exception.h>
2#include <opkele/ax.h>
3#include <opkele/uris.h>
4#include <opkele/util.h>
5
6#include <map>
7#include <string>
8#include <vector>
9
10using namespace std;
11
12namespace opkele {
13
14 void ax_t::add_attribute(const char *uri, bool required, const char *alias /* = NULL */, int count /* = 1 */) {
15 assert(uri && *uri);
16 assert(count != 0);
17
18 ax_attr_t attr;
19 attr.uri = uri;
20 attr.required = required;
21 attr.count = count;
22 // if no alias is specified, generate one using an internal auto-incremented counter
23 attr.alias = alias ? alias : string("attr") + opkele::util::long_to_string(++alias_count);
24
25 attrs.push_back(attr);
26 }
27
28 void ax_t::rp_checkid_hook(basic_openid_message& om) {
29 if (attrs.size() == 0) return; // not asking for any attributes
30
31 string pfx = om.allocate_ns(OIURI_AX10,"ax");
32 om.set_field(pfx+".mode", "fetch_request"); // only supports fetch_request for now
33
34 string required_fields, optional_fields;
35 for (size_t i = 0; i < attrs.size(); i++) {
36 // build up list of required/optional aliases
37 if (attrs[i].required) required_fields += (required_fields.empty() ? "" : ",") + attrs[i].alias;
38 else optional_fields += (optional_fields.empty() ? "" : ",") + attrs[i].alias;
39
40 om.set_field(pfx+".type."+attrs[i].alias, attrs[i].uri);
41
42 // only specify count if it's >1 or unlimited
43 if (attrs[i].count == UNLIMITED_COUNT) {
44 om.set_field(pfx+".count."+attrs[i].alias, "unlimited");
45 } else if (attrs[i].count > 1) {
46 om.set_field(pfx+".count."+attrs[i].alias, opkele::util::long_to_string(attrs[i].count));
47 }
48 }
49
50 if (!required_fields.empty()) om.set_field(pfx+".required", required_fields);
51 if (!optional_fields.empty()) om.set_field(pfx+".if_available", optional_fields);
52
53 if (!update_url.empty()) om.set_field(pfx+".update_url", update_url);
54 }
55
56 void ax_t::checkid_hook(basic_openid_message& om) {
57 rp_checkid_hook(om); }
58
59 void ax_t::rp_id_res_hook(const basic_openid_message& om,
60 const basic_openid_message& sp) {
61 string pfx;
62 try {
63 pfx = om.find_ns(OIURI_AX10,"ax");
64 }catch(failed_lookup&) {
65 return;
66 }
67 pfx += '.';
68
69 // first look at all aliases and generate an internal uri->alias map
70 string fn;
71 map<string, string> aliases;
72 for (basic_openid_message::fields_iterator it = sp.fields_begin(); it != sp.fields_end(); ++it) {
73 fn = *it;
74 string type_pfx = pfx; type_pfx += "type.";
75 size_t pos = fn.find(type_pfx);
76 if (pos == string::npos) continue;
77 string alias = fn.substr(pos + type_pfx.size());
78 aliases[sp.get_field(fn)] = alias;
79 }
80
81 // now for each alias, pull out the count and value(s) and store uri->[value1, ...]
82 for (map<string, string>::iterator it = aliases.begin(); it != aliases.end(); ++it) {
83 vector<string> values;
84 fn = pfx; fn += "count." + it->second;
85 if (sp.has_field(fn)) {
86 int count = opkele::util::string_to_long(sp.get_field(fn));
87 for (int i = 1; i <= count; i++) {
88 fn = pfx; fn += "value." + it->second + "." + opkele::util::long_to_string(i);
89 values.push_back(sp.get_field(fn));
90 }
91 } else {
92 fn = pfx; fn += "value." + it->second;
93 values.push_back(sp.get_field(fn));
94 }
95 response_attrs[it->first] = values;
96 }
97
98 fn = pfx; fn += "update_url";
99 if (sp.has_field(fn)) update_url = sp.get_field(fn);
100 }
101
102 string ax_t::get_attribute(const char *uri, int index /* = 0 */) {
103 if (response_attrs.find(uri) == response_attrs.end()) return "";
104 return response_attrs[uri][index];
105 }
106
107 size_t ax_t::get_attribute_count(const char *uri) {
108 if (response_attrs.find(uri) == response_attrs.end()) return 0;
109 return response_attrs[uri].size();
110 }
111
112 void ax_t::id_res_hook(const basic_openid_message& om,
113 const basic_openid_message& sp) {
114 rp_id_res_hook(om,sp); }
115
116 void ax_t::op_checkid_hook(const basic_openid_message& inm) {
117 }
118
119 void ax_t::op_id_res_hook(basic_openid_message& oum) {
120 }
121
122 void ax_t::checkid_hook(const basic_openid_message& inm,
123 basic_openid_message& oum) {
124 op_checkid_hook(inm);
125 setup_response(inm,oum);
126 op_id_res_hook(oum);
127 }
128
129 void ax_t::setup_response(const basic_openid_message& /* inm */,basic_openid_message& /* oum */) {
130 setup_response();
131 }
132 void ax_t::setup_response() {
133 }
134}
135