Commit 2aac95f34cdede873fde8eb46b350dd18246cdd6

Authored by 陈晓峰
1 parent b68250da

add csna

Showing 40 changed files with 2016 additions and 0 deletions
  1 +Thumbs.db
... ...
  1 + GNU GENERAL PUBLIC LICENSE
  2 + Version 2, June 1991
  3 +
  4 + Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
  5 + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  6 + Everyone is permitted to copy and distribute verbatim copies
  7 + of this license document, but changing it is not allowed.
  8 +
  9 + Preamble
  10 +
  11 + The licenses for most software are designed to take away your
  12 +freedom to share and change it. By contrast, the GNU General Public
  13 +License is intended to guarantee your freedom to share and change free
  14 +software--to make sure the software is free for all its users. This
  15 +General Public License applies to most of the Free Software
  16 +Foundation's software and to any other program whose authors commit to
  17 +using it. (Some other Free Software Foundation software is covered by
  18 +the GNU Lesser General Public License instead.) You can apply it to
  19 +your programs, too.
  20 +
  21 + When we speak of free software, we are referring to freedom, not
  22 +price. Our General Public Licenses are designed to make sure that you
  23 +have the freedom to distribute copies of free software (and charge for
  24 +this service if you wish), that you receive source code or can get it
  25 +if you want it, that you can change the software or use pieces of it
  26 +in new free programs; and that you know you can do these things.
  27 +
  28 + To protect your rights, we need to make restrictions that forbid
  29 +anyone to deny you these rights or to ask you to surrender the rights.
  30 +These restrictions translate to certain responsibilities for you if you
  31 +distribute copies of the software, or if you modify it.
  32 +
  33 + For example, if you distribute copies of such a program, whether
  34 +gratis or for a fee, you must give the recipients all the rights that
  35 +you have. You must make sure that they, too, receive or can get the
  36 +source code. And you must show them these terms so they know their
  37 +rights.
  38 +
  39 + We protect your rights with two steps: (1) copyright the software, and
  40 +(2) offer you this license which gives you legal permission to copy,
  41 +distribute and/or modify the software.
  42 +
  43 + Also, for each author's protection and ours, we want to make certain
  44 +that everyone understands that there is no warranty for this free
  45 +software. If the software is modified by someone else and passed on, we
  46 +want its recipients to know that what they have is not the original, so
  47 +that any problems introduced by others will not reflect on the original
  48 +authors' reputations.
  49 +
  50 + Finally, any free program is threatened constantly by software
  51 +patents. We wish to avoid the danger that redistributors of a free
  52 +program will individually obtain patent licenses, in effect making the
  53 +program proprietary. To prevent this, we have made it clear that any
  54 +patent must be licensed for everyone's free use or not licensed at all.
  55 +
  56 + The precise terms and conditions for copying, distribution and
  57 +modification follow.
  58 +
  59 + GNU GENERAL PUBLIC LICENSE
  60 + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
  61 +
  62 + 0. This License applies to any program or other work which contains
  63 +a notice placed by the copyright holder saying it may be distributed
  64 +under the terms of this General Public License. The "Program", below,
  65 +refers to any such program or work, and a "work based on the Program"
  66 +means either the Program or any derivative work under copyright law:
  67 +that is to say, a work containing the Program or a portion of it,
  68 +either verbatim or with modifications and/or translated into another
  69 +language. (Hereinafter, translation is included without limitation in
  70 +the term "modification".) Each licensee is addressed as "you".
  71 +
  72 +Activities other than copying, distribution and modification are not
  73 +covered by this License; they are outside its scope. The act of
  74 +running the Program is not restricted, and the output from the Program
  75 +is covered only if its contents constitute a work based on the
  76 +Program (independent of having been made by running the Program).
  77 +Whether that is true depends on what the Program does.
  78 +
  79 + 1. You may copy and distribute verbatim copies of the Program's
  80 +source code as you receive it, in any medium, provided that you
  81 +conspicuously and appropriately publish on each copy an appropriate
  82 +copyright notice and disclaimer of warranty; keep intact all the
  83 +notices that refer to this License and to the absence of any warranty;
  84 +and give any other recipients of the Program a copy of this License
  85 +along with the Program.
  86 +
  87 +You may charge a fee for the physical act of transferring a copy, and
  88 +you may at your option offer warranty protection in exchange for a fee.
  89 +
  90 + 2. You may modify your copy or copies of the Program or any portion
  91 +of it, thus forming a work based on the Program, and copy and
  92 +distribute such modifications or work under the terms of Section 1
  93 +above, provided that you also meet all of these conditions:
  94 +
  95 + a) You must cause the modified files to carry prominent notices
  96 + stating that you changed the files and the date of any change.
  97 +
  98 + b) You must cause any work that you distribute or publish, that in
  99 + whole or in part contains or is derived from the Program or any
  100 + part thereof, to be licensed as a whole at no charge to all third
  101 + parties under the terms of this License.
  102 +
  103 + c) If the modified program normally reads commands interactively
  104 + when run, you must cause it, when started running for such
  105 + interactive use in the most ordinary way, to print or display an
  106 + announcement including an appropriate copyright notice and a
  107 + notice that there is no warranty (or else, saying that you provide
  108 + a warranty) and that users may redistribute the program under
  109 + these conditions, and telling the user how to view a copy of this
  110 + License. (Exception: if the Program itself is interactive but
  111 + does not normally print such an announcement, your work based on
  112 + the Program is not required to print an announcement.)
  113 +
  114 +These requirements apply to the modified work as a whole. If
  115 +identifiable sections of that work are not derived from the Program,
  116 +and can be reasonably considered independent and separate works in
  117 +themselves, then this License, and its terms, do not apply to those
  118 +sections when you distribute them as separate works. But when you
  119 +distribute the same sections as part of a whole which is a work based
  120 +on the Program, the distribution of the whole must be on the terms of
  121 +this License, whose permissions for other licensees extend to the
  122 +entire whole, and thus to each and every part regardless of who wrote it.
  123 +
  124 +Thus, it is not the intent of this section to claim rights or contest
  125 +your rights to work written entirely by you; rather, the intent is to
  126 +exercise the right to control the distribution of derivative or
  127 +collective works based on the Program.
  128 +
  129 +In addition, mere aggregation of another work not based on the Program
  130 +with the Program (or with a work based on the Program) on a volume of
  131 +a storage or distribution medium does not bring the other work under
  132 +the scope of this License.
  133 +
  134 + 3. You may copy and distribute the Program (or a work based on it,
  135 +under Section 2) in object code or executable form under the terms of
  136 +Sections 1 and 2 above provided that you also do one of the following:
  137 +
  138 + a) Accompany it with the complete corresponding machine-readable
  139 + source code, which must be distributed under the terms of Sections
  140 + 1 and 2 above on a medium customarily used for software interchange; or,
  141 +
  142 + b) Accompany it with a written offer, valid for at least three
  143 + years, to give any third party, for a charge no more than your
  144 + cost of physically performing source distribution, a complete
  145 + machine-readable copy of the corresponding source code, to be
  146 + distributed under the terms of Sections 1 and 2 above on a medium
  147 + customarily used for software interchange; or,
  148 +
  149 + c) Accompany it with the information you received as to the offer
  150 + to distribute corresponding source code. (This alternative is
  151 + allowed only for noncommercial distribution and only if you
  152 + received the program in object code or executable form with such
  153 + an offer, in accord with Subsection b above.)
  154 +
  155 +The source code for a work means the preferred form of the work for
  156 +making modifications to it. For an executable work, complete source
  157 +code means all the source code for all modules it contains, plus any
  158 +associated interface definition files, plus the scripts used to
  159 +control compilation and installation of the executable. However, as a
  160 +special exception, the source code distributed need not include
  161 +anything that is normally distributed (in either source or binary
  162 +form) with the major components (compiler, kernel, and so on) of the
  163 +operating system on which the executable runs, unless that component
  164 +itself accompanies the executable.
  165 +
  166 +If distribution of executable or object code is made by offering
  167 +access to copy from a designated place, then offering equivalent
  168 +access to copy the source code from the same place counts as
  169 +distribution of the source code, even though third parties are not
  170 +compelled to copy the source along with the object code.
  171 +
  172 + 4. You may not copy, modify, sublicense, or distribute the Program
  173 +except as expressly provided under this License. Any attempt
  174 +otherwise to copy, modify, sublicense or distribute the Program is
  175 +void, and will automatically terminate your rights under this License.
  176 +However, parties who have received copies, or rights, from you under
  177 +this License will not have their licenses terminated so long as such
  178 +parties remain in full compliance.
  179 +
  180 + 5. You are not required to accept this License, since you have not
  181 +signed it. However, nothing else grants you permission to modify or
  182 +distribute the Program or its derivative works. These actions are
  183 +prohibited by law if you do not accept this License. Therefore, by
  184 +modifying or distributing the Program (or any work based on the
  185 +Program), you indicate your acceptance of this License to do so, and
  186 +all its terms and conditions for copying, distributing or modifying
  187 +the Program or works based on it.
  188 +
  189 + 6. Each time you redistribute the Program (or any work based on the
  190 +Program), the recipient automatically receives a license from the
  191 +original licensor to copy, distribute or modify the Program subject to
  192 +these terms and conditions. You may not impose any further
  193 +restrictions on the recipients' exercise of the rights granted herein.
  194 +You are not responsible for enforcing compliance by third parties to
  195 +this License.
  196 +
  197 + 7. If, as a consequence of a court judgment or allegation of patent
  198 +infringement or for any other reason (not limited to patent issues),
  199 +conditions are imposed on you (whether by court order, agreement or
  200 +otherwise) that contradict the conditions of this License, they do not
  201 +excuse you from the conditions of this License. If you cannot
  202 +distribute so as to satisfy simultaneously your obligations under this
  203 +License and any other pertinent obligations, then as a consequence you
  204 +may not distribute the Program at all. For example, if a patent
  205 +license would not permit royalty-free redistribution of the Program by
  206 +all those who receive copies directly or indirectly through you, then
  207 +the only way you could satisfy both it and this License would be to
  208 +refrain entirely from distribution of the Program.
  209 +
  210 +If any portion of this section is held invalid or unenforceable under
  211 +any particular circumstance, the balance of the section is intended to
  212 +apply and the section as a whole is intended to apply in other
  213 +circumstances.
  214 +
  215 +It is not the purpose of this section to induce you to infringe any
  216 +patents or other property right claims or to contest validity of any
  217 +such claims; this section has the sole purpose of protecting the
  218 +integrity of the free software distribution system, which is
  219 +implemented by public license practices. Many people have made
  220 +generous contributions to the wide range of software distributed
  221 +through that system in reliance on consistent application of that
  222 +system; it is up to the author/donor to decide if he or she is willing
  223 +to distribute software through any other system and a licensee cannot
  224 +impose that choice.
  225 +
  226 +This section is intended to make thoroughly clear what is believed to
  227 +be a consequence of the rest of this License.
  228 +
  229 + 8. If the distribution and/or use of the Program is restricted in
  230 +certain countries either by patents or by copyrighted interfaces, the
  231 +original copyright holder who places the Program under this License
  232 +may add an explicit geographical distribution limitation excluding
  233 +those countries, so that distribution is permitted only in or among
  234 +countries not thus excluded. In such case, this License incorporates
  235 +the limitation as if written in the body of this License.
  236 +
  237 + 9. The Free Software Foundation may publish revised and/or new versions
  238 +of the General Public License from time to time. Such new versions will
  239 +be similar in spirit to the present version, but may differ in detail to
  240 +address new problems or concerns.
  241 +
  242 +Each version is given a distinguishing version number. If the Program
  243 +specifies a version number of this License which applies to it and "any
  244 +later version", you have the option of following the terms and conditions
  245 +either of that version or of any later version published by the Free
  246 +Software Foundation. If the Program does not specify a version number of
  247 +this License, you may choose any version ever published by the Free Software
  248 +Foundation.
  249 +
  250 + 10. If you wish to incorporate parts of the Program into other free
  251 +programs whose distribution conditions are different, write to the author
  252 +to ask for permission. For software which is copyrighted by the Free
  253 +Software Foundation, write to the Free Software Foundation; we sometimes
  254 +make exceptions for this. Our decision will be guided by the two goals
  255 +of preserving the free status of all derivatives of our free software and
  256 +of promoting the sharing and reuse of software generally.
  257 +
  258 + NO WARRANTY
  259 +
  260 + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
  261 +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
  262 +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
  263 +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
  264 +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  265 +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
  266 +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
  267 +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
  268 +REPAIR OR CORRECTION.
  269 +
  270 + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
  271 +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
  272 +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
  273 +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
  274 +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
  275 +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
  276 +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
  277 +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
  278 +POSSIBILITY OF SUCH DAMAGES.
  279 +
  280 + END OF TERMS AND CONDITIONS
  281 +
  282 + How to Apply These Terms to Your New Programs
  283 +
  284 + If you develop a new program, and you want it to be of the greatest
  285 +possible use to the public, the best way to achieve this is to make it
  286 +free software which everyone can redistribute and change under these terms.
  287 +
  288 + To do so, attach the following notices to the program. It is safest
  289 +to attach them to the start of each source file to most effectively
  290 +convey the exclusion of warranty; and each file should have at least
  291 +the "copyright" line and a pointer to where the full notice is found.
  292 +
  293 + <one line to give the program's name and a brief idea of what it does.>
  294 + Copyright (C) <year> <name of author>
  295 +
  296 + This program is free software; you can redistribute it and/or modify
  297 + it under the terms of the GNU General Public License as published by
  298 + the Free Software Foundation; either version 2 of the License, or
  299 + (at your option) any later version.
  300 +
  301 + This program is distributed in the hope that it will be useful,
  302 + but WITHOUT ANY WARRANTY; without even the implied warranty of
  303 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  304 + GNU General Public License for more details.
  305 +
  306 + You should have received a copy of the GNU General Public License along
  307 + with this program; if not, write to the Free Software Foundation, Inc.,
  308 + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  309 +
  310 +Also add information on how to contact you by electronic and paper mail.
  311 +
  312 +If the program is interactive, make it output a short notice like this
  313 +when it starts in an interactive mode:
  314 +
  315 + Gnomovision version 69, Copyright (C) year name of author
  316 + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
  317 + This is free software, and you are welcome to redistribute it
  318 + under certain conditions; type `show c' for details.
  319 +
  320 +The hypothetical commands `show w' and `show c' should show the appropriate
  321 +parts of the General Public License. Of course, the commands you use may
  322 +be called something other than `show w' and `show c'; they could even be
  323 +mouse-clicks or menu items--whatever suits your program.
  324 +
  325 +You should also get your employer (if you work as a programmer) or your
  326 +school, if any, to sign a "copyright disclaimer" for the program, if
  327 +necessary. Here is a sample; alter the names:
  328 +
  329 + Yoyodyne, Inc., hereby disclaims all copyright interest in the program
  330 + `Gnomovision' (which makes passes at compilers) written by James Hacker.
  331 +
  332 + <signature of Ty Coon>, 1 April 1989
  333 + Ty Coon, President of Vice
  334 +
  335 +This General Public License does not permit incorporating your program into
  336 +proprietary programs. If your program is a subroutine library, you may
  337 +consider it more useful to permit linking proprietary applications with the
  338 +library. If this is what you want to do, use the GNU Lesser General
  339 +Public License instead of this License.
... ...
  1 +This module provides avalibility to allow user sign in with top Chinese Social
  2 +Networks.
  3 +
  4 +Currently we support:
  5 +Sina weibo (新浪微博), Chinese twitter like website.
  6 +Tencent (QQ), biggest Chinese IM provider.
  7 +Renren(人人网), biggest Chinese facebook like website.
  8 +Kaixin001(开心网), secondary Chinese facebook like website.
  9 +
  10 +Configuration:
  11 +The module contians 1 main module and 4 sub-modules.
  12 +Each of these 4 sub-modules represent 4 Chinese Social Networks.
  13 +Install and enable main module and any of these sub-modules you desired.
  14 +Go to configuration page (/admin/config/csna) and fill the KEY and SECRET you
  15 +get from these Chinese Social Networks.
  16 +
  17 +URL of subscribing for KEYs and SECRETs:
  18 +Weibo http://open.weibo.com/
  19 +QQ http://connect.qq.com/
  20 +Renren http://dev.renren.com/website
  21 +Kaixin http://open.kaixin001.com/
... ...
  1 +<?php
  2 +
  3 +/**
  4 + * @file
  5 + * Functionality for CSNA administration.
  6 + */
  7 +
  8 +/**
  9 + * Menu callback: CSNA key or secrect config.
  10 + */
  11 +function csna_admin_settings() {
  12 + $providers = csna_providers();
  13 + foreach ($providers as $provider_id => $provider) {
  14 + $form[$provider_id] = array(
  15 + '#type' => 'fieldset',
  16 + '#title' => $provider['title'],
  17 + '#description' => $provider['description'],
  18 + );
  19 + $form[$provider_id]['csna_' . $provider_id . '_key'] = array(
  20 + '#type' => 'textfield',
  21 + '#title' => t('Key'),
  22 + '#size' => 40,
  23 + '#maxlength' => 255,
  24 + '#default_value' => variable_get('csna_' . $provider_id . '_key', ''),
  25 + );
  26 + $form[$provider_id]['csna_' . $provider_id . '_secret'] = array(
  27 + '#type' => 'textfield',
  28 + '#title' => t('Secret'),
  29 + '#size' => 40,
  30 + '#maxlength' => 255,
  31 + '#default_value' => variable_get('csna_' . $provider_id . '_secret', ''),
  32 + );
  33 + }
  34 +
  35 + // If no provider/sub-module was found, provide a default help text.
  36 + if (!isset($form)) {
  37 + $form['default_message'] = array(
  38 + '#markup' => t('<strong>No CSNA third party API provider module has been enabled yet</strong>.<br/>Please enable <strong>at least a CSNA sub-module</strong> or any other <strong>CSNA API provider</strong> from the !modadminlink then feel free to browse this page again.<br/>See more information on !projectlink about <strong>supported providers</strong> and <strong>installation instructions</strong>.', array(
  39 + '!modadminlink' => l(t('module administration page'), 'admin/modules'),
  40 + '!projectlink' => l(t("module project's page"), 'http://drupal.org/project/csna', array('attributes' => array('target' => '_blank'))),
  41 + )),
  42 + );
  43 + return $form;
  44 + }
  45 + else {
  46 + $form['csna_require_email'] = array(
  47 + '#type' => 'checkbox',
  48 + '#title' => t('Require email'),
  49 + '#description' => t('Require user entering email after successful user login if email hasn\'t been set yet.'),
  50 + '#default_value' => variable_get('csna_require_email', TRUE),
  51 + );
  52 +
  53 + return system_settings_form($form);
  54 + }
  55 +}
... ...
  1 +<?php
  2 +/**
  3 + * @file
  4 + * API documentation for the Chinese Social Networks Authentication module.
  5 + */
  6 +
  7 +/**
  8 + * Define Authentication providers available to the CSNA framework.
  9 + *
  10 + * The Chinese Social Networks Authentication (CSNA) module uses this hook to
  11 + * gather information on provider authentication methods defined by enabled
  12 + * modules. These methods depend on a variety of properties used by CSNA to
  13 + * integrate with third party API providers based on the OAuth protocol.
  14 + *
  15 + * By default CSNA supports the following Authentication API providers through
  16 + * sub-modules:
  17 + * - Sina weibo (新浪微博), Chinese twitter like website.
  18 + * - Tencent (QQ), biggest Chinese IM provider.
  19 + * - Renren(人人网), biggest Chinese facebook like website.
  20 + * - Kaixin001(开心网), secondary Chinese facebook like website.
  21 + *
  22 + * This hook allows other modules to define custom authentication third party
  23 + * API providers by defining all the necessary information for CSNA's
  24 + * implementation of the OAuth protocol.
  25 + *
  26 + * @return array
  27 + * An array of providers keyed by provider_id with the following properties:
  28 + * - title: The title or name of the defined provider.
  29 + * - description: Description text to appear on the admin page for the
  30 + * configuration of the required parameters for this specific provider,
  31 + * such as Authentication API KEY or Password.
  32 + * - display_title: The title to be displayed in the list of links of
  33 + * providers returned by theme_csna_providers, which displays in the user
  34 + * login/registration forms and block. For better usage, HTML is allowed
  35 + * for this property, for example to display an image or logo.
  36 + * - type: string identifying the type of OAuth protocol used. By default,
  37 + * CSNA provides a constant for 'oauth2', see CSNA_OAUTH2, but any other
  38 + * custom OAuth type could also be used and provided for this property.
  39 + * - authorize_uri: The URL used by providers to authenticate users through
  40 + * the OAuth protocol.
  41 + * - access_token_uri: The URL used by CSNA to get the authentication token
  42 + * returned by providers if operation was successful.
  43 + * - info_uri: This URL allows capturing User's information from third party
  44 + * authentication providers, such as username, or other useful information.
  45 + *
  46 + * @see csna_providers()
  47 + * @see csna_weibo_csna_provider_info()
  48 + */
  49 +function hook_csna_provider_info() {
  50 + // Example taken from the csna_weibo sub-module.
  51 + $providers = array();
  52 +
  53 + $providers['weibo'] = array(
  54 + 'title' => t('Weibo Sina'),
  55 + 'description' => t('Set your Sina Weibo authorized KEY and SECRET below.'),
  56 + 'display_title' => csna_get_weibo_button_image(),
  57 + 'type' => CSNA_OAUTH2,
  58 + 'authorize_uri' => 'https://api.weibo.com/oauth2/authorize',
  59 + 'access_token_uri' => 'https://api.weibo.com/oauth2/access_token',
  60 + 'info_uri' => 'https://api.weibo.com/2/users/show.json',
  61 + );
  62 +
  63 + return $providers;
  64 +}
  65 +
  66 +/**
  67 + * Allows other modules to alter already defined list of providers.
  68 + *
  69 + * Any of the providers and any of their properties or values can be modified
  70 + * by using an implementation of this hook.
  71 + *
  72 + * @param array $providers
  73 + * An associative array of providers keyed by the provider_id, as returned by
  74 + * the function csna_providers(). See hook_csna_provider_info for a detailed
  75 + * list of all the defined and required properties for each provider.
  76 + *
  77 + * @see hook_csna_provider_info()
  78 + * @see csna_providers()
  79 + */
  80 +function hook_csna_provider_info_alter(&$providers) {
  81 + if (isset($providers['weibo'])) {
  82 + $providers['weibo']['display_title'] = t("Login or register with your Sina Weibo account!");
  83 + }
  84 +}
  85 +
  86 +/**
  87 + * Define providers custom authentication callback methods.
  88 + *
  89 + * The implementation of this hook is usually required when defining a Third
  90 + * Party authentication OAuth API provider through hook_csna_provider_info.
  91 + *
  92 + * This hook callback is executed when returning from provider's API
  93 + * authentication pages, with information about the operation, such as whether
  94 + * it was successful or not. In case of success, most providers will return a
  95 + * token or code that can be further used to verify or obtain user's
  96 + * information through the $provider['info_uri'] defined URL.
  97 + *
  98 + * @param array $provider
  99 + * An array of properties for the corresponding provider defined through
  100 + * hook_csna_provider_info, see API hooks documentation for more information.
  101 + * @param array $request
  102 + * A PHP predefined variable for HTTP Request variables: $_REQUEST, received
  103 + * from the third party authentication provider.
  104 + *
  105 + * @return array
  106 + * An array of properties including the following keys and values:
  107 + * - access_token: The access token returned by the provider through its
  108 + * access_token_uri URL to provider further access to user's information if
  109 + * authentication was successful.
  110 + * - uid: The ID of the user returned from the provider used to load user
  111 + * account through user_external_load (see core API).
  112 + * - name: The user name returned from the provider used to load user account
  113 + * account through user_load_by_name (see core API).
  114 + *
  115 + * @see csna_callback()
  116 + * @see csna_kaixin_csna_provider_callback()
  117 + */
  118 +function hook_csna_provider_callback($provider, $request) {
  119 + // Example taken from the csna_kaixin sub-module.
  120 + if (isset($request['code'])) {
  121 + $parameters = array(
  122 + 'client_id' => $provider['key'],
  123 + 'client_secret' => $provider['secret'],
  124 + 'grant_type' => 'authorization_code',
  125 + 'redirect_uri' => $provider['callback'],
  126 + 'code' => $request['code'],
  127 + );
  128 + $http = drupal_http_request(url($provider['access_token_uri'], array('query' => $parameters)));
  129 + $data = json_decode($http->data);
  130 + $http = drupal_http_request(url($provider['info_uri'], array('query' => array('access_token' => $data->access_token))));
  131 + $info = json_decode($http->data);
  132 + if (!isset($info->uid)) {
  133 + return FALSE;
  134 + }
  135 + return array(
  136 + 'access_token' => $data->access_token,
  137 + 'uid' => $info->uid,
  138 + 'name' => $info->name,
  139 + );
  140 + }
  141 +}
... ...
  1 +name = CSNA
  2 +description = Authentication for Chinese Social Networks
  3 +package = Authentication
  4 +core = 7.x
  5 +configure = admin/config/services/csna
  6 +
  7 +; Information added by Drupal.org packaging script on 2015-10-19
  8 +version = "7.x-1.3"
  9 +core = "7.x"
  10 +project = "csna"
  11 +datestamp = "1445231940"
  12 +
... ...
  1 +<?php
  2 +
  3 +/**
  4 + * @file
  5 + * The Chinese Social Networks Authentication (CSNA) module provides a global
  6 + * framework and API to allow other modules to define specific authentication
  7 + * methods from Chinese Social Networks through a supported OAuth protocol.
  8 + */
  9 +
  10 +define('CSNA_OAUTH2', 'oauth2');
  11 +
  12 +/**
  13 + * Implements hook_menu().
  14 + */
  15 +function csna_menu() {
  16 + $items['csna/%csna_provider'] = array(
  17 + 'title' => 'CSNA Redirect',
  18 + 'page callback' => 'csna_redirect',
  19 + 'page arguments' => array(1),
  20 + 'access callback' => 'user_is_anonymous',
  21 + 'type' => MENU_CALLBACK,
  22 + );
  23 +
  24 + $items['csna/%csna_provider/callback'] = array(
  25 + 'title' => 'Authentication callback',
  26 + 'page callback' => 'csna_callback',
  27 + 'page arguments' => array(1),
  28 + 'access callback' => 'user_is_anonymous',
  29 + 'type' => MENU_CALLBACK,
  30 + );
  31 +
  32 + $items['csna/%user/complete-register'] = array(
  33 + 'title' => t('Complete register'),
  34 + 'page callback' => 'drupal_get_form',
  35 + 'page arguments' => array('csna_complete_register_form', 1),
  36 + 'access callback' => 'csna_user_edit_access',
  37 + 'access arguments' => array(1),
  38 + 'file' => 'csna.pages.inc',
  39 + );
  40 +
  41 + $items['admin/config/services/csna'] = array(
  42 + 'title' => 'Chinese Social Networks Authentication settings (CSNA)',
  43 + 'description' => 'Configure the CSNA key or secrect code settings for third party authentication API providers.',
  44 + 'page callback' => 'drupal_get_form',
  45 + 'page arguments' => array('csna_admin_settings'),
  46 + 'access arguments' => array('administer csna'),
  47 + 'file' => 'csna.admin.inc',
  48 + );
  49 +
  50 + return $items;
  51 +}
  52 +
  53 +/**
  54 + * Check the Provider ID.
  55 + *
  56 + * @param string $provider_id
  57 + * The Provider ID.
  58 + *
  59 + * @return mixed
  60 + * A value of $providers[$provider_id] from csna_providers(),
  61 + * or FALSE if the value does not exist.
  62 + */
  63 +function csna_provider_load($provider_id) {
  64 + $providers = csna_providers();
  65 + return isset($providers[$provider_id]) ? $providers[$provider_id] : FALSE;
  66 +}
  67 +
  68 +/**
  69 + * Implements hook_perm().
  70 + */
  71 +function csna_permission() {
  72 + return array(
  73 + 'administer csna' => array(
  74 + 'title' => t('Administer CSNA'),
  75 + 'description' => t('Perform administration tasks for CSNA.'),
  76 + ),
  77 + );
  78 +}
  79 +
  80 +/**
  81 + * Implements hook_theme().
  82 + */
  83 +function csna_theme($existing, $type, $theme, $path) {
  84 + $providers = csna_providers();
  85 + return array(
  86 + 'csna_providers' => array(
  87 + 'variables' => array('providers' => $providers),
  88 + ),
  89 + );
  90 +}
  91 +
  92 +/**
  93 + * Menu callback: CSNA Redirect.
  94 + */
  95 +function csna_redirect($provider) {
  96 + $parameters = array(
  97 + 'client_id' => $provider['key'],
  98 + 'redirect_uri' => $provider['callback'],
  99 + 'response_type' => 'code',
  100 + );
  101 + if ($provider['provider_id'] == 'wechat') {
  102 + unset($parameters['client_id']);
  103 + $parameters['appid'] = $provider['key'];
  104 + $parameters['scope'] = 'snsapi_login';
  105 + }
  106 + drupal_goto($provider['authorize_uri'], array('query' => $parameters));
  107 +}
  108 +
  109 +/**
  110 + * Menu callback: CSNA Callback.
  111 + */
  112 +function csna_callback($provider) {
  113 +
  114 + global $user;
  115 + $data = module_invoke($provider['module'], 'csna_provider_callback', $provider, $_REQUEST);
  116 +
  117 + // Forcing array format because of Sina weibo will return an Object.
  118 + if (!is_array($data)) {
  119 + $data = (array) $data;
  120 + }
  121 +
  122 + if (isset($data['access_token'])) {
  123 + $identity = $provider['provider_id'] . '_' . $data['uid'];
  124 + $account = user_external_load($identity);
  125 +
  126 + if (!isset($account->uid)) {
  127 + $name = $data['name'];
  128 + $ac = user_load_by_name($name);
  129 + if ($ac) {
  130 + $separator = '_';
  131 + $i = 0;
  132 + do {
  133 + $i++;
  134 + $name = $data['name'] . $separator . $i;
  135 + } while (user_load_by_name($name));
  136 + }
  137 + //User avatar
  138 + if (isset($data['avatar_link'])) {
  139 + $avatar_directory = file_default_scheme() . '://' . variable_get('user_picture_path', 'pictures');
  140 + $avatar = system_retrieve_file($data['avatar_link'], $avatar_directory, TRUE, FILE_EXISTS_RENAME);
  141 + }
  142 + $edit = array(
  143 + 'name' => $name,
  144 + 'status' => 1,
  145 + 'picture' => isset($avatar->fid) ? $avatar->fid : '',
  146 + );
  147 + $account = user_save(NULL, $edit);
  148 + user_set_authmaps($account, array('authname_csna' => $identity));
  149 + }
  150 +
  151 + csna_execute_user_login($account);
  152 +
  153 + if (variable_get('csna_require_email', TRUE) && empty($account->mail)) {
  154 + drupal_goto('csna/' . $account->uid . '/complete-register');
  155 + }
  156 + }
  157 + drupal_goto('user');
  158 +}
  159 +
  160 +/**
  161 + * Helper function for CSNA Callback.
  162 + *
  163 + * It executes user login after returning from provider's authentication page.
  164 + * If no valid account is found or authentication with providers failed, this
  165 + * function returns FALSE.
  166 + */
  167 +function csna_execute_user_login($account) {
  168 + if (empty($account) OR !isset($account->uid)) {
  169 + return FALSE;
  170 + }
  171 + $form_state['uid'] = $account->uid;
  172 + user_login_submit(array(), $form_state);
  173 + return TRUE;
  174 +}
  175 +
  176 +/**
  177 + * Implements hook_form_alter().
  178 + */
  179 +function csna_form_alter(&$form, &$form_state, $form_id) {
  180 + if ($form_id == 'user_login' || $form_id == 'user_login_block' || $form_id == 'user_register_form') {
  181 + $providers = csna_providers();
  182 +
  183 + // if admin form
  184 + if (empty($form['administer_users']['#value'])) {
  185 + if (isset($form['submitted']['user_login_block']['#suffix']) && !empty($form['submitted']['user_login_block']['#suffix'])) {
  186 + $form['submitted']['user_login_block']['#suffix'] .= theme('csna_providers', array('providers' => $providers));
  187 + }
  188 + else {
  189 + $form['submitted']['user_login_block']['#suffix'] = theme('csna_providers', array('providers' => $providers));
  190 + }
  191 + }
  192 + }
  193 +}
  194 +
  195 +/**
  196 + * Returns an array of OAuth Third Party authentication providers.
  197 + *
  198 + * CSNA's API Framework provides a method for any enabled module to define
  199 + * additional authentication providers. This function gathers information on
  200 + * provider authentication methods defined by enabled modules.
  201 + *
  202 + * @return array
  203 + * An associative array of providers keyed by the provider_id.
  204 + *
  205 + * @see hook_csna_provider_info()
  206 + */
  207 +function csna_providers($valid = FALSE) {
  208 + static $providers;
  209 +
  210 + if (!isset($providers)) {
  211 + $providers = array();
  212 +
  213 + // Build the providers array, including module names for the purpose
  214 + // of including files if necessary.
  215 + // An associative array of providers objects keyed by the provider_id.
  216 + foreach (module_implements('csna_provider_info') as $module) {
  217 + foreach (module_invoke($module, 'csna_provider_info') as $provider_id => $provider) {
  218 + $provider['provider_id'] = $provider_id;
  219 + $provider['module'] = $module;
  220 + $provider['key'] = variable_get('csna_' . $provider_id . '_key', '');
  221 + $provider['secret'] = variable_get('csna_' . $provider_id . '_secret', '');
  222 + $providers[$provider_id] = $provider;
  223 + if ($valid && (empty($provider['key']) || empty($provider['secret']))) {
  224 + unset($providers[$provider_id]);
  225 + }
  226 + }
  227 + }
  228 +
  229 + drupal_alter('csna_provider_info', $providers);
  230 +
  231 + foreach ($providers as $provider_id => & $provider) {
  232 + $defaults = array(
  233 + 'provider_id' => $provider_id,
  234 + 'base' => $provider_id,
  235 + 'title' => '',
  236 + 'description' => '',
  237 + 'active' => FALSE,
  238 + 'callback' => url('csna/' . $provider_id . '/callback', array('absolute' => TRUE)),
  239 + 'file' => '',
  240 + );
  241 +
  242 + $provider += $defaults;
  243 +
  244 + // Default the display title to the title if necessary. The display
  245 + // title is used in instances where the login method has an official
  246 + // name but a different method of display on selection forms (like some
  247 + // text and a set of images).
  248 + if (empty($provider['display_title'])) {
  249 + $provider['display_title'] = $provider['title'];
  250 + }
  251 +
  252 + // Default the short title to the title if necessary. Like the display
  253 + // title, the short title is an alternate way of displaying the title to
  254 + // the user consisting of plain text but with unnecessary information
  255 + // stripped off.
  256 + if (empty($provider[$provider_id]['short_title'])) {
  257 + $provider['short_title'] = $provider['title'];
  258 + }
  259 + }
  260 + }
  261 +
  262 + return $providers;
  263 +}
  264 +
  265 +/**
  266 + * Render a themed list of links to providers authorized login URL pages.
  267 + *
  268 + * @param array $providers
  269 + * An associative array of providers keyed by the provider_id, as returned by
  270 + * the function csna_providers().
  271 + * Mostly the display_title property of providers is used in this function
  272 + * to display a custom title, name or even HTML to be linked to corresponding
  273 + * provider's authorized login URL page. See API documentation for more
  274 + * information on providers available properties.
  275 + *
  276 + * @see csna_providers()
  277 + * @see hook_csna_provider_info()
  278 + */
  279 +function theme_csna_providers($vars) {
  280 + $providers = $vars['providers'];
  281 + $items = array();
  282 + foreach ($providers as $provider_id => $provider) {
  283 + $items[] = array(
  284 + 'data' => l($provider['display_title'], 'csna/' . $provider_id, array('html' => TRUE)),
  285 + 'id' => 'csna_provider_' . $provider_id,
  286 + );
  287 + }
  288 +
  289 + return theme('item_list', array('items' => $items, 'attributes' => array('class' => 'csna-items')));
  290 +}
  291 +
  292 +/**
  293 + * Access callback for CSNA complete register.
  294 + *
  295 + * @param $account
  296 + */
  297 +function csna_user_edit_access($account) {
  298 + return $GLOBALS['user']->uid == $account->uid;
  299 +}
... ...
  1 +<?php
  2 +
  3 +/**
  4 + * @file
  5 + * Menu callbacks for the CSNA module.
  6 + */
  7 +
  8 +/**
  9 + * Menu callback: Set email address and password after successful user login
  10 + */
  11 +function csna_complete_register_form($form, &$form_state, $account) {
  12 + global $user;
  13 +
  14 + if ($account->mail) {
  15 + drupal_goto('user');
  16 + }
  17 +
  18 + $form_state['user'] = $account;
  19 +
  20 + $form['mail'] = array(
  21 + '#type' => 'textfield',
  22 + '#title' => t('E-mail address'),
  23 + '#maxlength' => EMAIL_MAX_LENGTH,
  24 + '#description' => t('A valid e-mail address. All e-mails from the system will be sent to this address. The e-mail address is not made public and will only be used if you wish to receive a new password or wish to receive certain news or notifications by e-mail.'),
  25 + '#required' => TRUE,
  26 + );
  27 +
  28 + $form['pass'] = array(
  29 + '#type' => 'password_confirm',
  30 + '#size' => 25,
  31 + '#description' => t('Provide a password for the new account in both fields.'),
  32 + '#required' => TRUE,
  33 + );
  34 +
  35 + $form['submit'] = array(
  36 + '#type' => 'submit',
  37 + '#value' => t('Save'),
  38 + );
  39 +
  40 + return $form;
  41 +}
  42 +
  43 +function csna_complete_register_form_validate($form, &$form_state) {
  44 + $account = $form_state['user'];
  45 +
  46 + // Trim whitespace from mail, to prevent confusing 'e-mail not valid'
  47 + // warnings often caused by cutting and pasting.
  48 + $mail = trim($form_state['values']['mail']);
  49 + form_set_value($form['mail'], $mail, $form_state);
  50 +
  51 + // Validate the e-mail address, and check if it is taken by an existing user.
  52 + if ($error = user_validate_mail($form_state['values']['mail'])) {
  53 + form_set_error('mail', $error);
  54 + }
  55 + elseif ((bool) db_select('users')->fields('users', array('uid'))->condition('uid', $account->uid, '<>')->condition('mail', db_like($form_state['values']['mail']), 'LIKE')->range(0, 1)->execute()->fetchField()) {
  56 + form_set_error('mail', t('The e-mail address %email is already taken.', array('%email' => $form_state['values']['mail'])));
  57 + }
  58 +}
  59 +
  60 +function csna_complete_register_form_submit($form, &$form_state) {
  61 + $account = $form_state['user'];
  62 +
  63 + $edit = array(
  64 + 'mail' => $form_state['values']['mail'],
  65 + 'pass' => $form_state['values']['pass'],
  66 + );
  67 +
  68 + user_save($account, $edit);
  69 +}
  70 +
... ...
  1 +name = CSNA Kaixin
  2 +description = Provide authentication integration for Kaixin.
  3 +package = Authentication
  4 +core = 7.x
  5 +dependencies[] = csna
  6 +configure = admin/config/services/csna
  7 +
  8 +; Information added by Drupal.org packaging script on 2015-10-19
  9 +version = "7.x-1.3"
  10 +core = "7.x"
  11 +project = "csna"
  12 +datestamp = "1445231940"
  13 +
... ...
  1 +<?php
  2 +
  3 +/**
  4 + * @file
  5 + * Uninstall functions for the CSNA Kaixin module.
  6 + */
  7 +
  8 +/**
  9 + * Implements hook_uninstall().
  10 + */
  11 +function csna_kaixin_uninstall() {
  12 + variable_del('csna_kaixin_key');
  13 + variable_del('csna_kaixin_secret');
  14 +}
... ...
  1 +<?php
  2 +
  3 +/**
  4 + * @file
  5 + * The CSNA Kaixin module is a sub-module of the Chinese Social Networks
  6 + * Authentication (CSNA) framework allowing integration with the Kaixin OAuth
  7 + * protocol for Authentication/Login.
  8 + */
  9 +
  10 +/**
  11 + * Implements hook_csna_provider_info().
  12 + */
  13 +function csna_kaixin_csna_provider_info() {
  14 + $providers = array();
  15 + $providers['kaixin'] = array(
  16 + 'title' => t('Kaixin'),
  17 + 'description' => t('Set your <strong>Kaixin authorized KEY</strong> and <strong>SECRET</strong> below.<br/>If you want to use an API key, you can get one at the !keylink.', array('!keylink' => l(t('Kaixin API website'), 'http://open.kaixin001.com/', array('attributes' => array('target' => '_blank'))))),
  18 + 'display_title' => csna_get_kaixin_button_image(),
  19 + 'authorize_uri' => 'http://api.kaixin001.com/oauth2/authorize',
  20 + 'access_token_uri' => 'http://api.kaixin001.com/oauth2/access_token',
  21 + 'info_uri' => 'https://api.kaixin001.com/users/me.json',
  22 + );
  23 + return $providers;
  24 +}
  25 +
  26 +/**
  27 + * Helper function for returning a themed image for the Kaixin display title.
  28 + */
  29 +function csna_get_kaixin_button_image() {
  30 + $image_arr = array(
  31 + 'path' => drupal_get_path('module', 'csna_kaixin') . '/kaixin_135x24.png',
  32 + 'title' => t('Sign in with Kaixin'),
  33 + 'alt' => t('Sign in with Kaixin'),
  34 + );
  35 + return theme('image', $image_arr);
  36 +}
  37 +
  38 +/**
  39 + * Implements hook_csna_provider_callback().
  40 + */
  41 +function csna_kaixin_csna_provider_callback($provider, $request) {
  42 + if (isset($request['code'])) {
  43 + $parameters = array(
  44 + 'client_id' => $provider['key'],
  45 + 'client_secret' => $provider['secret'],
  46 + 'grant_type' => 'authorization_code',
  47 + 'redirect_uri' => $provider['callback'],
  48 + 'code' => $request['code'],
  49 + );
  50 + $http = drupal_http_request(url($provider['access_token_uri'], array('query' => $parameters)));
  51 + $data = json_decode($http->data);
  52 + $http = drupal_http_request(url($provider['info_uri'], array('query' => array('access_token' => $data->access_token))));
  53 + $info = json_decode($http->data);
  54 + if (!isset($info->uid)) {
  55 + return FALSE;
  56 + }
  57 + return array(
  58 + 'access_token' => $data->access_token,
  59 + 'uid' => $info->uid,
  60 + 'name' => $info->name,
  61 + );
  62 + }
  63 +}
... ...
  1 +name = CSNA QQ
  2 +description = Provide authentication integration for QQ.
  3 +package = Authentication
  4 +core = 7.x
  5 +dependencies[] = csna
  6 +configure = admin/config/services/csna
  7 +
  8 +; Information added by Drupal.org packaging script on 2015-10-19
  9 +version = "7.x-1.3"
  10 +core = "7.x"
  11 +project = "csna"
  12 +datestamp = "1445231940"
  13 +
... ...
  1 +<?php
  2 +
  3 +/**
  4 + * @file
  5 + * uninstall functions for the CSNA QQ module.
  6 + */
  7 +
  8 +/**
  9 + * Implements hook_uninstall().
  10 + */
  11 +function csna_qq_uninstall() {
  12 + variable_del('csna_qq_key');
  13 + variable_del('csna_qq_secret');
  14 +}
... ...
  1 +<?php
  2 +
  3 +/**
  4 + * @file
  5 + * The CSNA QQ module is a sub-module of the Chinese Social Networks
  6 + * Authentication (CSNA) framework allowing integration with the QQ OAuth
  7 + * protocol for Authentication/Login.
  8 + */
  9 +
  10 +/**
  11 + * Implements hook_csna_provider_info().
  12 + */
  13 +function csna_qq_csna_provider_info() {
  14 + $providers = array();
  15 +
  16 + $providers['qq'] = array(
  17 + 'title' => t('QQ'),
  18 + 'description' => t('Set your <strong>QQ authorized KEY</strong> and <strong>SECRET</strong> below.<br/>If you want to use an API key, you can get one at the !keylink.', array('!keylink' => l(t('QQ API website'), 'http://connect.qq.com/', array('attributes' => array('target' => '_blank'))))),
  19 + 'display_title' => csna_get_qq_button_image(),
  20 + 'type' => CSNA_OAUTH2,
  21 + 'authorize_uri' => 'https://graph.qq.com/oauth2.0/authorize',
  22 + 'access_token_uri' => 'https://graph.qq.com/oauth2.0/token',
  23 + 'info_uri' => 'https://graph.qq.com/user/get_user_info',
  24 + );
  25 +
  26 + return $providers;
  27 +}
  28 +
  29 +/**
  30 + * Helper function for returning a themed image for the QQ display title.
  31 + */
  32 +function csna_get_qq_button_image() {
  33 + $image_arr = array(
  34 + 'path' => drupal_get_path('module', 'csna_qq') . '/qq_120x24.png',
  35 + 'title' => t('Sign in with QQ'),
  36 + 'alt' => t('Sign in with QQ'),
  37 + );
  38 + return theme('image', $image_arr);
  39 +}
  40 +
  41 +/**
  42 + * Implements hook_csna_provider_callback().
  43 + */
  44 +function csna_qq_csna_provider_callback($provider, $request) {
  45 + if (isset($request['code'])) {
  46 + $parameters = array(
  47 + 'client_id' => $provider['key'],
  48 + 'client_secret' => $provider['secret'],
  49 + 'grant_type' => 'authorization_code',
  50 + 'redirect_uri' => $provider['callback'],
  51 + 'code' => $request['code'],
  52 + );
  53 +
  54 + $param_data = array(
  55 + 'method' => 'POST',
  56 + 'data' => drupal_http_build_query($parameters),
  57 + );
  58 +
  59 + $http = drupal_http_request(url($provider['access_token_uri'], array('query' => $parameters)), $param_data);
  60 + $data = explode('&', $http->data);
  61 + $data = explode('=', reset($data));
  62 + $http = drupal_http_request('https://graph.qq.com/oauth2.0/me?' . $http->data);
  63 + preg_match('/\{[^\}]*\}/', $http->data, $obj);
  64 + $openid = json_decode($obj[0]);
  65 + $http = drupal_http_request(url($provider['info_uri'], array(
  66 + 'query' => array(
  67 + 'access_token' => $data[1],
  68 + 'oauth_consumer_key' => $provider['key'],
  69 + 'openid' => $openid->openid,))));
  70 + $info = json_decode($http->data);
  71 + return array(
  72 + 'access_token' => $data[1],
  73 + 'uid' => $openid->openid,
  74 + 'name' => $info->nickname,
  75 + 'avatar_link' => $info->figureurl_qq_2,
  76 + );
  77 + }
  78 +}
... ...
  1 +name = CSNA Renren
  2 +description = Provide authentication integration for Renren.
  3 +package = Authentication
  4 +core = 7.x
  5 +dependencies[] = csna
  6 +configure = admin/config/services/csna
  7 +
  8 +; Information added by Drupal.org packaging script on 2015-10-19
  9 +version = "7.x-1.3"
  10 +core = "7.x"
  11 +project = "csna"
  12 +datestamp = "1445231940"
  13 +
... ...
  1 +<?php
  2 +
  3 +/**
  4 + * @file
  5 + * uninstall functions for the CSNA Renren module.
  6 + */
  7 +
  8 +/**
  9 + * Implements hook_uninstall().
  10 + */
  11 +function csna_renren_uninstall() {
  12 + variable_del('csna_renren_key');
  13 + variable_del('csna_renren_secret');
  14 +}
... ...
  1 +<?php
  2 +
  3 +/**
  4 + * @file
  5 + * The CSNA Renren module is a sub-module of the Chinese Social Networks
  6 + * Authentication (CSNA) framework allowing integration with the Renren OAuth
  7 + * protocol for Authentication/Login.
  8 + */
  9 +
  10 +/**
  11 + * Implements hook_csna_provider_info().
  12 + */
  13 +function csna_renren_csna_provider_info() {
  14 + $providers = array();
  15 +
  16 + $providers['renren'] = array(
  17 + 'title' => t('Renren'),
  18 + 'description' => t('Set your <strong>Renren authorized KEY</strong> and <strong>SECRET</strong> below.<br/>If you want to use an API key, you can get one at the !keylink.', array('!keylink' => l(t('Renren API website'), 'http://dev.renren.com/website', array('attributes' => array('target' => '_blank'))))),
  19 + 'display_title' => csna_get_renren_button_image(),
  20 + 'authorize_uri' => 'https://graph.renren.com/oauth/authorize',
  21 + 'access_token_uri' => 'https://graph.renren.com/oauth/token',
  22 + 'active' => TRUE,
  23 + );
  24 +
  25 + return $providers;
  26 +}
  27 +
  28 +/**
  29 + * Helper function for returning a themed image for the Renren display title.
  30 + */
  31 +function csna_get_renren_button_image() {
  32 + $image_arr = array(
  33 + 'path' => drupal_get_path('module', 'csna_renren') . '/renren_133x28.png',
  34 + 'title' => t('Sign in with Renren'),
  35 + 'alt' => t('Sign in with Renren'),
  36 + );
  37 + return theme('image', $image_arr);
  38 +}
  39 +
  40 +/**
  41 + * Implements hook_csna_provider_callback().
  42 + */
  43 +function csna_renren_csna_provider_callback($provider, $request) {
  44 + if (isset($request['code'])) {
  45 + $parameters = array(
  46 + 'client_id' => $provider['key'],
  47 + 'client_secret' => $provider['secret'],
  48 + 'grant_type' => 'authorization_code',
  49 + 'redirect_uri' => $provider['callback'],
  50 + 'code' => $request['code'],
  51 + );
  52 +
  53 + $param_data = array(
  54 + 'method' => 'POST',
  55 + 'data' => drupal_http_build_query($parameters),
  56 + );
  57 +
  58 + $http = drupal_http_request(url($provider['access_token_uri'], array('query' => $parameters)), $param_data);
  59 + $data = json_decode($http->data);
  60 + if (!isset($data->user->id)) {
  61 + return FALSE;
  62 + }
  63 + return array(
  64 + 'access_token' => $data->access_token,
  65 + 'uid' => $data->user->id,
  66 + 'name' => $data->user->name,
  67 + );
  68 + }
  69 +}
... ...
  1 +name = CSNA Wechat
  2 +description = Provide authentication integration for Wechat.
  3 +package = Authentication
  4 +core = 7.x
  5 +dependencies[] = csna
  6 +configure = admin/config/services/csna
  7 +
  8 +; Information added by Drupal.org packaging script on 2015-10-19
  9 +version = "7.x-1.3"
  10 +core = "7.x"
  11 +project = "csna"
  12 +datestamp = "1445231940"
  13 +
... ...
  1 +<?php
  2 +
  3 +/**
  4 + * @file
  5 + * uninstall functions for the CSNA Wechat module.
  6 + */
  7 +
  8 +/**
  9 + * Implements hook_uninstall().
  10 + */
  11 +function csna_wechat_uninstall() {
  12 + variable_del('csna_wechat_key');
  13 + variable_del('csna_wechat_secret');
  14 +}
... ...
  1 +<?php
  2 +
  3 +/**
  4 + * @file
  5 + * The CSNA Wechat module is a sub-module of the Chinese Social Networks
  6 + * Authentication (CSNA) framework allowing integration with the Wechat OAuth
  7 + * protocol for Authentication/Login.
  8 + */
  9 +
  10 +/**
  11 + * Implements hook_csna_provider_info().
  12 + */
  13 +function csna_wechat_csna_provider_info() {
  14 + $providers = array();
  15 +
  16 + $providers['wechat'] = array(
  17 + 'title' => t('Wechat'),
  18 + 'description' => t('Set your <strong>Wechat authorized KEY</strong> and <strong>SECRET</strong> below.<br/>If you want to use an API key, you can get one at the !keylink.', array('!keylink' => l(t('Wechat API website'), 'https://open.weixin.qq.com/', array('attributes' => array('target' => '_blank'))))),
  19 + 'display_title' => csna_get_wechat_button_image(),
  20 + 'type' => CSNA_OAUTH2,
  21 + 'authorize_uri' => 'https://open.weixin.qq.com/connect/qrconnect',
  22 + 'access_token_uri' => 'https://api.weixin.qq.com/sns/oauth2/access_token',
  23 + 'info_uri' => 'https://api.weixin.qq.com/sns/userinfo',
  24 + );
  25 +
  26 + return $providers;
  27 +}
  28 +
  29 +/**
  30 + * Helper function for returning a themed image for the Wechat display title.
  31 + */
  32 +function csna_get_wechat_button_image() {
  33 + $image_arr = array(
  34 + 'path' => drupal_get_path('module', 'csna_wechat') . '/wechat_120x24.png',
  35 + 'title' => t('Sign in with Wechat'),
  36 + 'alt' => t('Sign in with Wechat'),
  37 + );
  38 + return theme('image', $image_arr);
  39 +}
  40 +
  41 +/**
  42 + * Implements hook_csna_provider_callback().
  43 + */
  44 +function csna_wechat_csna_provider_callback($provider, $request) {
  45 + if (isset($request['code'])) {
  46 + $parameters = array(
  47 + 'appid' => $provider['key'],
  48 + 'secret' => $provider['secret'],
  49 + 'grant_type' => 'authorization_code',
  50 + 'code' => $request['code'],
  51 + );
  52 +
  53 + $param_data = array(
  54 + 'method' => 'POST',
  55 + 'data' => drupal_http_build_query($parameters),
  56 + );
  57 +
  58 + $http = drupal_http_request(url($provider['access_token_uri'], array('query' => $parameters)), $param_data);
  59 + $data = json_decode($http->data);
  60 + $http = drupal_http_request(url($provider['info_uri'], array('query' => array('access_token' => $data->access_token, 'openid' => $data->openid))));
  61 + $info = json_decode($http->data);
  62 + if (!isset($info->openid)) {
  63 + return FALSE;
  64 + }
  65 + return array(
  66 + 'access_token' => $data->access_token,
  67 + 'uid' => $info->openid,
  68 + 'name' => $info->nickname,
  69 + );
  70 + }
  71 +}
... ...
  1 +name = CSNA Weibo
  2 +description = Provide authentication integration for Weibo.
  3 +package = Authentication
  4 +core = 7.x
  5 +dependencies[] = csna
  6 +configure = admin/config/services/csna
  7 +
  8 +; Information added by Drupal.org packaging script on 2015-10-19
  9 +version = "7.x-1.3"
  10 +core = "7.x"
  11 +project = "csna"
  12 +datestamp = "1445231940"
  13 +
... ...
  1 +<?php
  2 +
  3 +/**
  4 + * @file
  5 + * uninstall functions for the CSNA Weibo module.
  6 + */
  7 +
  8 +/**
  9 + * Implements hook_uninstall().
  10 + */
  11 +function csna_weibo_uninstall() {
  12 + variable_del('csna_weibo_key');
  13 + variable_del('csna_weibo_secret');
  14 +}
... ...
  1 +<?php
  2 +/**
  3 + * @file
  4 + * The CSNA Weibo module is a sub-module of the Chinese Social Networks
  5 + * Authentication (CSNA) framework allowing integration with the Weibo OAuth
  6 + * protocol for Authentication/Login.
  7 + */
  8 +
  9 +/**
  10 + * Implements hook_csna_provider_info().
  11 + */
  12 +function csna_weibo_csna_provider_info() {
  13 + $providers = array();
  14 +
  15 + $providers['weibo'] = array(
  16 + 'title' => t('Weibo Sina'),
  17 + 'description' => t('Set your <strong>Sina Weibo authorized KEY</strong> and <strong>SECRET</strong> below.<br/>If you want to use an API key, you can get one at the !keylink.', array('!keylink' => l(t('Sina Weibo API website'), 'http://open.weibo.com/', array('attributes' => array('target' => '_blank'))))),
  18 + 'display_title' => csna_get_weibo_button_image(),
  19 + 'type' => CSNA_OAUTH2,
  20 + 'authorize_uri' => 'https://api.weibo.com/oauth2/authorize',
  21 + 'access_token_uri' => 'https://api.weibo.com/oauth2/access_token',
  22 + 'info_uri' => 'https://api.weibo.com/2/users/show.json',
  23 + );
  24 +
  25 + return $providers;
  26 +}
  27 +
  28 +/**
  29 + * Helper function for returning a themed image for the Weibo display title.
  30 + */
  31 +function csna_get_weibo_button_image() {
  32 + $image_arr = array(
  33 + 'path' => drupal_get_path('module', 'csna_weibo') . '/weibo_126x24.png',
  34 + 'title' => t('Sign in with Weibo'),
  35 + 'alt' => t('Sign in with Weibo'),
  36 + );
  37 + return theme('image', $image_arr);
  38 +}
  39 +
  40 +/**
  41 + * Implements hook_csna_provider_callback().
  42 + */
  43 +function csna_weibo_csna_provider_callback($provider, $request) {
  44 + if (isset($request['code'])) {
  45 + $parameters = array(
  46 + 'client_id' => $provider['key'],
  47 + 'client_secret' => $provider['secret'],
  48 + 'grant_type' => 'authorization_code',
  49 + 'redirect_uri' => $provider['callback'],
  50 + 'code' => $request['code'],
  51 + );
  52 +
  53 + $param_data = array(
  54 + 'method' => 'POST',
  55 + 'data' => drupal_http_build_query($parameters),
  56 + );
  57 +
  58 + $http = drupal_http_request(url($provider['access_token_uri'], array('query' => $parameters)), $param_data);
  59 + $data = json_decode($http->data);
  60 + $http = drupal_http_request(url($provider['info_uri'], array('query' => array('access_token' => $data->access_token, 'uid' => $data->uid))));
  61 + $info = json_decode($http->data);
  62 + if (!isset($info->id)) {
  63 + return FALSE;
  64 + }
  65 + return array(
  66 + 'access_token' => $data->access_token,
  67 + 'uid' => $info->id,
  68 + 'name' => $info->name,
  69 + 'avatar_link' => $info->avatar_large,
  70 + );
  71 + }
  72 +}
... ...
  1 +csna_require_email: true
  2 +user_picture_path: pictures
... ...
  1 +<?php
  2 +/**
  3 + * @file
  4 + * API documentation for the Chinese Social Networks Authentication module.
  5 + */
  6 +
  7 +use Drupal\core\Url;
  8 +use GuzzleHttp\Exception\RequestException;
  9 +
  10 +/**
  11 + * Define Authentication providers available to the CSNA framework.
  12 + *
  13 + * The Chinese Social Networks Authentication (CSNA) module uses this hook to
  14 + * gather information on provider authentication methods defined by enabled
  15 + * modules. These methods depend on a variety of properties used by CSNA to
  16 + * integrate with third party API providers based on the OAuth protocol.
  17 + *
  18 + * By default CSNA supports the following Authentication API providers through
  19 + * sub-modules:
  20 + * - Sina weibo (新浪微博), Chinese twitter like website.
  21 + * - Tencent (QQ), biggest Chinese IM provider.
  22 + * - Renren(人人网), biggest Chinese facebook like website.
  23 + * - Kaixin001(开心网), secondary Chinese facebook like website.
  24 + *
  25 + * This hook allows other modules to define custom authentication third party
  26 + * API providers by defining all the necessary information for CSNA's
  27 + * implementation of the OAuth protocol.
  28 + *
  29 + * @return array
  30 + * An array of providers keyed by provider_id with the following properties:
  31 + * - title: The title or name of the defined provider.
  32 + * - description: Description text to appear on the admin page for the
  33 + * configuration of the required parameters for this specific provider,
  34 + * such as Authentication API KEY or Password.
  35 + * - display_title: The title to be displayed in the list of links of
  36 + * providers returned by theme_csna_providers, which displays in the user
  37 + * login/registration forms and block. For better usage, HTML is allowed
  38 + * for this property, for example to display an image or logo.
  39 + * - type: string identifying the type of OAuth protocol used. By default,
  40 + * CSNA provides a constant for 'oauth2', see CSNA_OAUTH2, but any other
  41 + * custom OAuth type could also be used and provided for this property.
  42 + * - authorize_uri: The URL used by providers to authenticate users through
  43 + * the OAuth protocol.
  44 + * - access_token_uri: The URL used by CSNA to get the authentication token
  45 + * returned by providers if operation was successful.
  46 + * - info_uri: This URL allows capturing User's information from third party
  47 + * authentication providers, such as username, or other useful information.
  48 + *
  49 + * @see csna_providers()
  50 + * @see csna_weibo_csna_provider_info()
  51 + */
  52 +function hook_csna_provider_info() {
  53 + // Example taken from the csna_weibo sub-module.
  54 + $providers = array();
  55 +
  56 + $providers['weibo'] = array(
  57 + 'title' => t('Weibo Sina'),
  58 + 'description' => t('Set your Sina Weibo authorized KEY and SECRET below.'),
  59 + 'display_title' => csna_get_weibo_button_image(),
  60 + 'type' => CSNA_OAUTH2,
  61 + 'authorize_uri' => 'https://api.weibo.com/oauth2/authorize',
  62 + 'access_token_uri' => 'https://api.weibo.com/oauth2/access_token',
  63 + 'info_uri' => 'https://api.weibo.com/2/users/show.json',
  64 + );
  65 +
  66 + return $providers;
  67 +}
  68 +
  69 +/**
  70 + * Allows other modules to alter already defined list of providers.
  71 + *
  72 + * Any of the providers and any of their properties or values can be modified
  73 + * by using an implementation of this hook.
  74 + *
  75 + * @param array $providers
  76 + * An associative array of providers keyed by the provider_id, as returned by
  77 + * the function csna_providers(). See hook_csna_provider_info for a detailed
  78 + * list of all the defined and required properties for each provider.
  79 + *
  80 + * @see hook_csna_provider_info()
  81 + * @see csna_providers()
  82 + */
  83 +/*function hook_csna_provider_info_alter(&$providers) {
  84 + if (isset($providers['weibo'])) {
  85 + $providers['weibo']['display_title'] = t("Login or register with your Sina Weibo account!");
  86 + }
  87 +}
  88 +*/
  89 +/**
  90 + * Define providers custom authentication callback methods.
  91 + *
  92 + * The implementation of this hook is usually required when defining a Third
  93 + * Party authentication OAuth API provider through hook_csna_provider_info.
  94 + *
  95 + * This hook callback is executed when returning from provider's API
  96 + * authentication pages, with information about the operation, such as whether
  97 + * it was successful or not. In case of success, most providers will return a
  98 + * token or code that can be further used to verify or obtain user's
  99 + * information through the $provider['info_uri'] defined URL.
  100 + *
  101 + * @param array $provider
  102 + * An array of properties for the corresponding provider defined through
  103 + * hook_csna_provider_info, see API hooks documentation for more information.
  104 + * @param array $request
  105 + * A PHP predefined variable for HTTP Request variables: $_REQUEST, received
  106 + * from the third party authentication provider.
  107 + *
  108 + * @return array
  109 + * An array of properties including the following keys and values:
  110 + * - access_token: The access token returned by the provider through its
  111 + * access_token_uri URL to provider further access to user's information if
  112 + * authentication was successful.
  113 + * - uid: The ID of the user returned from the provider used to load user
  114 + * account through user_external_load (see core API).
  115 + * - name: The user name returned from the provider used to load user account
  116 + * account through user_load_by_name (see core API).
  117 + *
  118 + * @see csna_callback()
  119 + * @see csna_kaixin_csna_provider_callback()
  120 + */
  121 +function hook_csna_provider_callback($provider, $request) {
  122 + // Example taken from the csna_kaixin sub-module.
  123 + if (isset($request['code'])) {
  124 + $parameters = array(
  125 + 'client_id' => $provider['key'],
  126 + 'client_secret' => $provider['secret'],
  127 + 'grant_type' => 'authorization_code',
  128 + 'redirect_uri' => $provider['callback'],
  129 + 'code' => $request['code'],
  130 + );
  131 + $client = \Drupal::httpClient();
  132 + $request = $client->request('GET', Url::fromUri($provider['access_token_uri'], array('query' => $parameters)));
  133 + $response_data = '';
  134 + try {
  135 + $response = $client->send($request);
  136 + // Expected result.
  137 + $response_data = $response->getBody();
  138 + }
  139 + catch (RequestException $e) {
  140 + }
  141 + $data = json_decode($response_data);
  142 + $request = $client->request('GET', Url::fromUri($provider['info_uri'], array('query' => array('access_token' => $data->access_token))));
  143 + try {
  144 + $response = $client->send($request);
  145 + // Expected result.
  146 + $response_data = $response->getBody();
  147 + }
  148 + catch (RequestException $e) {
  149 + }
  150 + $info = json_decode($response_data);
  151 + if (!isset($info->uid)) {
  152 + return FALSE;
  153 + }
  154 + return array(
  155 + 'access_token' => $data->access_token,
  156 + 'uid' => $info->uid,
  157 + 'name' => $info->name,
  158 + );
  159 + }
  160 + return FALSE;
  161 +}
... ...
  1 +name: 'CSNA'
  2 +type: module
  3 +description: 'Authentication for Chinese Social Networks.'
  4 +package: Authentication
  5 +configure: csna.settings
  6 +core: 8.x
\ No newline at end of file
... ...
  1 +csna.admin:
  2 + title: 'Chinese Social Networks Authentication settings (CSNA)'
  3 + description: 'Configure the CSNA key or secrect code settings for third party authentication API providers.'
  4 + parent: system.admin_config_development
  5 + route_name: csna.config
  6 + weight: 100
  7 +csna.callback:
  8 + title: 'Authentication callback'
  9 + route_name: csna.callback
... ...
  1 +<?php
  2 +
  3 +use Drupal\Core\Url;
  4 +use Drupal\Core\Form\FormStateInterface;
  5 +
  6 +/**
  7 + * Returns an array of OAuth Third Party authentication providers.
  8 + *
  9 + * CSNA's API Framework provides a method for any enabled module to define
  10 + * additional authentication providers. This function gathers information on
  11 + * provider authentication methods defined by enabled modules.
  12 + *
  13 + * @param bool $valid
  14 + * @return array An associative array of providers keyed by the provider_id.
  15 + * An associative array of providers keyed by the provider_id.
  16 + * @see hook_csna_provider_info()
  17 + */
  18 +function csna_providers($valid = FALSE) {
  19 + static $providers;
  20 +
  21 + if (!isset($providers)) {
  22 + $providers = array();
  23 +
  24 + // Build the providers array, including module names for the purpose
  25 + // of including files if necessary.
  26 + // An associative array of providers objects keyed by the provider_id.
  27 + $module_handler = \Drupal::moduleHandler();
  28 +
  29 + foreach ($module_handler->getImplementations('csna_provider_info') as $module) {
  30 + foreach ($module_handler->invoke($module, 'csna_provider_info') as $provider_id => $provider) {
  31 + $config = \Drupal::config('csna.' . $provider);
  32 + $provider['provider_id'] = $provider_id;
  33 + $provider['module'] = $module;
  34 + $provider['key'] = $config->get('csna_' . $provider_id . '_key');
  35 + $provider['secret'] = $config->get('csna_' . $provider_id . '_secret');
  36 + $providers[$provider_id] = $provider;
  37 + if ($valid && (empty($provider['key']) || empty($provider['secret']))) {
  38 + unset($providers[$provider_id]);
  39 + }
  40 + }
  41 + }
  42 +
  43 + $module_handler->alter('csna_provider_info', $providers);
  44 +
  45 + foreach ($providers as $provider_id => & $provider) {
  46 + $defaults = array(
  47 + 'provider_id' => $provider_id,
  48 + 'base' => $provider_id,
  49 + 'title' => '',
  50 + 'description' => '',
  51 + 'active' => FALSE,
  52 + 'callback' => Url::fromRoute('csna.callback',array('csna_provider' => $provider_id), array('absolute' => TRUE)),
  53 + 'file' => '',
  54 + );
  55 +
  56 + $provider += $defaults;
  57 +
  58 + // Default the display title to the title if necessary. The display
  59 + // title is used in instances where the login method has an official
  60 + // name but a different method of display on selection forms (like some
  61 + // text and a set of images).
  62 + if (empty($provider['display_title'])) {
  63 + $provider['display_title'] = $provider['title'];
  64 + }
  65 +
  66 + // Default the short title to the title if necessary. Like the display
  67 + // title, the short title is an alternate way of displaying the title to
  68 + // the user consisting of plain text but with unnecessary information
  69 + // stripped off.
  70 + if (empty($provider[$provider_id]['short_title'])) {
  71 + $provider['short_title'] = $provider['title'];
  72 + }
  73 + }
  74 + }
  75 +
  76 + return $providers;
  77 +}
  78 +
  79 +
  80 +function csna_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  81 + //$form_id == 'user_login' || $form_id == 'user_login_block' || $form_id == 'user_register_form'
  82 + if ( $form_id == 'user_login_form' ) {
  83 + $providers = csna_providers();
  84 +
  85 + // if admin form
  86 + if (empty($form['administer_users']['#value'])) {
  87 + $csna_provider = array(
  88 + '#theme' => 'csna_providers',
  89 + '#attributes' => array('providers' => $providers),
  90 + );
  91 +
  92 + if (isset($form['submitted']['user_login_block']['#suffix']) && !empty($form['submitted']['user_login_block']['#suffix'])) {
  93 + $form['submitted']['user_login_block']['#suffix'] .= drupal_render($csna_provider);
  94 + }
  95 + else {
  96 + $form['submitted']['user_login_block']['#suffix'] = drupal_render($csna_provider);
  97 + }
  98 + }
  99 + }
  100 + dpm($form_id);
  101 + // dpm($form);
  102 +}
  103 +/**
  104 + * Implements hook_theme().
  105 + */
  106 +function csna_theme($existing, $type, $theme, $path) {
  107 + $providers = csna_providers();
  108 + return array(
  109 + 'csna_providers' => array(
  110 + 'variables' => array('providers' => $providers),
  111 + ),
  112 + );
  113 +}
  114 +
  115 +
  116 +
  117 +/**
  118 + * Render a themed list of links to providers authorized login URL pages.
  119 + *
  120 + * @param array $providers
  121 + * An associative array of providers keyed by the provider_id, as returned by
  122 + * the function csna_providers().
  123 + * Mostly the display_title property of providers is used in this function
  124 + * to display a custom title, name or even HTML to be linked to corresponding
  125 + * provider's authorized login URL page. See API documentation for more
  126 + * information on providers available properties.
  127 + *
  128 + * @see csna_providers()
  129 + * @see hook_csna_provider_info()
  130 + */
  131 +function template_preprocess_csna_providers(&$vars) {
  132 + dpm($vars);
  133 + $providers = $vars['providers'];
  134 + $items = array();
  135 + foreach ($providers as $provider_id => $provider) {
  136 + $items[] = array(
  137 + 'data' => \Drupal::l($provider['display_title'], Url::fromRoute('csna.redirect', array('csna_provider' => $provider_id), array('html' => TRUE))),
  138 + 'id' => 'csna_provider_' . $provider_id,
  139 + );
  140 + }
  141 +
  142 + $item_list = array(
  143 + '#type' => 'item_list',
  144 + 'items' => $items,
  145 + 'attributes' => array('class' => 'csna-items'),
  146 + );
  147 + return drupal_render($item_list);
  148 +}
... ...
  1 +csna.config:
  2 + path: '/admin/config/services/csna'
  3 + defaults:
  4 + _title: 'Chinese Social Networks Authentication settings (CSNA)'
  5 + _form: '\Drupal\csna\Form\SettingsForm'
  6 + options:
  7 + _admin_route: TRUE
  8 + requirements:
  9 + _permission: 'administer site configuration'
  10 +csna.redirect:
  11 + path: 'csna/{csna_provider}'
  12 + defaults:
  13 + _controller: '\Drupal\csna\Controller\CsnaController::csna_redirect'
  14 + _title: 'Authentication redirect'
  15 +
  16 +csna.callback:
  17 + path: '/csna/{csna_provider}/callback'
  18 + defaults:
  19 + _controller: '\Drupal\csna\Controller\CsnaController::csna_callback'
  20 + _title: 'Authentication callback'
  21 + requirements:
  22 + _access: 'user_is_anonymous'
... ...
  1 +csna_qq_key: ''
  2 +csna_qq_secret: ''
\ No newline at end of file
... ...
  1 +name: 'CSNA QQ'
  2 +type: module
  3 +description: 'Provide authentication integration for QQ.'
  4 +package: Authentication
  5 +dependencies[] : csna
  6 +configure: csna.settings
  7 +core: 8.x
\ No newline at end of file
... ...
  1 +<?php
  2 +
  3 +use Drupal\Core\Url;
  4 +
  5 +/**
  6 + * @file
  7 + * The CSNA QQ module is a sub-module of the Chinese Social Networks
  8 + * Authentication (CSNA) framework allowing integration with the QQ OAuth
  9 + * protocol for Authentication/Login.
  10 + */
  11 +
  12 +/**
  13 + * Implements hook_csna_provider_info().
  14 + */
  15 +function csna_qq_csna_provider_info() {
  16 + $providers = array();
  17 +
  18 + $providers['qq'] = array(
  19 + 'title' => t('QQ'),
  20 + 'description' => t('Set your <strong>QQ authorized KEY</strong> and <strong>SECRET</strong> below.<br/>If you want to use an API key, you can get one at the !keylink.', array('!keylink' => \Drupal::l(t('QQ API website'), Url::fromUri('http://connect.qq.com/', array('attributes' => array('target' => '_blank')))))),
  21 + 'display_title' => csna_get_qq_button_image(),
  22 + 'type' => CSNA_OAUTH2,
  23 + 'authorize_uri' => 'https://graph.qq.com/oauth2.0/authorize',
  24 + 'access_token_uri' => 'https://graph.qq.com/oauth2.0/token',
  25 + 'info_uri' => 'https://graph.qq.com/user/get_user_info',
  26 + );
  27 +
  28 + return $providers;
  29 +}
  30 +
  31 +/**
  32 + * Helper function for returning a themed image for the QQ display title.
  33 + */
  34 +function csna_get_qq_button_image() {
  35 + $image_arr = array(
  36 + 'path' => drupal_get_path('module', 'csna_qq') . '/qq_120x24.png',
  37 + 'title' => t('Sign in with QQ'),
  38 + 'alt' => t('Sign in with QQ'),
  39 + );
  40 + //return theme('image', $image_arr);
  41 + return '';
  42 +}
\ No newline at end of file
... ...
  1 +<?php
  2 +/**
  3 + * @file
  4 + *Contains \Drupal\csna\Controller\CsnaController.
  5 + */
  6 +
  7 +namespace Drupal\csna\Controller;
  8 +
  9 +use Drupal\Core\Controller\ControllerBase;
  10 +use Symfony\Component\HttpFoundation\RedirectResponse;
  11 +
  12 +class CsnaController extends ControllerBase
  13 +{
  14 +
  15 + /**
  16 + * Menu callback: CSNA Redirect.
  17 + */
  18 + function csna_redirect( $provider )
  19 + {
  20 + $parameters = array(
  21 + 'client_id' => $provider['key'],
  22 + 'redirect_uri' => $provider['callback'],
  23 + 'response_type' => 'code',
  24 + );
  25 + if ($provider['provider_id'] == 'wechat') {
  26 + unset($parameters['client_id']);
  27 + $parameters['appid'] = $provider['key'];
  28 + $parameters['scope'] = 'snsapi_login';
  29 + }
  30 + return new RedirectResponse(\Drupal::url($provider['authorize_uri'], array('query' => $parameters)));
  31 + }
  32 +
  33 + /**
  34 + * @param $provider
  35 + */
  36 + public function csna_callback( $provider )
  37 + {
  38 + global $user;
  39 + $module_handler = \Drupal::moduleHandler();
  40 + $data = $module_handler->invoke($provider['module'], 'csna_provider_callback', array($provider, $_REQUEST));
  41 +
  42 + // Forcing array format because of Sina weibo will return an Object.
  43 + if (!is_array($data)) {
  44 + $data = (array) $data;
  45 + }
  46 +
  47 + if (isset($data['access_token'])) {
  48 + $identity = $provider['provider_id'] . '_' . $data['uid'];
  49 + $account = user_external_load($identity);
  50 +
  51 + if (!isset($account->uid)) {
  52 + $name = $data['name'];
  53 + $ac = user_load_by_name($name);
  54 + if ($ac) {
  55 + $separator = '_';
  56 + $i = 0;
  57 + do {
  58 + $i++;
  59 + $name = $data['name'] . $separator . $i;
  60 + } while (user_load_by_name($name));
  61 + }
  62 + //User avatar
  63 + if (isset($data['avatar_link'])) {
  64 + $avatar_directory = file_default_scheme() . '://' . variable_get('user_picture_path', 'pictures');
  65 + $avatar = system_retrieve_file($data['avatar_link'], $avatar_directory, TRUE, FILE_EXISTS_RENAME);
  66 + }
  67 + $edit = array(
  68 + 'name' => $name,
  69 + 'status' => 1,
  70 + 'picture' => isset($avatar->fid) ? $avatar->fid : '',
  71 + );
  72 + $account = user_save(NULL, $edit);
  73 + user_set_authmaps($account, array('authname_csna' => $identity));
  74 + }
  75 +
  76 + csna_execute_user_login($account);
  77 +
  78 + if (variable_get('csna_require_email', TRUE) && empty($account->mail)) {
  79 + drupal_goto('csna/' . $account->uid . '/complete-register');
  80 + }
  81 + }
  82 + drupal_goto('user');
  83 + }
  84 +}
  85 +
... ...
  1 +<?php
  2 +
  3 +/**
  4 + * @file
  5 + * Contains \Drupal\csna\Form\SettingsForm.
  6 + */
  7 +
  8 +namespace Drupal\csna\Form;
  9 +
  10 +use Drupal\Core\Form\ConfigFormBase;
  11 +use Symfony\Component\HttpFoundation\Request;
  12 +use Drupal\Core\Form\FormStateInterface;
  13 +use Drupal\Core\Url;
  14 +
  15 +/**
  16 + * Defines a form that configures csna settings.
  17 + */
  18 +class SettingsForm extends ConfigFormBase {
  19 + /**
  20 + * {@inheritdoc}
  21 + */
  22 + public function getFormId() {
  23 + return 'csna_admin_settings_form';
  24 + }
  25 +
  26 + /**
  27 + * {@inheritdoc}
  28 + */
  29 + protected function getEditableConfigNames() {
  30 + return [
  31 + 'csna.settings',
  32 + ];
  33 + }
  34 +
  35 + /**
  36 + * {@inheritdoc}
  37 + */
  38 + public function buildForm(array $form, FormStateInterface $form_state, Request $request = NULL) {
  39 + $providers = csna_providers();
  40 + foreach ($providers as $provider_id => $provider) {
  41 + $config = \Drupal::config('csna.' . $provider);
  42 + $form[$provider_id] = array(
  43 + '#type' => 'fieldset',
  44 + '#title' => $provider['title'],
  45 + '#description' => $provider['description'],
  46 + );
  47 + $form[$provider_id]['csna_' . $provider_id . '_key'] = array(
  48 + '#type' => 'textfield',
  49 + '#title' => t('Key'),
  50 + '#size' => 40,
  51 + '#maxlength' => 255,
  52 + '#default_value' => $config->get('csna_' . $provider_id . '_key'),
  53 + );
  54 + $form[$provider_id]['csna_' . $provider_id . '_secret'] = array(
  55 + '#type' => 'textfield',
  56 + '#title' => t('Secret'),
  57 + '#size' => 40,
  58 + '#maxlength' => 255,
  59 + '#default_value' => $config->get('csna_' . $provider_id . '_secret'),
  60 + );
  61 + }
  62 +
  63 + // If no provider/sub-module was found, provide a default help text.
  64 + if (!isset($form)) {
  65 + $form['default_message'] = array(
  66 + '#markup' => t('<strong>No CSNA third party API provider module has been enabled yet</strong>.<br/>Please enable <strong>at least a CSNA sub-module</strong> or any other <strong>CSNA API provider</strong> from the !modadminlink then feel free to browse this page again.<br/>See more information on !projectlink about <strong>supported providers</strong> and <strong>installation instructions</strong>.', array(
  67 + '!modadminlink' => \Drupal::l(t('module administration page'), Url::fromRoute('system.modules_list')),
  68 + '!projectlink' => \Drupal::l(t("module project's page"), Url::fromUri('http://drupal.org/project/csna', array('attributes' => array('target' => '_blank')))),
  69 + )),
  70 + );
  71 + return parent::buildForm($form, $form_state);
  72 + }
  73 + else {
  74 + $config = \Drupal::config('csna.settings');
  75 + $form['csna_require_email'] = array(
  76 + '#type' => 'checkbox',
  77 + '#title' => t('Require email'),
  78 + '#description' => t('Require user entering email after successful user login if email hasn\'t been set yet.'),
  79 + '#default_value' => $config->get('csna_require_email'),
  80 + );
  81 +
  82 + return parent::buildForm($form, $form_state);
  83 + }
  84 + }
  85 +
  86 +
  87 + /**
  88 + * {@inheritdoc}
  89 + */
  90 + public function submitForm(array &$form, FormStateInterface $form_state) {
  91 + parent::submitForm($form, $form_state);
  92 + $providers = csna_providers();
  93 + foreach ($providers as $provider_id => $provider) {
  94 + $config_providers = \Drupal::service('config.factory')->getEditable('csna.' . $provider);
  95 + // Let active plugins save their settings.
  96 + $config_providers->set('csna_' . $provider_id . '_key', $form_state->getValue('csna_' . $provider_id . '_key'));
  97 + $config_providers->set('csna_' . $provider_id . '_secret', $form_state->getValue('csna_' . $provider_id . '_secret'));
  98 + $config_providers->save();
  99 + }
  100 + $config_settings = \Drupal::service('config.factory')->getEditable('csna.settings');
  101 + $config_settings->set('csna_require_email', $form_state->getValue('csna_require_email'));
  102 + $config_settings->save();
  103 + }
  104 +}
... ...
  1 +<div>
  2 +</div>
\ No newline at end of file
... ...
Please register or login to post a comment