Merge branch 'develop' of https://git.trustie.net/jacknudt/trustieforge into develop
Conflicts: app/api/mobile/apis/courses.rb
This commit is contained in:
commit
ef4eb540c8
2
Gemfile
2
Gemfile
|
@ -4,7 +4,7 @@ unless RUBY_PLATFORM =~ /w32/
|
||||||
# unix-like only
|
# unix-like only
|
||||||
gem 'iconv'
|
gem 'iconv'
|
||||||
if RUBY_PLATFORM =~ /darwin/
|
if RUBY_PLATFORM =~ /darwin/
|
||||||
gem "rmagick", "= 2.15.4" ## osx must be this version
|
# gem "rmagick", "= 2.15.4" ## osx must be this version
|
||||||
elsif RUBY_PLATFORM =~ /linux/
|
elsif RUBY_PLATFORM =~ /linux/
|
||||||
gem "rmagick", "~> 2.13.1" ## centos yum install ImageMagick-devel
|
gem "rmagick", "~> 2.13.1" ## centos yum install ImageMagick-devel
|
||||||
gem 'simple_xlsx_reader'
|
gem 'simple_xlsx_reader'
|
||||||
|
|
|
@ -451,6 +451,8 @@ class AccountController < ApplicationController
|
||||||
eval("code = " + "/^" + home_url.gsub(/\//,"\\\/") + "\\\/*(welcome)?\\\/*(\\\/index\\\/*.*)?\$/")
|
eval("code = " + "/^" + home_url.gsub(/\//,"\\\/") + "\\\/*(welcome)?\\\/*(\\\/index\\\/*.*)?\$/")
|
||||||
if (code=~params[:back_url] || params[:back_url].to_s.include?('lost_password')) && last_login_on != ''
|
if (code=~params[:back_url] || params[:back_url].to_s.include?('lost_password')) && last_login_on != ''
|
||||||
redirect_to user_activities_path(user,host: Setting.host_user)
|
redirect_to user_activities_path(user,host: Setting.host_user)
|
||||||
|
elsif params[:back_url64]
|
||||||
|
redirect_to Base64.urlsafe_decode64(params[:back_url64])
|
||||||
else
|
else
|
||||||
if last_login_on == ''
|
if last_login_on == ''
|
||||||
redirect_to my_account_url
|
redirect_to my_account_url
|
||||||
|
|
|
@ -15,6 +15,7 @@ class ArticleHomepagesController < ApplicationController
|
||||||
@article.homepage_id = User.current.homepage.id
|
@article.homepage_id = User.current.homepage.id
|
||||||
@article.title = params[:article_homepage][:title]
|
@article.title = params[:article_homepage][:title]
|
||||||
@article.content = params[:article_homepage][:content]
|
@article.content = params[:article_homepage][:content]
|
||||||
|
@article.save_attachments_containers(params[:attachments], User.current, true)
|
||||||
if @article.save
|
if @article.save
|
||||||
if params[:set_homepage]
|
if params[:set_homepage]
|
||||||
User.current.homepage.update_attribute(:article_id, @article.id)
|
User.current.homepage.update_attribute(:article_id, @article.id)
|
||||||
|
@ -55,6 +56,7 @@ class ArticleHomepagesController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if @article.save
|
if @article.save
|
||||||
|
Attachment.attach_files(@article, params[:attachments])
|
||||||
redirect_to user_homepages_path(:user_id => User.current.id)
|
redirect_to user_homepages_path(:user_id => User.current.id)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
|
|
@ -772,7 +772,10 @@ class AttachmentsController < ApplicationController
|
||||||
elsif @attachment.container_type == 'Statistic'
|
elsif @attachment.container_type == 'Statistic'
|
||||||
@statistic = @attachment.container
|
@statistic = @attachment.container
|
||||||
else
|
else
|
||||||
unless @attachment.container_type == 'Syllabus' || @attachment.container_type == 'Bid' || @attachment.container_type == 'Organization' || @attachment.container_type == 'HomeworkAttach' || @attachment.container_type == 'Memo' || @attachment.container_type == 'Softapplication' || @attachment.container_type == 'PhoneAppVersion' || @attachment.container_type == 'StudentWorksScore'|| @attachment.container_type == 'StudentWork' || @attachment.container_type == 'Work'|| @attachment.container_type == 'ContestantWork'|| @attachment.container_type == 'Contest' || @attachment.container_type == 'HomeworkBank'
|
unless @attachment.container_type == 'Syllabus' || @attachment.container_type == 'Bid' || @attachment.container_type == 'Organization' || @attachment.container_type == 'HomeworkAttach' ||
|
||||||
|
@attachment.container_type == 'Memo' || @attachment.container_type == 'Softapplication' || @attachment.container_type == 'PhoneAppVersion' ||
|
||||||
|
@attachment.container_type == 'StudentWorksScore'|| @attachment.container_type == 'StudentWork' || @attachment.container_type == 'Work'|| @attachment.container_type == 'ContestantWork'||
|
||||||
|
@attachment.container_type == 'Contest' || @attachment.container_type == 'HomeworkBank' || @attachment.container_type == 'ArticleHomepage'
|
||||||
@project = @attachment.project
|
@project = @attachment.project
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -147,13 +147,21 @@ class MyController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
# 基本资料不完善 @force为false, 完善 @force为true
|
# 基本资料不完善 @force为false, 完善 @force为true
|
||||||
@force = false
|
@force = false
|
||||||
if params[:tip]
|
if params[:tip]
|
||||||
@force = true
|
@force = true
|
||||||
end
|
end
|
||||||
|
|
||||||
@user = User.current
|
@user = User.current
|
||||||
|
|
||||||
|
#是否是Oschina过来的
|
||||||
|
@is_oauth = !!Oschina.find_by_user_id(@user.id)
|
||||||
|
|
||||||
|
#是否没设置过密码
|
||||||
|
@is_set_password = @user.hashed_password.present?
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
lg = @user.login
|
lg = @user.login
|
||||||
@pref = @user.pref
|
@pref = @user.pref
|
||||||
diskfile = disk_filename('User', @user.id)
|
diskfile = disk_filename('User', @user.id)
|
||||||
|
@ -168,6 +176,16 @@ class MyController < ApplicationController
|
||||||
@user.pref.attributes = params[:pref]
|
@user.pref.attributes = params[:pref]
|
||||||
@user.pref[:no_self_notified] = (params[:no_self_notified] == '1')
|
@user.pref[:no_self_notified] = (params[:no_self_notified] == '1')
|
||||||
@user.login = params[:login].strip
|
@user.login = params[:login].strip
|
||||||
|
|
||||||
|
if @is_oauth && !@user.mail.present?
|
||||||
|
@user.mail = params[:user][:mail]
|
||||||
|
end
|
||||||
|
|
||||||
|
if @is_oauth && !@is_set_password
|
||||||
|
@user.password = params[:new_password]
|
||||||
|
@user.password_confirmation = params[:new_password_confirmation]
|
||||||
|
end
|
||||||
|
|
||||||
unless @user.user_extensions.nil?
|
unless @user.user_extensions.nil?
|
||||||
# 如果用户是从业者,将单位名称保存至学校id字段
|
# 如果用户是从业者,将单位名称保存至学校id字段
|
||||||
if @user.user_extensions.identity == 3
|
if @user.user_extensions.identity == 3
|
||||||
|
|
|
@ -0,0 +1,165 @@
|
||||||
|
#encoding: utf-8
|
||||||
|
class OauthController < ApplicationController
|
||||||
|
|
||||||
|
include ApplicationHelper
|
||||||
|
|
||||||
|
before_filter :user_setup
|
||||||
|
before_filter :require_login, only: [:authorize]
|
||||||
|
|
||||||
|
|
||||||
|
skip_before_filter :verify_authenticity_token, only: [:token]
|
||||||
|
|
||||||
|
|
||||||
|
def index
|
||||||
|
render 'oauth/index', layout: false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# 客户端申请认证的URI,包含以下参数:
|
||||||
|
#
|
||||||
|
# response_type:表示授权类型,必选项,此处的值固定为”code”
|
||||||
|
# client_id:表示客户端的ID,必选项
|
||||||
|
# redirect_uri:表示重定向URI,可选项
|
||||||
|
# scope:表示申请的权限范围,可选项
|
||||||
|
# state:表示客户端的当前状态,可以指定任意值(最好是随机字符串),认证服务器会原封不动地返回这个值,可防止CSRF攻击
|
||||||
|
#
|
||||||
|
# 这个页显示授权页,如果授权成功,返回redirect_uri+code
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# 服务器回应客户端的URI,包含以下参数:
|
||||||
|
#
|
||||||
|
# code:表示授权码,必选项。该码的有效期应该很短,通常设为10分钟,客户端只能使用该码一次, 否则会被授权服务器拒绝。该码与客户端ID和重定向URI,是一一对应关系。
|
||||||
|
# state:如果客户端的请求中包含这个参数,认证服务器的回应也必须一模一样包含这个参数。
|
||||||
|
def authorize
|
||||||
|
begin
|
||||||
|
|
||||||
|
#参数检查
|
||||||
|
raise "response_type只能为code" unless params["response_type"] == "code"
|
||||||
|
raise "client_id为必传项" unless params["client_id"].present?
|
||||||
|
raise "redirect_uri为必传项" unless params["redirect_uri"].present?
|
||||||
|
|
||||||
|
|
||||||
|
config = OauthConfig.where(client_id: params["client_id"], redirect_uri: params["redirect_uri"]).first
|
||||||
|
raise "client_id或redirect_uri不正确" unless config
|
||||||
|
|
||||||
|
|
||||||
|
@data = params
|
||||||
|
|
||||||
|
if params[:gen_code]
|
||||||
|
## 检查通过,生成code
|
||||||
|
oauth = Oauth.create!(client_id: config.client_id,
|
||||||
|
client_secret: config.client_secret,
|
||||||
|
redirect_uri: config.redirect_uri,
|
||||||
|
user_id: User.current.id
|
||||||
|
)
|
||||||
|
code = oauth.gen_code
|
||||||
|
|
||||||
|
redirect_to params["redirect_uri"] + "?code=#{code}&state=#{params[:state]}"
|
||||||
|
end
|
||||||
|
|
||||||
|
#render 'oauth/authorize', :layout => 'base_authorize_oschina'
|
||||||
|
rescue => e
|
||||||
|
logger.error e
|
||||||
|
render :text => e.message
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_callback
|
||||||
|
# 申请 token
|
||||||
|
#
|
||||||
|
client_id = "88d893c5a345313e7b8c6fcf23d3d024ee08d5e41ce120c3448b6eea77d8de30"
|
||||||
|
client_secret = "e9240cc5fc913741db5aea93f2986a8ea0631bb67f7c00e41e491b95d9619e64"
|
||||||
|
redirect_uri = "http://localhost:3000/oauth/cb"
|
||||||
|
url = "http://127.0.0.1:3000/oauth/token?grant_type=authorization_code&code=#{params['code']}&redirect_uri=#{redirect_uri}&client_id=#{client_id}&client_secret=#{client_secret}"
|
||||||
|
|
||||||
|
render text: url
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
# 客户端向认证服务器申请令牌的HTTP请求,包含以下参数:
|
||||||
|
#
|
||||||
|
# grant_type:表示使用的授权模式,必选项,此处的值固定为”authorization_code”。
|
||||||
|
# code:表示上一步获得的授权码,必选项。
|
||||||
|
# redirect_uri:表示重定向URI,必选项,且必须与A步骤中的该参数值保持一致。
|
||||||
|
# client_id:表示客户端ID,必选项。
|
||||||
|
# client_secret: 表示客户端密钥,必选项。
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# 认证服务器核对了授权码和”重定向URI”,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)。
|
||||||
|
#
|
||||||
|
# 认证服务器发送的HTTP回复,包含以下内容:
|
||||||
|
#
|
||||||
|
# access_token:表示访问令牌,必选项。
|
||||||
|
# token_type:表示令牌类型,该值大小写不敏感,必选项,可以是bearer类型或mac类型。
|
||||||
|
# expires_in:表示过期时间,单位为秒。如果省略该参数,必须其他方式设置过期时间。
|
||||||
|
# refresh_token:表示更新令牌,用来获取下一次的访问令牌,可选项。
|
||||||
|
# scope:表示权限范围,如果与客户端申请的范围一致,此项可省略。
|
||||||
|
def token
|
||||||
|
begin
|
||||||
|
res = {}
|
||||||
|
if params[:grant_type] == 'authorization_code'
|
||||||
|
|
||||||
|
raise "code必传" unless params["code"]
|
||||||
|
raise "client_id必传" unless params["client_id"]
|
||||||
|
raise "client_secret必传" unless params["client_secret"]
|
||||||
|
|
||||||
|
raise "code错误或已超时" unless Oauth.code_valid?(params["code"])
|
||||||
|
|
||||||
|
oauth = Oauth.auth_code(params["code"], params["client_id"], params["client_secret"])
|
||||||
|
raise "认证不通过" unless oauth
|
||||||
|
|
||||||
|
## 生成 token
|
||||||
|
#
|
||||||
|
oauth.gen_token
|
||||||
|
|
||||||
|
oauth.reload
|
||||||
|
|
||||||
|
res = {
|
||||||
|
access_token: oauth.access_token,
|
||||||
|
token_type: 'bearer',
|
||||||
|
expires_in: oauth.token_expires_in,
|
||||||
|
refresh_token: oauth.refresh_token
|
||||||
|
}
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
render json: res.to_json
|
||||||
|
|
||||||
|
rescue => e
|
||||||
|
logger.error e
|
||||||
|
render text: e.message
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def get_userinfo
|
||||||
|
user = Oauth.auth(params["access_token"])
|
||||||
|
|
||||||
|
user_info = {}
|
||||||
|
if user
|
||||||
|
user_info = {
|
||||||
|
token: user.id,
|
||||||
|
login: user.login,
|
||||||
|
avatar_url: "https://www.trustie.net/images/" + url_to_avatar(user),
|
||||||
|
name: user.show_name,
|
||||||
|
email: user.mail
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
render json: user_info.to_json
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def require_login
|
||||||
|
require "base64"
|
||||||
|
if !User.current.logged?
|
||||||
|
redirect_to '/login?back_url64=' + Base64.urlsafe_encode64(request.original_url)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
include Trustie::Http
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,64 @@
|
||||||
|
#coding=utf-8
|
||||||
|
#
|
||||||
|
class OschinaController < ApplicationController
|
||||||
|
|
||||||
|
CLIENT_ID = 'e5da9855f89bc724a335d100cb63cf02a03a592bd3151bbc84acf7b2e222ddb8'
|
||||||
|
CLIENT_SECRET = '4f2f291fac1d3dae338c18a3e3544814be5a1c4ade9e72d62f45ceab914c89f5'
|
||||||
|
ROOT_URl = Redmine::Configuration['oschina_oauth_cburl'] || 'https://www.trustie.net'
|
||||||
|
OSCHINA_URL = 'https://gitee.com'
|
||||||
|
|
||||||
|
def login
|
||||||
|
# 根据session,看看有没有存access_token,去刷新下。
|
||||||
|
# 1. 如果过期,则跳转
|
||||||
|
# 2. 未过期,直接用
|
||||||
|
|
||||||
|
redirect_to "#{OSCHINA_URL}/oauth/authorize?client_id=#{CLIENT_ID}&redirect_uri=#{ROOT_URl}/oschina/login_cb&response_type=code"
|
||||||
|
end
|
||||||
|
|
||||||
|
def login_callback
|
||||||
|
#获取code
|
||||||
|
#
|
||||||
|
#
|
||||||
|
logger.debug params
|
||||||
|
url = "#{OSCHINA_URL}/oauth/token?grant_type=authorization_code"+
|
||||||
|
"&code=#{params[:code]}&client_id=#{CLIENT_ID}&redirect_uri=#{ROOT_URl}/oschina/login_cb&client_secret=#{CLIENT_SECRET}"
|
||||||
|
|
||||||
|
res = post(url)
|
||||||
|
logger.debug res
|
||||||
|
|
||||||
|
body = decode(res)
|
||||||
|
#{"access_token":"21a80f20ff736b54aecd002b60210943","token_type":"bearer","expires_in":86400,"refresh_token":"be92e2c137a8c6dd22f0d8c4a622b3aeceb054087a95d293130f04ec60fd3e3f","scope":"user_info","created_at":1542684088}
|
||||||
|
raise '登录失败' unless body["access_token"]
|
||||||
|
|
||||||
|
#获取此用户信息
|
||||||
|
res = get("#{OSCHINA_URL}/api/v5/user?access_token=#{body["access_token"]}")
|
||||||
|
logger.debug res
|
||||||
|
info = decode(res)
|
||||||
|
|
||||||
|
oschina = Oschina.find_by_oschina_id(info["id"])
|
||||||
|
unless oschina
|
||||||
|
#新建用户
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
user = User.create_with_oschina!(info)
|
||||||
|
oschina = Oschina.create_with_info!(info, user)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self.logged_user = oschina.user
|
||||||
|
|
||||||
|
user = UserExtensions.where(:user_id => User.current.id).first
|
||||||
|
if user.gender.nil? || user.school_id.nil? || User.current.lastname.nil?
|
||||||
|
redirect_to my_account_path
|
||||||
|
elsif user.identity == 3 && user.school_id.nil?
|
||||||
|
redirect_to my_account_path
|
||||||
|
else
|
||||||
|
redirect_to User.current
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
private
|
||||||
|
include Trustie::Http
|
||||||
|
|
||||||
|
end
|
|
@ -2377,6 +2377,7 @@ class UsersController < ApplicationController
|
||||||
act_type = 'all'
|
act_type = 'all'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
logger.info("####################{container_type}")
|
||||||
if container_type != '' && container_type != 'all'
|
if container_type != '' && container_type != 'all'
|
||||||
if container_type == 'Course'
|
if container_type == 'Course'
|
||||||
sql = "container_type = '#{container_type}' and container_id in #{user_course_ids} and act_type = '#{act_type}'"
|
sql = "container_type = '#{container_type}' and container_id in #{user_course_ids} and act_type = '#{act_type}'"
|
||||||
|
|
|
@ -2171,6 +2171,12 @@ module ApplicationHelper
|
||||||
hidden_field_tag('back_url', url, :id => nil) unless url.blank?
|
hidden_field_tag('back_url', url, :id => nil) unless url.blank?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def back_url64_hidden_field_tag
|
||||||
|
url = params[:back_url64]
|
||||||
|
hidden_field_tag('back_url64', url, :id => nil) unless url.blank?
|
||||||
|
end
|
||||||
|
|
||||||
def check_all_links(form_name)
|
def check_all_links(form_name)
|
||||||
link_to_function_none(l(:button_check_all), "checkAll('#{form_name}', true)") + " ".html_safe + " | "+ " ".html_safe +
|
link_to_function_none(l(:button_check_all), "checkAll('#{form_name}', true)") + " ".html_safe + " | "+ " ".html_safe +
|
||||||
link_to_function_none(l(:button_uncheck_all), "checkAll('#{form_name}', false)")
|
link_to_function_none(l(:button_uncheck_all), "checkAll('#{form_name}', false)")
|
||||||
|
@ -2590,6 +2596,8 @@ module ApplicationHelper
|
||||||
candown = true
|
candown = true
|
||||||
elsif attachment.container.class.to_s=="Syllabus" #论坛资源允许下载
|
elsif attachment.container.class.to_s=="Syllabus" #论坛资源允许下载
|
||||||
candown = true
|
candown = true
|
||||||
|
elsif attachment.container.class.to_s=="ArticleHomepage" #主页帖子的下载权限
|
||||||
|
candown = true
|
||||||
elsif attachment.container.class.to_s == "User"
|
elsif attachment.container.class.to_s == "User"
|
||||||
candown = (attachment.is_public == 1 || attachment.is_public == true || attachment.author_id == User.current.id)
|
candown = (attachment.is_public == 1 || attachment.is_public == true || attachment.author_id == User.current.id)
|
||||||
elsif attachment.container_type == "Bid" && attachment.container && attachment.container.courses
|
elsif attachment.container_type == "Bid" && attachment.container && attachment.container.courses
|
||||||
|
|
|
@ -2,4 +2,5 @@ class ArticleHomepage < ActiveRecord::Base
|
||||||
belongs_to :user
|
belongs_to :user
|
||||||
belongs_to :homepage
|
belongs_to :homepage
|
||||||
attr_accessible :content, :title, :user_id, :homepage_id
|
attr_accessible :content, :title, :user_id, :homepage_id
|
||||||
|
acts_as_attachable
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
require 'base64'
|
||||||
|
|
||||||
|
class Oauth < ActiveRecord::Base
|
||||||
|
attr_accessible :client_id, :client_secret, :redirect_uri, :access_token,
|
||||||
|
:refresh_token, :token_created_at,:token_expires_in, :user_id
|
||||||
|
|
||||||
|
belongs_to :user
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def gen_code
|
||||||
|
code = Base64.urlsafe_encode64 Digest::MD5.hexdigest "#{Time.now}-#{Random.new_seed}"
|
||||||
|
update_column(:code, code)
|
||||||
|
code
|
||||||
|
end
|
||||||
|
|
||||||
|
def gen_token
|
||||||
|
access_token = Digest::MD5.hexdigest "#{Time.now}-#{Random.new_seed}"
|
||||||
|
refresh_token = Digest::MD5.hexdigest "#{Random.new_seed}-#{Time.now}-#{Random.new_seed}"
|
||||||
|
|
||||||
|
self.update_attributes(access_token: access_token,
|
||||||
|
refresh_token: refresh_token,
|
||||||
|
token_created_at: Time.now.to_i,
|
||||||
|
token_expires_in: Time.now.to_i + 24*60*60,
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def self.code_valid?(code)
|
||||||
|
# 1. 是否存在
|
||||||
|
oauth = Oauth.where(code: code).order("ID desc").first
|
||||||
|
return false unless oauth
|
||||||
|
|
||||||
|
# 2. 是否超过10分钟
|
||||||
|
return false if Time.now.to_i - oauth.created_at.to_i > 10*60
|
||||||
|
|
||||||
|
# 3. 是否有使用过
|
||||||
|
return false if oauth.access_token.present?
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def self.auth_code(code, client_id, client_secret)
|
||||||
|
Oauth.where(code: code, client_id: client_id, client_secret: client_secret).order('id desc').first
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.auth(access_token)
|
||||||
|
oauth = self.find_by_access_token(access_token)
|
||||||
|
return nil unless oauth
|
||||||
|
oauth.user
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,3 @@
|
||||||
|
class OauthConfig < ActiveRecord::Base
|
||||||
|
attr_accessible :client_id, :client_secret, :redirect_uri, :scope
|
||||||
|
end
|
|
@ -0,0 +1,18 @@
|
||||||
|
class Oschina < ActiveRecord::Base
|
||||||
|
belongs_to :user
|
||||||
|
attr_accessible :login, :user, :name, :avatar_url, :email, :phone, :oschina_id
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def self.create_with_info!(info, user)
|
||||||
|
self.create!(
|
||||||
|
login: info["login"],
|
||||||
|
name: info["name"],
|
||||||
|
avatar_url: info["avatar_url"],
|
||||||
|
email: info["email"],
|
||||||
|
phone: info["phone"],
|
||||||
|
oschina_id: info["id"],
|
||||||
|
user: user
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
|
@ -1453,6 +1453,34 @@ class User < Principal
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def self.create_with_oschina!(info)
|
||||||
|
user = User.new
|
||||||
|
user.admin = false
|
||||||
|
user.login = info["login"]
|
||||||
|
if User.find_by_login(info["login"])
|
||||||
|
user.login = "oschina_" + info["login"]
|
||||||
|
end
|
||||||
|
|
||||||
|
unless User.find_by_mail(info["email"])
|
||||||
|
user.mail = info["email"]
|
||||||
|
end
|
||||||
|
user.lastname = info["name"]
|
||||||
|
|
||||||
|
user.activate
|
||||||
|
user.last_login_on = Time.now
|
||||||
|
user.save!(:validate => false)
|
||||||
|
|
||||||
|
UserStatus.create!(:user_id => user.id, :changsets_count => 0, :watchers_count => 0)
|
||||||
|
|
||||||
|
ue = user.user_extensions ||= UserExtensions.new
|
||||||
|
ue.user_id = user.id
|
||||||
|
ue.save!
|
||||||
|
|
||||||
|
user
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class AnonymousUser < User
|
class AnonymousUser < User
|
||||||
|
|
|
@ -48,6 +48,35 @@ class CoursesService
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# 获取课程最新动态
|
||||||
|
def get_course_activity params
|
||||||
|
page = params[:page] || 1
|
||||||
|
activities = UserActivity.where(:container_type => 'Course', :act_type => 'HomeworkCommon').order('created_at desc')
|
||||||
|
|
||||||
|
activities_count = activities.count
|
||||||
|
activities_pages = Redmine::Pagination::Paginator.new @activities_count, 4, page
|
||||||
|
activities = activities.offset(activities_pages.offset).limit(activities_pages.per_page)
|
||||||
|
course_activites_data = []
|
||||||
|
activities.each do |a|
|
||||||
|
Rails.logger.info("###############{a.container.to_json}")
|
||||||
|
course_name = a.container.name
|
||||||
|
course_activites_data << {course_name: course_name, content: a.act.name, time: format_time(a.created_at), url: "www.trustie.net/course/#{a.container_id}"}
|
||||||
|
end
|
||||||
|
{course_activites_data: course_activites_data}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_course_data params
|
||||||
|
page = params[:page] || 1
|
||||||
|
courses = Course.where(:is_delete => false, :is_public => true).order("visits desc")
|
||||||
|
courses_count = courses.count
|
||||||
|
courses_pages = Redmine::Pagination::Paginator.new courses_count, 4, page
|
||||||
|
courses = courses.offset(courses_pages.offset).limit(courses_pages.per_page)
|
||||||
|
course_data = []
|
||||||
|
courses.each do |c|
|
||||||
|
course_data << {name: c.name, time: format_time(c.created_at), url: "www.trustie.net/courses/#{c.id}"}
|
||||||
|
end
|
||||||
|
{course_data: course_data}
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
#搜索课程
|
#搜索课程
|
||||||
|
|
|
@ -135,7 +135,7 @@
|
||||||
<h3> 欢迎加入Trustie创新实践社区</h3>
|
<h3> 欢迎加入Trustie创新实践社区</h3>
|
||||||
<p>在这里,您的创新意识和创新潜力将得到充分发挥!目前已有超过200所高校和科研机构在平台中开展在线协同开发、协同学习和协同研究。</p>
|
<p>在这里,您的创新意识和创新潜力将得到充分发挥!目前已有超过200所高校和科研机构在平台中开展在线协同开发、协同学习和协同研究。</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="new_login_box fr mr45 mt100">
|
<div class="new_login_box fr mr45 mt60">
|
||||||
<% if @message %>
|
<% if @message %>
|
||||||
<p class="f14 mb5" style=" color:#fff;"><i class="icon-ok mr5"></i><%= h @message %></p>
|
<p class="f14 mb5" style=" color:#fff;"><i class="icon-ok mr5"></i><%= h @message %></p>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
@ -145,6 +145,7 @@
|
||||||
<div class="new_login_form">
|
<div class="new_login_form">
|
||||||
<%= form_tag(signin_path,:id=>'main_login_form',:method=>'post') do %>
|
<%= form_tag(signin_path,:id=>'main_login_form',:method=>'post') do %>
|
||||||
<%= back_url_hidden_field_tag %>
|
<%= back_url_hidden_field_tag %>
|
||||||
|
<%= back_url64_hidden_field_tag %>
|
||||||
<ul>
|
<ul>
|
||||||
<li class="new_loggin_users">
|
<li class="new_loggin_users">
|
||||||
<%= text_field_tag 'username', params[:username], :tabindex => '1', :class=>'new_loggin_input',:placeholder=>'请输入邮箱地址或登录名', :onkeypress => "user_name_keypress(event);"%>
|
<%= text_field_tag 'username', params[:username], :tabindex => '1', :class=>'new_loggin_input',:placeholder=>'请输入邮箱地址或登录名', :onkeypress => "user_name_keypress(event);"%>
|
||||||
|
@ -158,6 +159,7 @@
|
||||||
<% if Setting.autologin? %>
|
<% if Setting.autologin? %>
|
||||||
<label><%= check_box_tag 'autologin', 1, true, :tabindex => 4, :class => "new_login_check" %><%= l(:label_stay_logged_in) %></label>
|
<label><%= check_box_tag 'autologin', 1, true, :tabindex => 4, :class => "new_login_check" %><%= l(:label_stay_logged_in) %></label>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
<%#= link_to 'oschina登录', oschina_login_path %>
|
||||||
<a href="<%= lost_password_path %>" class="fr">
|
<a href="<%= lost_password_path %>" class="fr">
|
||||||
<% if Setting.lost_password? %>忘记密码<% end %>
|
<% if Setting.lost_password? %>忘记密码<% end %>
|
||||||
</a>
|
</a>
|
||||||
|
@ -167,7 +169,12 @@
|
||||||
</ul>
|
</ul>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="text_c">
|
||||||
|
<a href="<%= oschina_login_path %>">
|
||||||
|
<ul style="width: auto;display: inline-block;"><span class="oschinaBox"><i class="iconfont icon-oschina c_white oschinaIcon"></i></span></ul>
|
||||||
|
<p class="c_white f12">使用oschina账号登录</p>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="cl"></div>
|
<div class="cl"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -21,8 +21,7 @@
|
||||||
:minHeight=>500,
|
:minHeight=>500,
|
||||||
:class => 'talk_text fl',
|
:class => 'talk_text fl',
|
||||||
:input_html => { :id => 'message_content',
|
:input_html => { :id => 'message_content',
|
||||||
:class => 'talk_text fl',
|
:class => 'talk_text fl'}%>
|
||||||
:maxlength => 5000 }%>
|
|
||||||
<div class="cl"></div>
|
<div class="cl"></div>
|
||||||
<p id="message_content_span"></p>
|
<p id="message_content_span"></p>
|
||||||
<p id="e_tip" class="c_grey"></p>
|
<p id="e_tip" class="c_grey"></p>
|
||||||
|
@ -32,6 +31,11 @@
|
||||||
<input type="checkbox" value="1" id="set_homepage" name="set_homepage"/>
|
<input type="checkbox" value="1" id="set_homepage" name="set_homepage"/>
|
||||||
<label for="set_homepage">设为主页</label>
|
<label for="set_homepage">设为主页</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mt10">
|
||||||
|
<div class="fl" id="topic_attachments">
|
||||||
|
<%= render :partial => 'attachments/form_course', :locals => {:container => @article, :isReply => @isReply} %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="cl"></div>
|
<div class="cl"></div>
|
||||||
<div class="mt5">
|
<div class="mt5">
|
||||||
<a href="javascript:void(0);" class="BlueCirBtnMini fr" onclick="submit_article();">确定</a>
|
<a href="javascript:void(0);" class="BlueCirBtnMini fr" onclick="submit_article();">确定</a>
|
||||||
|
|
|
@ -61,6 +61,10 @@
|
||||||
<div class="break_word mt10" style="padding: 5px 5px 0 0" id="intro_content">
|
<div class="break_word mt10" style="padding: 5px 5px 0 0" id="intro_content">
|
||||||
<%=@article.content.html_safe %>
|
<%=@article.content.html_safe %>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="cl"></div>
|
||||||
|
<div class="mt10" style="font-weight:normal;">
|
||||||
|
<%= render :partial=>"attachments/activity_attach", :locals=>{:activity => @article} %>
|
||||||
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
<% @nav_dispaly_home_path_label = 1
|
||||||
|
@nav_dispaly_main_course_label = 1
|
||||||
|
@nav_dispaly_main_project_label = 1
|
||||||
|
@nav_dispaly_main_contest_label = 1 %>
|
||||||
|
<% @nav_dispaly_forum_label = 1%>
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="<%= current_language %>">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title><%=h html_title %></title>
|
||||||
|
<meta name="description" content="<%= Redmine::Info.app_name %>" />
|
||||||
|
<meta name="keywords" content="issue,bug,tracker" />
|
||||||
|
<%= csrf_meta_tag %>
|
||||||
|
<%= favicon %>
|
||||||
|
<%= stylesheet_link_tag 'jquery/jquery-ui-1.9.2', 'application', 'nyan','prettify','//at.alicdn.com/t/font_930423_4z0tgi8hlb9.css', :media => 'all' %>
|
||||||
|
<%= stylesheet_link_tag 'rtl', :media => 'all' if l(:direction) == 'rtl' %>
|
||||||
|
<%= javascript_heads %>
|
||||||
|
<%= javascript_include_tag "jquery.leanModal.min",'prettify' %>
|
||||||
|
<%= javascript_include_tag 'seems_rateable/jRating', 'seems_rateable/rateable'%>
|
||||||
|
<%= heads_for_theme %>
|
||||||
|
<%= call_hook :view_layouts_base_html_head %>
|
||||||
|
<!-- page specific tags -->
|
||||||
|
<%= yield :header_tags -%>
|
||||||
|
<%= stylesheet_link_tag 'css/common','css/structure','css/public', :media => 'all'%>
|
||||||
|
<!-- MathJax的配置 -->
|
||||||
|
<script type="text/javascript"
|
||||||
|
src="/javascripts/MathJax/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
|
||||||
|
</script>
|
||||||
|
<!-- 配置 : 在生成的公式图片上去掉Math定义的右键菜单,$$ $$ \( \) \[ \] 中的公式给予显示-->
|
||||||
|
<script type="text/x-mathjax-config">
|
||||||
|
MathJax.Hub.Config({
|
||||||
|
showMathMenu: false,
|
||||||
|
showMathMenuMSIE: false,
|
||||||
|
tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body class="<%=h body_css_classes %>" style="background-color: #fff;">
|
||||||
|
<div class="cl"></div>
|
||||||
|
<div>
|
||||||
|
<%= yield %>
|
||||||
|
</div>
|
||||||
|
<%= call_hook :view_layouts_base_body_bottom %>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -7,7 +7,7 @@
|
||||||
<meta name="keywords" content="issue,bug,tracker" />
|
<meta name="keywords" content="issue,bug,tracker" />
|
||||||
<%= csrf_meta_tag %>
|
<%= csrf_meta_tag %>
|
||||||
<%= favicon %>
|
<%= favicon %>
|
||||||
<%= stylesheet_link_tag 'jquery/jquery-ui-1.9.2', 'css/common', 'css/structure', 'css/font-awesome', :media => 'all' %>
|
<%= stylesheet_link_tag 'jquery/jquery-ui-1.9.2', 'css/common', 'css/structure', 'css/font-awesome','//at.alicdn.com/t/font_930423_4z0tgi8hlb9.css', :media => 'all' %>
|
||||||
<%= stylesheet_link_tag 'rtl', :media => 'all' if l(:direction) == 'rtl' %>
|
<%= stylesheet_link_tag 'rtl', :media => 'all' if l(:direction) == 'rtl' %>
|
||||||
<%= javascript_heads %>
|
<%= javascript_heads %>
|
||||||
<%= javascript_include_tag "bootstrap","avatars","new_user"%>
|
<%= javascript_include_tag "bootstrap","avatars","new_user"%>
|
||||||
|
|
|
@ -27,6 +27,12 @@
|
||||||
<% end %>
|
<% end %>
|
||||||
<ul class="setting_left">
|
<ul class="setting_left">
|
||||||
<li><span style="color:red;">*</span> 登录名 : </li>
|
<li><span style="color:red;">*</span> 登录名 : </li>
|
||||||
|
|
||||||
|
<% if @is_oauth && !@is_set_password %>
|
||||||
|
<li>新密码 : </li>
|
||||||
|
<li>确认密码 : </li>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
<li><span style="color:red;">*</span> 邮箱 : </li>
|
<li><span style="color:red;">*</span> 邮箱 : </li>
|
||||||
<li><span style="color:red;">*</span> 职业 : </li>
|
<li><span style="color:red;">*</span> 职业 : </li>
|
||||||
<li nhname="tag" nh_tag_0="true" nh_tag_1="true" nh_tag_3="true" ><span style="color:red;">*</span> 姓名 : </li>
|
<li nhname="tag" nh_tag_0="true" nh_tag_1="true" nh_tag_3="true" ><span style="color:red;">*</span> 姓名 : </li>
|
||||||
|
@ -50,6 +56,12 @@
|
||||||
:class => "w210"
|
:class => "w210"
|
||||||
%>
|
%>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<% if @is_oauth && !@is_set_password %>
|
||||||
|
<li><input id="new_password" name="new_password" class="w210" type="password" required="true" nh_required="1"><span class="c_red ml5">请输入8-12个字符</span></li>
|
||||||
|
<li><input id="new_password_confirmation" name="new_password_confirmation" class="w210" type="password" required="true" nh_required="1"></li>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
<% if @force %>
|
<% if @force %>
|
||||||
<li><%= f.text_field :mail,:no_label=>true, :required => true,:nh_required => "1",:class=>"w210",:disabled=>'disabled'%></li>
|
<li><%= f.text_field :mail,:no_label=>true, :required => true,:nh_required => "1",:class=>"w210",:disabled=>'disabled'%></li>
|
||||||
<% else %>
|
<% else %>
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
<% if false %>
|
||||||
|
<p>当前用户: <%= current_user.login %></p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
<% end %>
|
||||||
|
<link href="//at.alicdn.com/t/font_930423_4z0tgi8hlb9.css" rel="stylesheet"/>
|
||||||
|
<div class="authmain clearfix">
|
||||||
|
<div class="l-r-trustie">
|
||||||
|
<div class="clearfix" style="width: 100%;">
|
||||||
|
<span class="fl mr20"><i class="iconfont f40 icon-oschina c_grey"></i></span>
|
||||||
|
<div class="fl">
|
||||||
|
<p><span class="c_blue">码云</span>将获得以下权限</p>
|
||||||
|
<p><input type="checkbox" checked="checked" disabled class="checked-choose"/>获得您的昵称、头像、性别</p>
|
||||||
|
<%= form_for oauth_authorize_path do%>
|
||||||
|
<input type="hidden" name="gen_code" value="true">
|
||||||
|
<input type="hidden" name="client_id" value="<%= @data["client_id"] %>">
|
||||||
|
<input type="hidden" name="redirect_uri" value="<%= @data["redirect_uri"] %>">
|
||||||
|
<input type="hidden" name="response_type" value="<%= @data["response_type"] %>">
|
||||||
|
<input type="hidden" name="scope" value="<%= @data["scope"] %>">
|
||||||
|
<input type="hidden" name="state" value="<%= @data["state"] %>">
|
||||||
|
<button class="auth-login-btn mr20" type="submit">授权并登录</button>
|
||||||
|
<% end %>
|
||||||
|
<a href="<%= @data['redirect_uri'] %>?error=access_denied&error_description=用户或服务器拒绝了请求" class="auth-cancel-btn mr20">拒绝</a>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,300 @@
|
||||||
|
<!DOCTYPE html><html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Trustie oauth2.0帮助</title>
|
||||||
|
<style>
|
||||||
|
html,body{ font-family: "SF UI Display", ".PingFang SC","PingFang SC", "Neue Haas Grotesk Text Pro", "Arial Nova", "Segoe UI", "Microsoft YaHei", "Microsoft JhengHei", "Helvetica Neue", "Source Han Sans SC", "Noto Sans CJK SC", "Source Han Sans CN", "Noto Sans SC", "Source Han Sans TC", "Noto Sans CJK TC", "Hiragino Sans GB", sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
color:#222;
|
||||||
|
-webkit-text-size-adjust:none; min-width: 200px;
|
||||||
|
max-width: 760px;
|
||||||
|
margin: 0 auto; padding: 1rem;
|
||||||
|
line-height: 1.5rem;
|
||||||
|
|
||||||
|
}
|
||||||
|
h1,h2,h3,h4,h5,h6{font-family: "PT Sans","SF UI Display", ".PingFang SC","PingFang SC", "Neue Haas Grotesk Text Pro", "Arial Nova", "Segoe UI", "Microsoft YaHei", "Microsoft JhengHei", "Helvetica Neue", "Source Han Sans SC", "Noto Sans CJK SC", "Source Han Sans CN", "Noto Sans SC", "Source Han Sans TC", "Noto Sans CJK TC", "Hiragino Sans GB", sans-serif;
|
||||||
|
text-rendering:optimizelegibility;margin-bottom:1em;font-weight:bold; line-height: 1.8rem;
|
||||||
|
|
||||||
|
}
|
||||||
|
h1,h2{position:relative;padding-top:1rem;padding-bottom:0.2rem;margin-bottom:1rem;
|
||||||
|
border-bottom: solid 1px #eee;
|
||||||
|
}
|
||||||
|
h2{padding-top:0.8rem;padding-bottom:0.2rem;}
|
||||||
|
h1{ font-size: 1.6rem;}
|
||||||
|
h2{ font-size: 1.4rem;}
|
||||||
|
h3{ font-size: 1.2rem;}
|
||||||
|
h4{ font-size: 1.1rem;}
|
||||||
|
h5{ font-size: 1.0rem;}
|
||||||
|
h6{ font-size: 0.9rem;}
|
||||||
|
|
||||||
|
table{border-collapse:collapse;border-spacing:0;
|
||||||
|
margin-top: 0.8rem;
|
||||||
|
margin-bottom: 1.4rem;
|
||||||
|
}
|
||||||
|
tr{ background-color: #fff;
|
||||||
|
border-top: 1px solid #ccc;}
|
||||||
|
th,td{padding: 5px 14px;
|
||||||
|
border: 1px solid #ddd;}
|
||||||
|
|
||||||
|
blockquote{font-style:italic;font-size:1.1em;line-height:1.5em;padding-left:1em; border-left:4px solid #D5D5D5; margin-left: 0;
|
||||||
|
margin-right: 0;
|
||||||
|
margin-bottom: 1.5rem; }
|
||||||
|
|
||||||
|
a{color:#1863a1}
|
||||||
|
a:hover{color: #1b438d;}
|
||||||
|
pre,code,p code,li code{font-family:Menlo,Monaco,"Andale Mono","lucida console","Courier New",monospace}
|
||||||
|
|
||||||
|
pre{-webkit-border-radius:0.4em;-moz-border-radius:0.4em;-ms-border-radius:0.4em;-o-border-radius:0.4em;border-radius:0.4em;border:1px solid #e7dec3;line-height:1.45em;font-size:0.9rem;margin-bottom:2.1em;padding:.8em 1em;color:#586e75;overflow:auto; background-color:#fdf6e3;}
|
||||||
|
|
||||||
|
p code,li code{display:inline-block;white-space:no-wrap;background:#fff;font-size:0.9rem;line-height:1.5em;color:#555;border:1px solid #ddd;-webkit-border-radius:0.4em;-moz-border-radius:0.4em;-ms-border-radius:0.4em;-o-border-radius:0.4em;border-radius:0.4em;padding:0 .3em;margin:-1px 4px;}
|
||||||
|
p pre code,li pre code{font-size:1em !important;background:none;border:none}
|
||||||
|
|
||||||
|
img{max-width:100%;padding: 8px 0px;}
|
||||||
|
|
||||||
|
|
||||||
|
hr {
|
||||||
|
height: 0;
|
||||||
|
margin: 15px 0;
|
||||||
|
overflow: hidden;
|
||||||
|
background: transparent;
|
||||||
|
border: 0;
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PrismJS 1.14.0
|
||||||
|
https://prismjs.com/download.html#themes=prism-solarizedlight&languages=markup+css+clike+javascript */
|
||||||
|
/*
|
||||||
|
Solarized Color Schemes originally by Ethan Schoonover
|
||||||
|
http://ethanschoonover.com/solarized
|
||||||
|
|
||||||
|
Ported for PrismJS by Hector Matos
|
||||||
|
Website: https://krakendev.io
|
||||||
|
Twitter Handle: https://twitter.com/allonsykraken)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
SOLARIZED HEX
|
||||||
|
--------- -------
|
||||||
|
base03 #002b36
|
||||||
|
base02 #073642
|
||||||
|
base01 #586e75
|
||||||
|
base00 #657b83
|
||||||
|
base0 #839496
|
||||||
|
base1 #93a1a1
|
||||||
|
base2 #eee8d5
|
||||||
|
base3 #fdf6e3
|
||||||
|
yellow #b58900
|
||||||
|
orange #cb4b16
|
||||||
|
red #dc322f
|
||||||
|
magenta #d33682
|
||||||
|
violet #6c71c4
|
||||||
|
blue #268bd2
|
||||||
|
cyan #2aa198
|
||||||
|
green #859900
|
||||||
|
*/
|
||||||
|
|
||||||
|
code[class*="language-"],
|
||||||
|
pre[class*="language-"] {
|
||||||
|
color: #657b83; /* base00 */
|
||||||
|
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||||
|
text-align: left;
|
||||||
|
white-space: pre;
|
||||||
|
word-spacing: normal;
|
||||||
|
word-break: normal;
|
||||||
|
word-wrap: normal;
|
||||||
|
|
||||||
|
line-height: 1.5;
|
||||||
|
|
||||||
|
-moz-tab-size: 4;
|
||||||
|
-o-tab-size: 4;
|
||||||
|
tab-size: 4;
|
||||||
|
|
||||||
|
-webkit-hyphens: none;
|
||||||
|
-moz-hyphens: none;
|
||||||
|
-ms-hyphens: none;
|
||||||
|
hyphens: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
|
||||||
|
code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
|
||||||
|
background: #073642; /* base02 */
|
||||||
|
}
|
||||||
|
|
||||||
|
pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
|
||||||
|
code[class*="language-"]::selection, code[class*="language-"] ::selection {
|
||||||
|
background: #073642; /* base02 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Code blocks */
|
||||||
|
pre[class*="language-"] {
|
||||||
|
padding: 1em;
|
||||||
|
margin: .5em 0;
|
||||||
|
overflow: auto;
|
||||||
|
border-radius: 0.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
:not(pre) > code[class*="language-"],
|
||||||
|
pre[class*="language-"] {
|
||||||
|
background-color: #fdf6e3; /* base3 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inline code */
|
||||||
|
:not(pre) > code[class*="language-"] {
|
||||||
|
padding: .1em;
|
||||||
|
border-radius: .3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.comment,
|
||||||
|
.token.prolog,
|
||||||
|
.token.doctype,
|
||||||
|
.token.cdata {
|
||||||
|
color: #93a1a1; /* base1 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.punctuation {
|
||||||
|
color: #586e75; /* base01 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.namespace {
|
||||||
|
opacity: .7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.property,
|
||||||
|
.token.tag,
|
||||||
|
.token.boolean,
|
||||||
|
.token.number,
|
||||||
|
.token.constant,
|
||||||
|
.token.symbol,
|
||||||
|
.token.deleted {
|
||||||
|
color: #268bd2; /* blue */
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.selector,
|
||||||
|
.token.attr-name,
|
||||||
|
.token.string,
|
||||||
|
.token.char,
|
||||||
|
.token.builtin,
|
||||||
|
.token.url,
|
||||||
|
.token.inserted {
|
||||||
|
color: #2aa198; /* cyan */
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.entity {
|
||||||
|
color: #657b83; /* base00 */
|
||||||
|
background: #eee8d5; /* base2 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.atrule,
|
||||||
|
.token.attr-value,
|
||||||
|
.token.keyword {
|
||||||
|
color: #859900; /* green */
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.function,
|
||||||
|
.token.class-name {
|
||||||
|
color: #b58900; /* yellow */
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.regex,
|
||||||
|
.token.important,
|
||||||
|
.token.variable {
|
||||||
|
color: #cb4b16; /* orange */
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.important,
|
||||||
|
.token.bold {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.token.italic {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.token.entity {
|
||||||
|
cursor: help;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre[class*="language-"].line-numbers {
|
||||||
|
position: relative;
|
||||||
|
padding-left: 3.8em;
|
||||||
|
counter-reset: linenumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre[class*="language-"].line-numbers > code {
|
||||||
|
position: relative;
|
||||||
|
white-space: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
.line-numbers .line-numbers-rows {
|
||||||
|
position: absolute;
|
||||||
|
pointer-events: none;
|
||||||
|
top: 0;
|
||||||
|
font-size: 100%;
|
||||||
|
left: -3.8em;
|
||||||
|
width: 3em; /* works for line-numbers below 1000 lines */
|
||||||
|
letter-spacing: -1px;
|
||||||
|
border-right: 1px solid #999;
|
||||||
|
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.line-numbers-rows > span {
|
||||||
|
pointer-events: none;
|
||||||
|
display: block;
|
||||||
|
counter-increment: linenumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
.line-numbers-rows > span:before {
|
||||||
|
content: counter(linenumber);
|
||||||
|
color: #999;
|
||||||
|
display: block;
|
||||||
|
padding-right: 0.8em;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style> @media print{ code[class*="language-"],pre[class*="language-"]{overflow: visible; word-wrap: break-word !important;} }</style></head><body><div class="markdown-body">
|
||||||
|
<h1 id="toc_0">Trustie oauth2.0帮助</h1>
|
||||||
|
|
||||||
|
<p>目前提供授权码方式进行认证</p>
|
||||||
|
|
||||||
|
<h2 id="toc_1">步骤</h2>
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<li><p>应用通过 浏览器 或 Webview 将用户引导到码云三方认证页面上( GET请求 )</p>
|
||||||
|
<p><code>https://server/oauth/authorize?client_id={client_id}&redirect_uri={redirect_uri}&response_type=code</code></p></li>
|
||||||
|
<li><p>用户对应用进行授权</p>
|
||||||
|
<p>认证服务器通过回调地址<code>{redirect_uri}</code>将 用户授权码 传递给 应用服务器 或者直接在 Webview 中跳转到携带 用户授权码的回调地址上,Webview 直接获取code即可({redirect_uri}?code=abc&state=xyz)</p>
|
||||||
|
<p>应用服务器 或 Webview 使用 access_token API 向 认证服务器发送post请求传入 用户授权码 以及 回调地址( POST请求 )</p>
|
||||||
|
<p><code>https://server/oauth/token?grant_type=authorization_code&code={code}&client_id={client_id}&redirect_uri={redirect_uri}&client_secret={client_secret}</code></p></li>
|
||||||
|
<li><p>认证服务器返回 <code>access_token</code></p></li>
|
||||||
|
<li><p>应用通过 <code>access_token</code> 访问 Open API 使用用户数据。</p></li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<h2 id="toc_2">api</h2>
|
||||||
|
|
||||||
|
<ol>
|
||||||
|
<li>获取当前用户资料</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<p><code>/oauth/userinfo?access_token={access_token}</code></p>
|
||||||
|
|
||||||
|
<pre><code class="language-text">{
|
||||||
|
token: 1,
|
||||||
|
login: 'name',
|
||||||
|
avatar_url: 'url',
|
||||||
|
name: '张三',
|
||||||
|
email: 'trustie@trustie.net'
|
||||||
|
}
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
</div></body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -50,19 +50,22 @@
|
||||||
if(checkboxs.length == 0) {
|
if(checkboxs.length == 0) {
|
||||||
$("#choose_courses_notice").html("请先选择作业");
|
$("#choose_courses_notice").html("请先选择作业");
|
||||||
} else{
|
} else{
|
||||||
$.post(
|
$("#choose_courses_notice").html("");
|
||||||
'<%=check_homework_users_path() %>',
|
$('#select_homework_form').submit();
|
||||||
{homework: checkboxs.val()},
|
hideModal();
|
||||||
function(data){
|
// $.post(
|
||||||
if(data.status == 1) {
|
// '<%#=check_homework_users_path() %>',
|
||||||
$("#choose_courses_notice").html("您选中的题是“我收到的作业”,不能选用");
|
// {homework: checkboxs.val()},
|
||||||
} else if(data.status == 0) {
|
// function(data){
|
||||||
$("#choose_courses_notice").html("");
|
// if(data.status == 1) {
|
||||||
$('#select_homework_form').submit();
|
// $("#choose_courses_notice").html("您选中的题是“我收到的作业”,不能选用");
|
||||||
hideModal();
|
// } else if(data.status == 0) {
|
||||||
}
|
// $("#choose_courses_notice").html("");
|
||||||
}
|
// $('#select_homework_form').submit();
|
||||||
);
|
// hideModal();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$("#public_homeworks_choose").click(function(){
|
$("#public_homeworks_choose").click(function(){
|
||||||
|
|
|
@ -2147,7 +2147,7 @@ zh:
|
||||||
label_co_organizer_BHU: 北京航空航天大学
|
label_co_organizer_BHU: 北京航空航天大学
|
||||||
label_co_organizer_CAS: 中国科学院软件研究所
|
label_co_organizer_CAS: 中国科学院软件研究所
|
||||||
label_co_organizer_InforS: 中创软件
|
label_co_organizer_InforS: 中创软件
|
||||||
label_rights_reserved: Copyright 2007~2018, 国防科技大学.
|
label_rights_reserved: Copyright 2007~2019, 国防科技大学.
|
||||||
label_about_us: 关于我们
|
label_about_us: 关于我们
|
||||||
label_contact_us: 联系我们
|
label_contact_us: 联系我们
|
||||||
label_recruitment_information: 招聘信息
|
label_recruitment_information: 招聘信息
|
||||||
|
|
|
@ -554,6 +554,17 @@ RedmineApp::Application.routes.draw do
|
||||||
#激活邮箱反馈问题
|
#激活邮箱反馈问题
|
||||||
match 'users/:id/leave_email_activation_message', :to => 'words#leave_email_activation_message', :via => :post, :as => "leave_email_activation_message"
|
match 'users/:id/leave_email_activation_message', :to => 'words#leave_email_activation_message', :via => :post, :as => "leave_email_activation_message"
|
||||||
|
|
||||||
|
## oschina登录相关
|
||||||
|
match 'oschina/login', to: 'oschina#login', :via => :get
|
||||||
|
match 'oschina/login_cb', to: 'oschina#login_callback', :via => [:get, :post]
|
||||||
|
|
||||||
|
## oauth相关
|
||||||
|
match 'oauth', to: 'oauth#index'
|
||||||
|
match 'oauth/authorize', to: 'oauth#authorize', :via => [:get, :post]
|
||||||
|
match 'oauth/token', to: 'oauth#token', :via => :post
|
||||||
|
match 'oauth/cb', to: 'oauth#test_callback', :via => :get
|
||||||
|
match 'oauth/userinfo', to: 'oauth#get_userinfo', :via => :get
|
||||||
|
|
||||||
# boards
|
# boards
|
||||||
match 'boards/:board_id/topics/new', :to => 'messages#new', :via => [:get, :post], :as => 'new_board_message'
|
match 'boards/:board_id/topics/new', :to => 'messages#new', :via => [:get, :post], :as => 'new_board_message'
|
||||||
match 'boards/:id/join_to_org_subfields', :to => 'boards#join_to_org_subfields'
|
match 'boards/:id/join_to_org_subfields', :to => 'boards#join_to_org_subfields'
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
class CreateOschinas < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
create_table :oschinas do |t|
|
||||||
|
t.references :user
|
||||||
|
|
||||||
|
t.string :login
|
||||||
|
t.string :name
|
||||||
|
t.string :avatar_url
|
||||||
|
t.string :email
|
||||||
|
t.string :phone
|
||||||
|
t.integer :oschina_id
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
add_index :oschinas, :user_id
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,22 @@
|
||||||
|
class CreateOauthConfigs < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
create_table :oauth_configs do |t|
|
||||||
|
t.string :client_id
|
||||||
|
t.string :client_secret
|
||||||
|
t.string :redirect_uri
|
||||||
|
t.string :scope
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
OauthConfig.create(
|
||||||
|
client_id: '88d893c5a345313e7b8c6fcf23d3d024ee08d5e41ce120c3448b6eea77d8de30',
|
||||||
|
client_secret: 'e9240cc5fc913741db5aea93f2986a8ea0631bb67f7c00e41e491b95d9619e64',
|
||||||
|
redirect_uri: 'http://localhost:3000/oschina/login_cb',
|
||||||
|
scope: ''
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,24 @@
|
||||||
|
class AddUserIdToOauths < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
|
||||||
|
create_table :oauths do |t|
|
||||||
|
t.string :client_id
|
||||||
|
t.string :client_secret
|
||||||
|
t.string :code
|
||||||
|
t.string :redirect_uri
|
||||||
|
t.string :scope
|
||||||
|
|
||||||
|
t.string :access_token
|
||||||
|
t.string :refresh_token
|
||||||
|
t.integer :token_created_at
|
||||||
|
t.integer :token_expires_in #过期时间
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
add_column :oauths, :user_id, :integer, default: 0
|
||||||
|
|
||||||
|
add_index :oauths, :user_id
|
||||||
|
end
|
||||||
|
end
|
1558
db/schema.rb
1558
db/schema.rb
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Settings><!--This file was automatically generated by Ruby plugin.
|
||||||
|
You are allowed to:
|
||||||
|
1. Remove rake task
|
||||||
|
2. Add existing rake tasks
|
||||||
|
To add existing rake tasks automatically delete this file and reload the project.
|
||||||
|
--><RakeGroup description="" fullCmd="" taksId="rake" /></Settings>
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Settings><!--This file was automatically generated by Ruby plugin.
|
||||||
|
You are allowed to:
|
||||||
|
1. Remove rake task
|
||||||
|
2. Add existing rake tasks
|
||||||
|
To add existing rake tasks automatically delete this file and reload the project.
|
||||||
|
--><RakeGroup description="" fullCmd="" taksId="rake" /></Settings>
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Settings><!--This file was automatically generated by Ruby plugin.
|
||||||
|
You are allowed to:
|
||||||
|
1. Remove rake task
|
||||||
|
2. Add existing rake tasks
|
||||||
|
To add existing rake tasks automatically delete this file and reload the project.
|
||||||
|
--><RakeGroup description="" fullCmd="" taksId="rake" /></Settings>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
||||||
|
ref: refs/heads/master
|
|
@ -0,0 +1,6 @@
|
||||||
|
[core]
|
||||||
|
repositoryformatversion = 0
|
||||||
|
filemode = true
|
||||||
|
bare = true
|
||||||
|
ignorecase = true
|
||||||
|
precomposeunicode = true
|
|
@ -0,0 +1 @@
|
||||||
|
Unnamed repository; edit this file 'description' to name the repository.
|
|
@ -0,0 +1,15 @@
|
||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# An example hook script to check the commit log message taken by
|
||||||
|
# applypatch from an e-mail message.
|
||||||
|
#
|
||||||
|
# The hook should exit with non-zero status after issuing an
|
||||||
|
# appropriate message if it wants to stop the commit. The hook is
|
||||||
|
# allowed to edit the commit message file.
|
||||||
|
#
|
||||||
|
# To enable this hook, rename this file to "applypatch-msg".
|
||||||
|
|
||||||
|
. git-sh-setup
|
||||||
|
commitmsg="$(git rev-parse --git-path hooks/commit-msg)"
|
||||||
|
test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"}
|
||||||
|
:
|
|
@ -0,0 +1,24 @@
|
||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# An example hook script to check the commit log message.
|
||||||
|
# Called by "git commit" with one argument, the name of the file
|
||||||
|
# that has the commit message. The hook should exit with non-zero
|
||||||
|
# status after issuing an appropriate message if it wants to stop the
|
||||||
|
# commit. The hook is allowed to edit the commit message file.
|
||||||
|
#
|
||||||
|
# To enable this hook, rename this file to "commit-msg".
|
||||||
|
|
||||||
|
# Uncomment the below to add a Signed-off-by line to the message.
|
||||||
|
# Doing this in a hook is a bad idea in general, but the prepare-commit-msg
|
||||||
|
# hook is more suited to it.
|
||||||
|
#
|
||||||
|
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
|
||||||
|
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
|
||||||
|
|
||||||
|
# This example catches duplicate Signed-off-by lines.
|
||||||
|
|
||||||
|
test "" = "$(grep '^Signed-off-by: ' "$1" |
|
||||||
|
sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || {
|
||||||
|
echo >&2 Duplicate Signed-off-by lines.
|
||||||
|
exit 1
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# An example hook script to prepare a packed repository for use over
|
||||||
|
# dumb transports.
|
||||||
|
#
|
||||||
|
# To enable this hook, rename this file to "post-update".
|
||||||
|
|
||||||
|
exec git update-server-info
|
|
@ -0,0 +1,14 @@
|
||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# An example hook script to verify what is about to be committed
|
||||||
|
# by applypatch from an e-mail message.
|
||||||
|
#
|
||||||
|
# The hook should exit with non-zero status after issuing an
|
||||||
|
# appropriate message if it wants to stop the commit.
|
||||||
|
#
|
||||||
|
# To enable this hook, rename this file to "pre-applypatch".
|
||||||
|
|
||||||
|
. git-sh-setup
|
||||||
|
precommit="$(git rev-parse --git-path hooks/pre-commit)"
|
||||||
|
test -x "$precommit" && exec "$precommit" ${1+"$@"}
|
||||||
|
:
|
|
@ -0,0 +1,49 @@
|
||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# An example hook script to verify what is about to be committed.
|
||||||
|
# Called by "git commit" with no arguments. The hook should
|
||||||
|
# exit with non-zero status after issuing an appropriate message if
|
||||||
|
# it wants to stop the commit.
|
||||||
|
#
|
||||||
|
# To enable this hook, rename this file to "pre-commit".
|
||||||
|
|
||||||
|
if git rev-parse --verify HEAD >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
against=HEAD
|
||||||
|
else
|
||||||
|
# Initial commit: diff against an empty tree object
|
||||||
|
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If you want to allow non-ASCII filenames set this variable to true.
|
||||||
|
allownonascii=$(git config --bool hooks.allownonascii)
|
||||||
|
|
||||||
|
# Redirect output to stderr.
|
||||||
|
exec 1>&2
|
||||||
|
|
||||||
|
# Cross platform projects tend to avoid non-ASCII filenames; prevent
|
||||||
|
# them from being added to the repository. We exploit the fact that the
|
||||||
|
# printable range starts at the space character and ends with tilde.
|
||||||
|
if [ "$allownonascii" != "true" ] &&
|
||||||
|
# Note that the use of brackets around a tr range is ok here, (it's
|
||||||
|
# even required, for portability to Solaris 10's /usr/bin/tr), since
|
||||||
|
# the square bracket bytes happen to fall in the designated range.
|
||||||
|
test $(git diff --cached --name-only --diff-filter=A -z $against |
|
||||||
|
LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
|
||||||
|
then
|
||||||
|
cat <<\EOF
|
||||||
|
Error: Attempt to add a non-ASCII file name.
|
||||||
|
|
||||||
|
This can cause problems if you want to work with people on other platforms.
|
||||||
|
|
||||||
|
To be portable it is advisable to rename the file.
|
||||||
|
|
||||||
|
If you know what you are doing you can disable this check using:
|
||||||
|
|
||||||
|
git config hooks.allownonascii true
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If there are whitespace errors, print the offending file names and fail.
|
||||||
|
exec git diff-index --check --cached $against --
|
|
@ -0,0 +1,53 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# An example hook script to verify what is about to be pushed. Called by "git
|
||||||
|
# push" after it has checked the remote status, but before anything has been
|
||||||
|
# pushed. If this script exits with a non-zero status nothing will be pushed.
|
||||||
|
#
|
||||||
|
# This hook is called with the following parameters:
|
||||||
|
#
|
||||||
|
# $1 -- Name of the remote to which the push is being done
|
||||||
|
# $2 -- URL to which the push is being done
|
||||||
|
#
|
||||||
|
# If pushing without using a named remote those arguments will be equal.
|
||||||
|
#
|
||||||
|
# Information about the commits which are being pushed is supplied as lines to
|
||||||
|
# the standard input in the form:
|
||||||
|
#
|
||||||
|
# <local ref> <local sha1> <remote ref> <remote sha1>
|
||||||
|
#
|
||||||
|
# This sample shows how to prevent push of commits where the log message starts
|
||||||
|
# with "WIP" (work in progress).
|
||||||
|
|
||||||
|
remote="$1"
|
||||||
|
url="$2"
|
||||||
|
|
||||||
|
z40=0000000000000000000000000000000000000000
|
||||||
|
|
||||||
|
while read local_ref local_sha remote_ref remote_sha
|
||||||
|
do
|
||||||
|
if [ "$local_sha" = $z40 ]
|
||||||
|
then
|
||||||
|
# Handle delete
|
||||||
|
:
|
||||||
|
else
|
||||||
|
if [ "$remote_sha" = $z40 ]
|
||||||
|
then
|
||||||
|
# New branch, examine all commits
|
||||||
|
range="$local_sha"
|
||||||
|
else
|
||||||
|
# Update to existing branch, examine new commits
|
||||||
|
range="$remote_sha..$local_sha"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for WIP commit
|
||||||
|
commit=`git rev-list -n 1 --grep '^WIP' "$range"`
|
||||||
|
if [ -n "$commit" ]
|
||||||
|
then
|
||||||
|
echo >&2 "Found WIP commit in $local_ref, not pushing"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
exit 0
|
|
@ -0,0 +1,169 @@
|
||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Copyright (c) 2006, 2008 Junio C Hamano
|
||||||
|
#
|
||||||
|
# The "pre-rebase" hook is run just before "git rebase" starts doing
|
||||||
|
# its job, and can prevent the command from running by exiting with
|
||||||
|
# non-zero status.
|
||||||
|
#
|
||||||
|
# The hook is called with the following parameters:
|
||||||
|
#
|
||||||
|
# $1 -- the upstream the series was forked from.
|
||||||
|
# $2 -- the branch being rebased (or empty when rebasing the current branch).
|
||||||
|
#
|
||||||
|
# This sample shows how to prevent topic branches that are already
|
||||||
|
# merged to 'next' branch from getting rebased, because allowing it
|
||||||
|
# would result in rebasing already published history.
|
||||||
|
|
||||||
|
publish=next
|
||||||
|
basebranch="$1"
|
||||||
|
if test "$#" = 2
|
||||||
|
then
|
||||||
|
topic="refs/heads/$2"
|
||||||
|
else
|
||||||
|
topic=`git symbolic-ref HEAD` ||
|
||||||
|
exit 0 ;# we do not interrupt rebasing detached HEAD
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$topic" in
|
||||||
|
refs/heads/??/*)
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
exit 0 ;# we do not interrupt others.
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Now we are dealing with a topic branch being rebased
|
||||||
|
# on top of master. Is it OK to rebase it?
|
||||||
|
|
||||||
|
# Does the topic really exist?
|
||||||
|
git show-ref -q "$topic" || {
|
||||||
|
echo >&2 "No such branch $topic"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Is topic fully merged to master?
|
||||||
|
not_in_master=`git rev-list --pretty=oneline ^master "$topic"`
|
||||||
|
if test -z "$not_in_master"
|
||||||
|
then
|
||||||
|
echo >&2 "$topic is fully merged to master; better remove it."
|
||||||
|
exit 1 ;# we could allow it, but there is no point.
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Is topic ever merged to next? If so you should not be rebasing it.
|
||||||
|
only_next_1=`git rev-list ^master "^$topic" ${publish} | sort`
|
||||||
|
only_next_2=`git rev-list ^master ${publish} | sort`
|
||||||
|
if test "$only_next_1" = "$only_next_2"
|
||||||
|
then
|
||||||
|
not_in_topic=`git rev-list "^$topic" master`
|
||||||
|
if test -z "$not_in_topic"
|
||||||
|
then
|
||||||
|
echo >&2 "$topic is already up-to-date with master"
|
||||||
|
exit 1 ;# we could allow it, but there is no point.
|
||||||
|
else
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"`
|
||||||
|
/usr/bin/perl -e '
|
||||||
|
my $topic = $ARGV[0];
|
||||||
|
my $msg = "* $topic has commits already merged to public branch:\n";
|
||||||
|
my (%not_in_next) = map {
|
||||||
|
/^([0-9a-f]+) /;
|
||||||
|
($1 => 1);
|
||||||
|
} split(/\n/, $ARGV[1]);
|
||||||
|
for my $elem (map {
|
||||||
|
/^([0-9a-f]+) (.*)$/;
|
||||||
|
[$1 => $2];
|
||||||
|
} split(/\n/, $ARGV[2])) {
|
||||||
|
if (!exists $not_in_next{$elem->[0]}) {
|
||||||
|
if ($msg) {
|
||||||
|
print STDERR $msg;
|
||||||
|
undef $msg;
|
||||||
|
}
|
||||||
|
print STDERR " $elem->[1]\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
' "$topic" "$not_in_next" "$not_in_master"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
<<\DOC_END
|
||||||
|
|
||||||
|
This sample hook safeguards topic branches that have been
|
||||||
|
published from being rewound.
|
||||||
|
|
||||||
|
The workflow assumed here is:
|
||||||
|
|
||||||
|
* Once a topic branch forks from "master", "master" is never
|
||||||
|
merged into it again (either directly or indirectly).
|
||||||
|
|
||||||
|
* Once a topic branch is fully cooked and merged into "master",
|
||||||
|
it is deleted. If you need to build on top of it to correct
|
||||||
|
earlier mistakes, a new topic branch is created by forking at
|
||||||
|
the tip of the "master". This is not strictly necessary, but
|
||||||
|
it makes it easier to keep your history simple.
|
||||||
|
|
||||||
|
* Whenever you need to test or publish your changes to topic
|
||||||
|
branches, merge them into "next" branch.
|
||||||
|
|
||||||
|
The script, being an example, hardcodes the publish branch name
|
||||||
|
to be "next", but it is trivial to make it configurable via
|
||||||
|
$GIT_DIR/config mechanism.
|
||||||
|
|
||||||
|
With this workflow, you would want to know:
|
||||||
|
|
||||||
|
(1) ... if a topic branch has ever been merged to "next". Young
|
||||||
|
topic branches can have stupid mistakes you would rather
|
||||||
|
clean up before publishing, and things that have not been
|
||||||
|
merged into other branches can be easily rebased without
|
||||||
|
affecting other people. But once it is published, you would
|
||||||
|
not want to rewind it.
|
||||||
|
|
||||||
|
(2) ... if a topic branch has been fully merged to "master".
|
||||||
|
Then you can delete it. More importantly, you should not
|
||||||
|
build on top of it -- other people may already want to
|
||||||
|
change things related to the topic as patches against your
|
||||||
|
"master", so if you need further changes, it is better to
|
||||||
|
fork the topic (perhaps with the same name) afresh from the
|
||||||
|
tip of "master".
|
||||||
|
|
||||||
|
Let's look at this example:
|
||||||
|
|
||||||
|
o---o---o---o---o---o---o---o---o---o "next"
|
||||||
|
/ / / /
|
||||||
|
/ a---a---b A / /
|
||||||
|
/ / / /
|
||||||
|
/ / c---c---c---c B /
|
||||||
|
/ / / \ /
|
||||||
|
/ / / b---b C \ /
|
||||||
|
/ / / / \ /
|
||||||
|
---o---o---o---o---o---o---o---o---o---o---o "master"
|
||||||
|
|
||||||
|
|
||||||
|
A, B and C are topic branches.
|
||||||
|
|
||||||
|
* A has one fix since it was merged up to "next".
|
||||||
|
|
||||||
|
* B has finished. It has been fully merged up to "master" and "next",
|
||||||
|
and is ready to be deleted.
|
||||||
|
|
||||||
|
* C has not merged to "next" at all.
|
||||||
|
|
||||||
|
We would want to allow C to be rebased, refuse A, and encourage
|
||||||
|
B to be deleted.
|
||||||
|
|
||||||
|
To compute (1):
|
||||||
|
|
||||||
|
git rev-list ^master ^topic next
|
||||||
|
git rev-list ^master next
|
||||||
|
|
||||||
|
if these match, topic has not merged in next at all.
|
||||||
|
|
||||||
|
To compute (2):
|
||||||
|
|
||||||
|
git rev-list master..topic
|
||||||
|
|
||||||
|
if this is empty, it is fully merged to "master".
|
||||||
|
|
||||||
|
DOC_END
|
|
@ -0,0 +1,24 @@
|
||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# An example hook script to make use of push options.
|
||||||
|
# The example simply echoes all push options that start with 'echoback='
|
||||||
|
# and rejects all pushes when the "reject" push option is used.
|
||||||
|
#
|
||||||
|
# To enable this hook, rename this file to "pre-receive".
|
||||||
|
|
||||||
|
if test -n "$GIT_PUSH_OPTION_COUNT"
|
||||||
|
then
|
||||||
|
i=0
|
||||||
|
while test "$i" -lt "$GIT_PUSH_OPTION_COUNT"
|
||||||
|
do
|
||||||
|
eval "value=\$GIT_PUSH_OPTION_$i"
|
||||||
|
case "$value" in
|
||||||
|
echoback=*)
|
||||||
|
echo "echo from the pre-receive-hook: ${value#*=}" >&2
|
||||||
|
;;
|
||||||
|
reject)
|
||||||
|
exit 1
|
||||||
|
esac
|
||||||
|
i=$((i + 1))
|
||||||
|
done
|
||||||
|
fi
|
|
@ -0,0 +1,36 @@
|
||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# An example hook script to prepare the commit log message.
|
||||||
|
# Called by "git commit" with the name of the file that has the
|
||||||
|
# commit message, followed by the description of the commit
|
||||||
|
# message's source. The hook's purpose is to edit the commit
|
||||||
|
# message file. If the hook fails with a non-zero status,
|
||||||
|
# the commit is aborted.
|
||||||
|
#
|
||||||
|
# To enable this hook, rename this file to "prepare-commit-msg".
|
||||||
|
|
||||||
|
# This hook includes three examples. The first comments out the
|
||||||
|
# "Conflicts:" part of a merge commit.
|
||||||
|
#
|
||||||
|
# The second includes the output of "git diff --name-status -r"
|
||||||
|
# into the message, just before the "git status" output. It is
|
||||||
|
# commented because it doesn't cope with --amend or with squashed
|
||||||
|
# commits.
|
||||||
|
#
|
||||||
|
# The third example adds a Signed-off-by line to the message, that can
|
||||||
|
# still be edited. This is rarely a good idea.
|
||||||
|
|
||||||
|
case "$2,$3" in
|
||||||
|
merge,)
|
||||||
|
/usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;;
|
||||||
|
|
||||||
|
# ,|template,)
|
||||||
|
# /usr/bin/perl -i.bak -pe '
|
||||||
|
# print "\n" . `git diff --cached --name-status -r`
|
||||||
|
# if /^#/ && $first++ == 0' "$1" ;;
|
||||||
|
|
||||||
|
*) ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p')
|
||||||
|
# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1"
|
|
@ -0,0 +1,128 @@
|
||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# An example hook script to block unannotated tags from entering.
|
||||||
|
# Called by "git receive-pack" with arguments: refname sha1-old sha1-new
|
||||||
|
#
|
||||||
|
# To enable this hook, rename this file to "update".
|
||||||
|
#
|
||||||
|
# Config
|
||||||
|
# ------
|
||||||
|
# hooks.allowunannotated
|
||||||
|
# This boolean sets whether unannotated tags will be allowed into the
|
||||||
|
# repository. By default they won't be.
|
||||||
|
# hooks.allowdeletetag
|
||||||
|
# This boolean sets whether deleting tags will be allowed in the
|
||||||
|
# repository. By default they won't be.
|
||||||
|
# hooks.allowmodifytag
|
||||||
|
# This boolean sets whether a tag may be modified after creation. By default
|
||||||
|
# it won't be.
|
||||||
|
# hooks.allowdeletebranch
|
||||||
|
# This boolean sets whether deleting branches will be allowed in the
|
||||||
|
# repository. By default they won't be.
|
||||||
|
# hooks.denycreatebranch
|
||||||
|
# This boolean sets whether remotely creating branches will be denied
|
||||||
|
# in the repository. By default this is allowed.
|
||||||
|
#
|
||||||
|
|
||||||
|
# --- Command line
|
||||||
|
refname="$1"
|
||||||
|
oldrev="$2"
|
||||||
|
newrev="$3"
|
||||||
|
|
||||||
|
# --- Safety check
|
||||||
|
if [ -z "$GIT_DIR" ]; then
|
||||||
|
echo "Don't run this script from the command line." >&2
|
||||||
|
echo " (if you want, you could supply GIT_DIR then run" >&2
|
||||||
|
echo " $0 <ref> <oldrev> <newrev>)" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then
|
||||||
|
echo "usage: $0 <ref> <oldrev> <newrev>" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# --- Config
|
||||||
|
allowunannotated=$(git config --bool hooks.allowunannotated)
|
||||||
|
allowdeletebranch=$(git config --bool hooks.allowdeletebranch)
|
||||||
|
denycreatebranch=$(git config --bool hooks.denycreatebranch)
|
||||||
|
allowdeletetag=$(git config --bool hooks.allowdeletetag)
|
||||||
|
allowmodifytag=$(git config --bool hooks.allowmodifytag)
|
||||||
|
|
||||||
|
# check for no description
|
||||||
|
projectdesc=$(sed -e '1q' "$GIT_DIR/description")
|
||||||
|
case "$projectdesc" in
|
||||||
|
"Unnamed repository"* | "")
|
||||||
|
echo "*** Project description file hasn't been set" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# --- Check types
|
||||||
|
# if $newrev is 0000...0000, it's a commit to delete a ref.
|
||||||
|
zero="0000000000000000000000000000000000000000"
|
||||||
|
if [ "$newrev" = "$zero" ]; then
|
||||||
|
newrev_type=delete
|
||||||
|
else
|
||||||
|
newrev_type=$(git cat-file -t $newrev)
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$refname","$newrev_type" in
|
||||||
|
refs/tags/*,commit)
|
||||||
|
# un-annotated tag
|
||||||
|
short_refname=${refname##refs/tags/}
|
||||||
|
if [ "$allowunannotated" != "true" ]; then
|
||||||
|
echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2
|
||||||
|
echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
refs/tags/*,delete)
|
||||||
|
# delete tag
|
||||||
|
if [ "$allowdeletetag" != "true" ]; then
|
||||||
|
echo "*** Deleting a tag is not allowed in this repository" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
refs/tags/*,tag)
|
||||||
|
# annotated tag
|
||||||
|
if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1
|
||||||
|
then
|
||||||
|
echo "*** Tag '$refname' already exists." >&2
|
||||||
|
echo "*** Modifying a tag is not allowed in this repository." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
refs/heads/*,commit)
|
||||||
|
# branch
|
||||||
|
if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then
|
||||||
|
echo "*** Creating a branch is not allowed in this repository" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
refs/heads/*,delete)
|
||||||
|
# delete branch
|
||||||
|
if [ "$allowdeletebranch" != "true" ]; then
|
||||||
|
echo "*** Deleting a branch is not allowed in this repository" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
refs/remotes/*,commit)
|
||||||
|
# tracking branch
|
||||||
|
;;
|
||||||
|
refs/remotes/*,delete)
|
||||||
|
# delete tracking branch
|
||||||
|
if [ "$allowdeletebranch" != "true" ]; then
|
||||||
|
echo "*** Deleting a tracking branch is not allowed in this repository" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# Anything else (is there anything else?)
|
||||||
|
echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# --- Finished
|
||||||
|
exit 0
|
|
@ -0,0 +1,6 @@
|
||||||
|
# git ls-files --others --exclude-from=.git/info/exclude
|
||||||
|
# Lines that start with '#' are comments.
|
||||||
|
# For a project mostly in C, the following would be a good set of
|
||||||
|
# exclude patterns (uncomment them if you want to use them):
|
||||||
|
# *.[oa]
|
||||||
|
# *~
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
||||||
|
5ca322560f72403ec54e015f2f41fb87a4c10945
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Settings><!--This file was automatically generated by Ruby plugin.
|
||||||
|
You are allowed to:
|
||||||
|
1. Remove rake task
|
||||||
|
2. Add existing rake tasks
|
||||||
|
To add existing rake tasks automatically delete this file and reload the project.
|
||||||
|
--><RakeGroup description="" fullCmd="" taksId="rake" /></Settings>
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Settings><!--This file was automatically generated by Ruby plugin.
|
||||||
|
You are allowed to:
|
||||||
|
1. Remove rake task
|
||||||
|
2. Add existing rake tasks
|
||||||
|
To add existing rake tasks automatically delete this file and reload the project.
|
||||||
|
--><RakeGroup description="" fullCmd="" taksId="rake" /></Settings>
|
|
@ -0,0 +1,40 @@
|
||||||
|
PATH
|
||||||
|
remote: .
|
||||||
|
specs:
|
||||||
|
rails_kindeditor (0.4.5)
|
||||||
|
carrierwave
|
||||||
|
mini_magick
|
||||||
|
|
||||||
|
GEM
|
||||||
|
remote: https://gems.ruby-china.com/
|
||||||
|
specs:
|
||||||
|
activemodel (3.2.22.5)
|
||||||
|
activesupport (= 3.2.22.5)
|
||||||
|
builder (~> 3.0.0)
|
||||||
|
activesupport (3.2.22.5)
|
||||||
|
i18n (~> 0.6, >= 0.6.4)
|
||||||
|
multi_json (~> 1.0)
|
||||||
|
builder (3.0.0)
|
||||||
|
carrierwave (0.11.2)
|
||||||
|
activemodel (>= 3.2.0)
|
||||||
|
activesupport (>= 3.2.0)
|
||||||
|
json (>= 1.7)
|
||||||
|
mime-types (>= 1.16)
|
||||||
|
mimemagic (>= 0.3.0)
|
||||||
|
i18n (0.6.11)
|
||||||
|
json (1.8.6)
|
||||||
|
mime-types (1.25.1)
|
||||||
|
mimemagic (0.3.2)
|
||||||
|
mini_magick (4.8.0)
|
||||||
|
multi_json (1.13.1)
|
||||||
|
|
||||||
|
PLATFORMS
|
||||||
|
ruby
|
||||||
|
|
||||||
|
DEPENDENCIES
|
||||||
|
carrierwave
|
||||||
|
mini_magick
|
||||||
|
rails_kindeditor!
|
||||||
|
|
||||||
|
BUNDLED WITH
|
||||||
|
1.16.1
|
|
@ -4,3 +4,4 @@ require 'trustie/gitlab/api'
|
||||||
require 'trustie/grack/grack'
|
require 'trustie/grack/grack'
|
||||||
require 'trustie/at/at'
|
require 'trustie/at/at'
|
||||||
require 'trustie/sms/sms'
|
require 'trustie/sms/sms'
|
||||||
|
require 'trustie/http/http'
|
|
@ -0,0 +1,46 @@
|
||||||
|
#coding=utf-8
|
||||||
|
|
||||||
|
require 'net/http'
|
||||||
|
require 'uri'
|
||||||
|
|
||||||
|
|
||||||
|
module Trustie
|
||||||
|
module Http
|
||||||
|
|
||||||
|
def get(url)
|
||||||
|
uri = URI(url)
|
||||||
|
res = Net::HTTP.start(uri.host, uri.port, use_ssl: url.start_with?('https')) do |http|
|
||||||
|
req = Net::HTTP::Get.new(uri)
|
||||||
|
#req['Content-Type'] = 'application/json'
|
||||||
|
# The body needs to be a JSON string, use whatever you know to parse Hash to JSON
|
||||||
|
#req.body = {a: 1}.to_json
|
||||||
|
http.request(req)
|
||||||
|
end
|
||||||
|
|
||||||
|
res.body
|
||||||
|
end
|
||||||
|
|
||||||
|
def post(url, data=nil)
|
||||||
|
uri = URI(url)
|
||||||
|
res = Net::HTTP.start(uri.host, uri.port, use_ssl: url.start_with?('https')) do |http|
|
||||||
|
req = Net::HTTP::Post.new(uri)
|
||||||
|
#req['Content-Type'] = 'application/json'
|
||||||
|
# The body needs to be a JSON string, use whatever you know to parse Hash to JSON
|
||||||
|
req.body = data if data
|
||||||
|
http.request(req)
|
||||||
|
end
|
||||||
|
|
||||||
|
res.body
|
||||||
|
end
|
||||||
|
|
||||||
|
def decode(s)
|
||||||
|
begin
|
||||||
|
obj = ActiveSupport::JSON.decode(s)
|
||||||
|
rescue ActiveSupport::JSON.parse_error
|
||||||
|
logger.error("Attempted to decode invalid JSON: #{s}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Settings><!--This file was automatically generated by Ruby plugin.
|
||||||
|
You are allowed to:
|
||||||
|
1. Remove rake task
|
||||||
|
2. Add existing rake tasks
|
||||||
|
To add existing rake tasks automatically delete this file and reload the project.
|
||||||
|
--><RakeGroup description="" fullCmd="" taksId="rake" /></Settings>
|
|
@ -0,0 +1,129 @@
|
||||||
|
GEM
|
||||||
|
remote: https://gems.ruby-china.com/
|
||||||
|
specs:
|
||||||
|
actionmailer (3.2.22.5)
|
||||||
|
actionpack (= 3.2.22.5)
|
||||||
|
mail (~> 2.5.4)
|
||||||
|
actionpack (3.2.22.5)
|
||||||
|
activemodel (= 3.2.22.5)
|
||||||
|
activesupport (= 3.2.22.5)
|
||||||
|
builder (~> 3.0.0)
|
||||||
|
erubis (~> 2.7.0)
|
||||||
|
journey (~> 1.0.4)
|
||||||
|
rack (~> 1.4.5)
|
||||||
|
rack-cache (~> 1.2)
|
||||||
|
rack-test (~> 0.6.1)
|
||||||
|
sprockets (~> 2.2.1)
|
||||||
|
activemodel (3.2.22.5)
|
||||||
|
activesupport (= 3.2.22.5)
|
||||||
|
builder (~> 3.0.0)
|
||||||
|
activerecord (3.2.22.5)
|
||||||
|
activemodel (= 3.2.22.5)
|
||||||
|
activesupport (= 3.2.22.5)
|
||||||
|
arel (~> 3.0.2)
|
||||||
|
tzinfo (~> 0.3.29)
|
||||||
|
activeresource (3.2.22.5)
|
||||||
|
activemodel (= 3.2.22.5)
|
||||||
|
activesupport (= 3.2.22.5)
|
||||||
|
activesupport (3.2.22.5)
|
||||||
|
i18n (~> 0.6, >= 0.6.4)
|
||||||
|
multi_json (~> 1.0)
|
||||||
|
arel (3.0.3)
|
||||||
|
builder (3.0.0)
|
||||||
|
climate_control (0.2.0)
|
||||||
|
cocaine (0.5.8)
|
||||||
|
climate_control (>= 0.0.3, < 1.0)
|
||||||
|
erubis (2.7.0)
|
||||||
|
ffi (1.9.21)
|
||||||
|
hike (1.2.3)
|
||||||
|
htmlentities (4.3.4)
|
||||||
|
i18n (0.6.11)
|
||||||
|
journey (1.0.4)
|
||||||
|
jquery-rails (2.0.3)
|
||||||
|
railties (>= 3.1.0, < 5.0)
|
||||||
|
thor (~> 0.14)
|
||||||
|
json (1.8.6)
|
||||||
|
kaminari (0.17.0)
|
||||||
|
actionpack (>= 3.0.0)
|
||||||
|
activesupport (>= 3.0.0)
|
||||||
|
mail (2.5.5)
|
||||||
|
mime-types (~> 1.16)
|
||||||
|
treetop (~> 1.4.8)
|
||||||
|
mime-types (1.25.1)
|
||||||
|
multi_json (1.13.1)
|
||||||
|
paperclip (3.5.4)
|
||||||
|
activemodel (>= 3.0.0)
|
||||||
|
activesupport (>= 3.0.0)
|
||||||
|
cocaine (~> 0.5.3)
|
||||||
|
mime-types
|
||||||
|
polyglot (0.3.5)
|
||||||
|
rack (1.4.7)
|
||||||
|
rack-cache (1.7.1)
|
||||||
|
rack (>= 0.4)
|
||||||
|
rack-raw-upload (1.1.1)
|
||||||
|
multi_json
|
||||||
|
rack-ssl (1.3.4)
|
||||||
|
rack
|
||||||
|
rack-test (0.6.3)
|
||||||
|
rack (>= 1.0)
|
||||||
|
rails (3.2.22.5)
|
||||||
|
actionmailer (= 3.2.22.5)
|
||||||
|
actionpack (= 3.2.22.5)
|
||||||
|
activerecord (= 3.2.22.5)
|
||||||
|
activeresource (= 3.2.22.5)
|
||||||
|
activesupport (= 3.2.22.5)
|
||||||
|
bundler (~> 1.0)
|
||||||
|
railties (= 3.2.22.5)
|
||||||
|
railties (3.2.22.5)
|
||||||
|
actionpack (= 3.2.22.5)
|
||||||
|
activesupport (= 3.2.22.5)
|
||||||
|
rack-ssl (~> 1.3.2)
|
||||||
|
rake (>= 0.8.7)
|
||||||
|
rdoc (~> 3.4)
|
||||||
|
thor (>= 0.14.6, < 2.0)
|
||||||
|
rake (12.3.0)
|
||||||
|
rb-fsevent (0.10.2)
|
||||||
|
rb-inotify (0.9.10)
|
||||||
|
ffi (>= 0.5.0, < 2)
|
||||||
|
rdoc (3.12.2)
|
||||||
|
json (~> 1.4)
|
||||||
|
rich (1.4.6)
|
||||||
|
jquery-rails
|
||||||
|
kaminari
|
||||||
|
mime-types
|
||||||
|
paperclip
|
||||||
|
rack-raw-upload
|
||||||
|
rails (>= 3.2.0)
|
||||||
|
sass-rails
|
||||||
|
sass (3.5.5)
|
||||||
|
sass-listen (~> 4.0.0)
|
||||||
|
sass-listen (4.0.0)
|
||||||
|
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||||
|
rb-inotify (~> 0.9, >= 0.9.7)
|
||||||
|
sass-rails (3.2.6)
|
||||||
|
railties (~> 3.2.0)
|
||||||
|
sass (>= 3.1.10)
|
||||||
|
tilt (~> 1.3)
|
||||||
|
sprockets (2.2.3)
|
||||||
|
hike (~> 1.2)
|
||||||
|
multi_json (~> 1.0)
|
||||||
|
rack (~> 1.0)
|
||||||
|
tilt (~> 1.1, != 1.3.0)
|
||||||
|
thor (0.20.0)
|
||||||
|
tilt (1.4.1)
|
||||||
|
treetop (1.4.15)
|
||||||
|
polyglot
|
||||||
|
polyglot (>= 0.3.1)
|
||||||
|
tzinfo (0.3.53)
|
||||||
|
|
||||||
|
PLATFORMS
|
||||||
|
ruby
|
||||||
|
|
||||||
|
DEPENDENCIES
|
||||||
|
htmlentities
|
||||||
|
kaminari
|
||||||
|
paperclip (~> 3.5.4)
|
||||||
|
rich (= 1.4.6)
|
||||||
|
|
||||||
|
BUNDLED WITH
|
||||||
|
1.16.1
|
|
@ -40,8 +40,8 @@ function regexTopicDescription()
|
||||||
$("#message_content_span").css('color','#ff0000');
|
$("#message_content_span").css('color','#ff0000');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if(name.length >=20000){
|
else if(name.length >=60000){
|
||||||
$("#message_content_span").text("描述最多20000个汉字(或40000个英文字符)");
|
$("#message_content_span").text("描述最多60000个汉字(或120000个英文字符)");
|
||||||
$("#message_content_span").css('color','#ff0000');
|
$("#message_content_span").css('color','#ff0000');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,8 @@ h4{ font-size:14px;}/*color:#3b3b3b;*/
|
||||||
.f16{font-size:16px;}
|
.f16{font-size:16px;}
|
||||||
.f18{font-size:18px;}
|
.f18{font-size:18px;}
|
||||||
.f20{font-size:20px;}
|
.f20{font-size:20px;}
|
||||||
|
.f40{font-size:40px!important;}
|
||||||
|
.f50{font-size:50px!important;}
|
||||||
.fb{font-weight:bold;}
|
.fb{font-weight:bold;}
|
||||||
.f_b{ font-weight: bold;}
|
.f_b{ font-weight: bold;}
|
||||||
.lh20{line-height:20px;}
|
.lh20{line-height:20px;}
|
||||||
|
@ -108,7 +110,7 @@ h4{ font-size:14px;}/*color:#3b3b3b;*/
|
||||||
.mt1{margin-top: 1px;}.mt2{ margin-top:2px;}.mt3{ margin-top:3px;}.mt4{ margin-top:4px;}.mt5{ margin-top:5px;}.mt6{ margin-top:6px;}.mt7 {margin-top:7px;}
|
.mt1{margin-top: 1px;}.mt2{ margin-top:2px;}.mt3{ margin-top:3px;}.mt4{ margin-top:4px;}.mt5{ margin-top:5px;}.mt6{ margin-top:6px;}.mt7 {margin-top:7px;}
|
||||||
.mt8{ margin-top:8px !important;}.mt9{ margin-top:9px !important;}.mt10{ margin-top:10px !important;}.mt12 { margin-top:12px !important;}.mt14 {margin-top:14px;}
|
.mt8{ margin-top:8px !important;}.mt9{ margin-top:9px !important;}.mt10{ margin-top:10px !important;}.mt12 { margin-top:12px !important;}.mt14 {margin-top:14px;}
|
||||||
.mt15 {margin-top:15px;}.mt16{ margin-top:16px !important;}.mt19 {margin-top:19px !important;}.mt20{margin-top: 20px;}.mt28 {margin-top:28px;}.mt30{ margin-top: 30px;}
|
.mt15 {margin-top:15px;}.mt16{ margin-top:16px !important;}.mt19 {margin-top:19px !important;}.mt20{margin-top: 20px;}.mt28 {margin-top:28px;}.mt30{ margin-top: 30px;}
|
||||||
.mt35 {margin-top:35px;}.mt40{ margin-top: 40px;}.mt45{ margin-top: 45px;}.mt50{ margin-top:50px;}.mt100{ margin-top:100px;}.mb0 {margin-bottom: 0px !important;}.mb4{ margin-bottom:4px;}
|
.mt35 {margin-top:35px;}.mt40{ margin-top: 40px;}.mt45{ margin-top: 45px;}.mt50{ margin-top:50px;}.mt60{ margin-top:60px;}.mt100{ margin-top:100px;}.mb0 {margin-bottom: 0px !important;}.mb4{ margin-bottom:4px;}
|
||||||
.mb5{ margin-bottom:5px;}.mb8 {margin-bottom:8px !important;}.pb5{ padding-bottom: 5px;}.mb10{ margin-bottom:10px !important;}.mb12 {margin-bottom:12px !important;}
|
.mb5{ margin-bottom:5px;}.mb8 {margin-bottom:8px !important;}.pb5{ padding-bottom: 5px;}.mb10{ margin-bottom:10px !important;}.mb12 {margin-bottom:12px !important;}
|
||||||
.mb15{margin-bottom: 15px;}.mb20{ margin-bottom:20px;}.mb25{ margin-bottom:25px;}.mb30 {margin-bottom:30px;}.mb40 {margin-bottom:40px;}.pl5{ padding-left:5px;}
|
.mb15{margin-bottom: 15px;}.mb20{ margin-bottom:20px;}.mb25{ margin-bottom:25px;}.mb30 {margin-bottom:30px;}.mb40 {margin-bottom:40px;}.pl5{ padding-left:5px;}
|
||||||
.pl10 {padding-left:10px;}.pr5 {padding-right:5px;}.pr10{padding-right: 10px;}.pl62 {padding-left: 62px;}.pl15{ padding-left:15px;}.pt5{ padding-top:5px;}
|
.pl10 {padding-left:10px;}.pr5 {padding-right:5px;}.pr10{padding-right: 10px;}.pl62 {padding-left: 62px;}.pl15{ padding-left:15px;}.pt5{ padding-top:5px;}
|
||||||
|
@ -530,4 +532,6 @@ a:hover.btn_green_64_width{ background: #14ad5a; color: #fff;}
|
||||||
.c-white {color:#ffffff;}
|
.c-white {color:#ffffff;}
|
||||||
.c-black {color:#333}
|
.c-black {color:#333}
|
||||||
|
|
||||||
.bg_white_bor{background-color: #fff;border:1px solid #dddddd}
|
.bg_white_bor{background-color: #fff;border:1px solid #dddddd}
|
||||||
|
|
||||||
|
#intro_content p{word-break:break-word!important;}
|
|
@ -802,6 +802,8 @@ input.new_loggin_input{ -webkit-box-shadow: 0 0 0px 1000px white inset; outline:
|
||||||
.new_login_txt h3{ font-size:18px;text-align:center;margin-bottom:20px;}
|
.new_login_txt h3{ font-size:18px;text-align:center;margin-bottom:20px;}
|
||||||
.new_login_txt p{ line-height:2.0;}
|
.new_login_txt p{ line-height:2.0;}
|
||||||
.new_register_left{margin-top:250px;}
|
.new_register_left{margin-top:250px;}
|
||||||
|
.oschinaBox{float: left;padding: 7px;border: 1px solid #fff;border-radius: 50%;width: 50px;height: 50px;box-sizing: border-box;}
|
||||||
|
.oschinaIcon{height: 40px;width: 40px;margin-left: -2px;display: block!important;font-size: 33px; margin-top: -2px;}
|
||||||
/*未登录回复提示*/
|
/*未登录回复提示*/
|
||||||
.visitor-box {height:33px; line-height:33px; text-align:center; vertical-align: middle; border:1px solid #ccc; background-color: #fff;}
|
.visitor-box {height:33px; line-height:33px; text-align:center; vertical-align: middle; border:1px solid #ccc; background-color: #fff;}
|
||||||
/* 个人资料修改弹框 */
|
/* 个人资料修改弹框 */
|
||||||
|
|
|
@ -502,4 +502,14 @@ a.user_editinfo{border-top:1px solid #e5e5e5; height:30px; line-height:30px; tex
|
||||||
.messageInformationContents{ margin-right:10px; font-size:14px; color:#4b4b4b; display:block; overflow:hidden; white-space: nowrap; text-overflow:ellipsis;max-height:49px; float:left; }
|
.messageInformationContents{ margin-right:10px; font-size:14px; color:#4b4b4b; display:block; overflow:hidden; white-space: nowrap; text-overflow:ellipsis;max-height:49px; float:left; }
|
||||||
.homepageBackground{ background-color:#90C5EC; flex:1; text-align: center }
|
.homepageBackground{ background-color:#90C5EC; flex:1; text-align: center }
|
||||||
.homepageClickBackground{ background-color:#3b94d6; flex:1; text-align: center }
|
.homepageClickBackground{ background-color:#3b94d6; flex:1; text-align: center }
|
||||||
.flex-cell_homepage:hover{ background-color:#3b94d6;}
|
.flex-cell_homepage:hover{ background-color:#3b94d6;}
|
||||||
|
|
||||||
|
|
||||||
|
/*oschina授权页*/
|
||||||
|
.authTop{width: 100%;position: fixed;left: 0px;top:0px;background-color: #51B7EC;height: 58px;color: #fff;}
|
||||||
|
.authmain{width: 1000px;margin:0px auto;display: block!important;}
|
||||||
|
.auth-login-btn{width: 100px;height: 32px;line-height: 32px;margin-top:20px;margin-bottom:20px;text-align: center;color: #fff!important;font-size: 14px;display: inline-block;background-color: #4CACFF;border-radius: 2px;}
|
||||||
|
.auth-cancel-btn{width: 100px;height: 32px;line-height: 32px;margin-top:20px;margin-bottom:20px;text-align: center;color: #666!important;font-size: 14px;display: inline-block;background-color: #fff;border-radius: 2px;border:1px solid #eaeaea;}
|
||||||
|
.l-r-trustie{padding:50px;width: 350px;margin:100px auto;}
|
||||||
|
.l-r-trustie p{line-height: 40px;font-size: 15px;}
|
||||||
|
.checked-choose{margin-right: 5px;margin-top: 13px;float: left}
|
Loading…
Reference in New Issue