V20220125.patch
into develop
2 years ago
@@ -64,6 +64,11 @@ func Toggle(options *ToggleOptions) macaron.Handler { | |||
ctx.Redirect(setting.AppSubURL + "/") | |||
return | |||
} | |||
if ctx.QueryBool("course") { | |||
ctx.Redirect(setting.AppSubURL + "/" + setting.Course.OrgName) | |||
return | |||
} | |||
} | |||
// Redirect to dashboard if user tries to visit any non-login page. | |||
@@ -45,8 +45,8 @@ type Context struct { | |||
IsSigned bool | |||
IsBasicAuth bool | |||
Repo *Repository | |||
Org *Organization | |||
Repo *Repository | |||
Org *Organization | |||
Cloudbrain *models.Cloudbrain | |||
} | |||
@@ -347,9 +347,9 @@ func Contexter() macaron.Handler { | |||
ctx.Data["EnableSwagger"] = setting.API.EnableSwagger | |||
ctx.Data["EnableOpenIDSignIn"] = setting.Service.EnableOpenIDSignIn | |||
notice, _ := notice.GetNewestNotice() | |||
if notice != nil { | |||
ctx.Data["notice"] = *notice | |||
notices, _ := notice.GetNewestNotice() | |||
if notices != nil { | |||
ctx.Data["notices"] = notices | |||
} | |||
c.Map(ctx) | |||
} | |||
@@ -16,27 +16,31 @@ const ( | |||
) | |||
type Notice struct { | |||
Title string | |||
Link string | |||
Visible int //0 invisible, 1 visible | |||
Title string | |||
Link string | |||
Visible int //0 invisible, 1 visible | |||
} | |||
type NoticeResponse struct { | |||
Notices []*Notice | |||
CommitId string | |||
} | |||
var lock int32 = 0 | |||
func GetNewestNotice() (*Notice, error) { | |||
func GetNewestNotice() (*NoticeResponse, error) { | |||
defer func() { | |||
if err := recover(); err != nil { | |||
log.Error("recover error", err) | |||
} | |||
}() | |||
var notice *Notice | |||
var notice *NoticeResponse | |||
var err error | |||
if setting.CacheOn { | |||
notice, err = getNewestNoticeFromCacheAndDisk() | |||
notice, err = getNewestNoticesFromCacheAndDisk() | |||
} else { | |||
notice, err = getNewestNoticeFromDisk() | |||
notice, err = getNewestNoticesFromDisk() | |||
} | |||
if err != nil { | |||
@@ -49,34 +53,39 @@ func getNoticeTimeout() time.Duration { | |||
return time.Duration(setting.CacheTimeOutSecond) * time.Second | |||
} | |||
func getNewestNoticeFromDisk() (*Notice, error) { | |||
func getNewestNoticesFromDisk() (*NoticeResponse, error) { | |||
log.Debug("Get notice from disk") | |||
repoFile, err := models.ReadLatestFileInRepo(setting.UserNameOfNoticeRepo, setting.RepoNameOfNoticeRepo, setting.RefNameOfNoticeRepo, setting.TreePathOfNoticeRepo) | |||
repo, err := models.GetRepositoryByOwnerAndAlias(setting.UserNameOfNoticeRepo, setting.RepoNameOfNoticeRepo) | |||
if err != nil { | |||
log.Error("get notice repo failed, error=%v", err) | |||
return nil, err | |||
} | |||
repoFile, err := models.ReadLatestFileInRepo(repo.OwnerName, repo.Name, setting.RefNameOfNoticeRepo, setting.TreePathOfNoticeRepo) | |||
if err != nil { | |||
log.Error("GetNewestNotice failed, error=%v", err) | |||
return nil, err | |||
} | |||
notice := &Notice{} | |||
json.Unmarshal(repoFile.Content, notice) | |||
if notice.Title == "" { | |||
res := &NoticeResponse{} | |||
json.Unmarshal(repoFile.Content, res) | |||
if res == nil || len(res.Notices) == 0 { | |||
return nil, err | |||
} | |||
notice.CommitId = repoFile.CommitId | |||
return notice, nil | |||
res.CommitId = repoFile.CommitId | |||
return res, nil | |||
} | |||
func getNewestNoticeFromCacheAndDisk() (*Notice, error) { | |||
func getNewestNoticesFromCacheAndDisk() (*NoticeResponse, error) { | |||
v, success := noticeCache.Get(NOTICE_CACHE_KEY) | |||
if success { | |||
log.Debug("Get notice from cache,value = %v", v) | |||
if v == nil { | |||
return nil, nil | |||
} | |||
n := v.(*Notice) | |||
n := v.(*NoticeResponse) | |||
return n, nil | |||
} | |||
notice, err := getNewestNoticeFromDisk() | |||
notice, err := getNewestNoticesFromDisk() | |||
if err != nil { | |||
log.Error("GetNewestNotice failed, error=%v", err) | |||
noticeCache.Set(NOTICE_CACHE_KEY, nil, 30*time.Second) | |||
@@ -116,8 +116,16 @@ func checkAutoLogin(ctx *context.Context) bool { | |||
} | |||
if isSucceed { | |||
isCourse := ctx.QueryBool("course") | |||
ctx.SetCookie("redirect_to", "", -1, setting.AppSubURL, "", setting.SessionConfig.Secure, true) | |||
ctx.RedirectToFirst(redirectTo, setting.AppSubURL+string(setting.LandingPageURL)) | |||
if redirectTo == "" && isCourse { | |||
redirectToCourse := setting.AppSubURL + "/" + setting.Course.OrgName | |||
ctx.RedirectToFirst(redirectToCourse) | |||
} else { | |||
ctx.RedirectToFirst(redirectTo, setting.AppSubURL+string(setting.LandingPageURL)) | |||
} | |||
return true | |||
} | |||
@@ -143,6 +151,7 @@ func SignIn(ctx *context.Context) { | |||
ctx.Data["Title"] = ctx.Tr("sign_in") | |||
ctx.Data["SignInLink"] = setting.AppSubURL + "/user/login" | |||
ctx.Data["PageIsSignIn"] = true | |||
ctx.Data["IsCourse"] = ctx.QueryBool("course") | |||
ctx.Data["PageIsLogin"] = true | |||
ctx.Data["EnableSSPI"] = models.IsSSPIEnabled() | |||
ctx.Data["EnableCloudBrain"] = true | |||
@@ -182,6 +191,7 @@ func SignInPost(ctx *context.Context, form auth.SignInForm) { | |||
ctx.Data["SignInLink"] = setting.AppSubURL + "/user/login" | |||
ctx.Data["PageIsSignIn"] = true | |||
ctx.Data["PageIsLogin"] = true | |||
ctx.Data["IsCourse"] = ctx.QueryBool("course") | |||
ctx.Data["EnableSSPI"] = models.IsSSPIEnabled() | |||
if ctx.HasError() { | |||
@@ -565,6 +575,12 @@ func handleSignInFull(ctx *context.Context, u *models.User, remember bool, obeyR | |||
return setting.AppSubURL + "/dashboard" | |||
} | |||
isCourse := ctx.QueryBool("course") | |||
if isCourse { | |||
redirectToCourse := setting.AppSubURL + "/" + setting.Course.OrgName | |||
ctx.RedirectToFirst(redirectToCourse) | |||
return redirectToCourse | |||
} | |||
if redirectTo := ctx.GetCookie("redirect_to"); len(redirectTo) > 0 && !util.IsExternalURL(redirectTo) { | |||
ctx.SetCookie("redirect_to", "", -1, setting.AppSubURL, "", setting.SessionConfig.Secure, true) | |||
if obeyRedirect { | |||
@@ -200,16 +200,7 @@ var _hmt = _hmt || []; | |||
<div class="ui top secondary stackable main menu following bar dark"> | |||
{{template "base/head_navbar" .}} | |||
</div><!-- end bar --> | |||
<!-- {{if not .IsCourse}} --> | |||
<div class="notic_content" id ="notic_content" style="display: none;"> | |||
<a href={{.notice.Link}} class="a_width"> | |||
<marquee behavior="scroll" direction="left"> | |||
{{.notice.Title}} | |||
</marquee> | |||
</a> | |||
<i class="ri-close-fill x_icon" onclick="closeNoice()"></i> | |||
</div> | |||
<!-- {{end}} --> | |||
{{template "base/head_notice" .}} | |||
{{end}} | |||
{{/* | |||
</div> | |||
@@ -233,7 +224,15 @@ var _hmt = _hmt || []; | |||
}else{ | |||
isNewNotice=false; | |||
} | |||
if (JSON.parse("{{.notice.Visible}}")){ | |||
let isShowNoticeTag = false; | |||
let notices= {{.notices.Notices}} | |||
for (i =0;i<notices.length;i++){ | |||
if (notices[i].Visible==1){ | |||
isShowNoticeTag =true; | |||
break; | |||
} | |||
} | |||
if (isShowNoticeTag){ | |||
if(isNewNotice){ | |||
document.getElementById("notic_content").style.display='block' | |||
}else{ | |||
@@ -249,6 +248,7 @@ var _hmt = _hmt || []; | |||
document.getElementById("notic_content").style.display='none' | |||
} | |||
} | |||
if(!("{{.IsCourse}}" == true || "{{.IsCourse}}" =='true')) { | |||
isShowNotice(); | |||
} | |||
@@ -201,14 +201,7 @@ var _hmt = _hmt || []; | |||
<div class="ui top secondary stackable main menu following bar dark"> | |||
{{template "base/head_navbar_fluid" .}} | |||
</div><!-- end bar --> | |||
<div class="notic_content" id ="notic_content" style="display: none;"> | |||
<a href={{.notice.Link}} class="a_width"> | |||
<marquee behavior="scroll" direction="left"> | |||
{{.notice.Title}} | |||
</marquee> | |||
</a> | |||
<i class="ri-close-fill x_icon" onclick="closeNoice()"></i> | |||
</div> | |||
{{template "base/head_notice" .}} | |||
{{end}} | |||
{{/* | |||
</div> | |||
@@ -232,7 +225,15 @@ var _hmt = _hmt || []; | |||
}else{ | |||
isNewNotice=false; | |||
} | |||
if (JSON.parse("{{.notice.Visible}}")){ | |||
let isShowNoticeTag = false; | |||
let notices= {{.notices.Notices}} | |||
for (i =0;i<notices.length;i++){ | |||
if (notices[i].Visible==1){ | |||
isShowNoticeTag =true; | |||
break; | |||
} | |||
} | |||
if (isShowNoticeTag){ | |||
if(isNewNotice){ | |||
document.getElementById("notic_content").style.display='block' | |||
}else{ | |||
@@ -248,6 +249,7 @@ var _hmt = _hmt || []; | |||
document.getElementById("notic_content").style.display='none' | |||
} | |||
} | |||
if(!("{{.IsCourse}}" == true || "{{.IsCourse}}" =='true')) { | |||
isShowNotice(); | |||
} |
@@ -205,14 +205,7 @@ var _hmt = _hmt || []; | |||
<div class="ui top secondary stackable main menu following bar dark"> | |||
{{template "base/head_navbar" .}} | |||
</div><!-- end bar --> | |||
<div class="notic_content" id ="notic_content" style="display: none;" > | |||
<a href={{.notice.Link}} class="a_width"> | |||
<marquee behavior="scroll" direction="left"> | |||
{{.notice.Title}} | |||
</marquee> | |||
</a> | |||
<i class="ri-close-fill x_icon" onclick="closeNoice()"></i> | |||
</div> | |||
{{template "base/head_notice" .}} | |||
{{end}} | |||
{{/* | |||
</div> | |||
@@ -236,7 +229,15 @@ var _hmt = _hmt || []; | |||
}else{ | |||
isNewNotice=false; | |||
} | |||
if (JSON.parse("{{.notice.Visible}}")){ | |||
let isShowNoticeTag = false; | |||
let notices= {{.notices.Notices}} | |||
for (i =0;i<notices.length;i++){ | |||
if (notices[i].Visible==1){ | |||
isShowNoticeTag =true; | |||
break; | |||
} | |||
} | |||
if (isShowNoticeTag){ | |||
if(isNewNotice){ | |||
document.getElementById("notic_content").style.display='block' | |||
}else{ | |||
@@ -252,6 +253,7 @@ var _hmt = _hmt || []; | |||
document.getElementById("notic_content").style.display='none' | |||
} | |||
} | |||
if(!("{{.IsCourse}}" == true || "{{.IsCourse}}" =='true')) { | |||
isShowNotice(); | |||
} |
@@ -211,13 +211,25 @@ | |||
</div> | |||
</form> | |||
{{if .ShowRegistrationButton}} | |||
<a class="item{{if .PageIsSignUp}} active{{end}}" href="{{AppSubUrl}}/user/sign_up"> | |||
{{svg "octicon-person" 16}} {{.i18n.Tr "register"}} | |||
{{if .IsCourse}} | |||
<a class="item{{if .PageIsSignUp}} active{{end}}" href="https://git.openi.org.cn/user/sign_up" target="_blank"> | |||
{{svg "octicon-person" 16}} {{.i18n.Tr "register"}} | |||
</a> | |||
{{else}} | |||
<a class="item{{if .PageIsSignUp}} active{{end}}" href="{{AppSubUrl}}/user/sign_up"> | |||
{{svg "octicon-person" 16}} {{.i18n.Tr "register"}} | |||
</a> | |||
{{end}} | |||
{{end}} | |||
{{if .IsCourse}} | |||
<a class="item{{if .PageIsSignIn}} active{{end}}" rel="nofollow" href="https://git.openi.org.cn/user/login?course=true" target="_blank"> | |||
{{svg "octicon-sign-in" 16}} {{.i18n.Tr "sign_in"}} | |||
</a> | |||
{{else}} | |||
<a class="item{{if .PageIsSignIn}} active{{end}}" rel="nofollow" href="{{AppSubUrl}}/user/login"> | |||
{{svg "octicon-sign-in" 16}} {{.i18n.Tr "sign_in"}} | |||
</a> | |||
{{end}} | |||
<a class="item{{if .PageIsSignIn}} active{{end}}" rel="nofollow" href="{{AppSubUrl}}/user/login"> | |||
{{svg "octicon-sign-in" 16}} {{.i18n.Tr "sign_in"}} | |||
</a> | |||
</div><!-- end anonymous right menu --> | |||
{{end}} | |||
@@ -0,0 +1,32 @@ | |||
{{if not .IsCourse}} | |||
{{ if .notices}} | |||
<div class="notic_content" id ="notic_content" style="display: block; position: relative"> | |||
<diV class="ui container"> | |||
<marquee behavior="scroll" direction="left"> | |||
{{ $firstTag := true }} | |||
{{range .notices.Notices}} | |||
{{if eq .Visible 1}} | |||
{{if $firstTag}} | |||
<a href={{.Link}} class="a_width" style = 'margin-left: 0px !important;' target="_blank"> | |||
<i class="ri-arrow-right-s-line"></i> | |||
{{.Title}} | |||
</a> | |||
{{else}} | |||
<a href={{.Link}} class="a_width" target="_blank"> | |||
<i class="ri-arrow-right-s-line"></i> | |||
{{.Title}} | |||
</a> | |||
{{end}} | |||
{{ $firstTag = false }} | |||
{{end}} | |||
{{end}} | |||
</marquee> | |||
<div class="item right" style="position:absolute;right: 1px;top:0px;"> | |||
<i class="ri-close-fill x_icon" onclick="closeNoice()"></i> | |||
</div> | |||
</diV> | |||
</div> | |||
{{end}} | |||
{{end}} |
@@ -201,14 +201,7 @@ var _hmt = _hmt || []; | |||
<div class="ui top secondary stackable main menu following bar dark"> | |||
{{template "base/head_navbar_pro" .}} | |||
</div><!-- end bar --> | |||
<div class="notic_content" id ="notic_content" style="display: none;" > | |||
<a href={{.notice.Link}} class="a_width"> | |||
<marquee behavior="scroll" direction="left"> | |||
{{.notice.Title}} | |||
</marquee> | |||
</a> | |||
<i class="icon icon-octicon x_icon" onclick="closeNoice()">{{svg "octicon-x" 16}}</i> | |||
</div> | |||
{{template "base/head_notice" .}} | |||
{{end}} | |||
{{/* | |||
</div> | |||
@@ -233,7 +226,15 @@ var _hmt = _hmt || []; | |||
}else{ | |||
isNewNotice=false; | |||
} | |||
if (JSON.parse("{{.notice.Visible}}")){ | |||
let isShowNoticeTag = false; | |||
let notices= {{.notices.Notices}} | |||
for (i =0;i<notices.length;i++){ | |||
if (notices[i].Visible==1){ | |||
isShowNoticeTag =true; | |||
break; | |||
} | |||
} | |||
if (isShowNoticeTag){ | |||
if(isNewNotice){ | |||
document.getElementById("notic_content").style.display='block' | |||
}else{ | |||
@@ -249,6 +250,7 @@ var _hmt = _hmt || []; | |||
document.getElementById("notic_content").style.display='none' | |||
} | |||
} | |||
if(!("{{.IsCourse}}" == true || "{{.IsCourse}}" =='true')) { | |||
isShowNotice(); | |||
} |
@@ -96,7 +96,7 @@ | |||
{{if .Topics }} | |||
<div class="omit tags " style="position: relative;"> | |||
{{range .Topics}} | |||
{{if ne . "" }}<a style="max-width:100%;margin: 5px 0;display:inline-flex;" ><span class="ui small label topic course_topic" >{{.}}</span></a>{{end}} | |||
{{if ne . "" }}<a style="max-width:100%;margin: 5px 0;display:inline-flex;cursor:default" ><span class="ui small label topic course_topic" >{{.}}</span></a>{{end}} | |||
{{end}} | |||
</div> | |||
@@ -136,11 +136,7 @@ | |||
<div class="ui sixteen wide mobile six wide tablet four wide computer column"> | |||
<div class=" ui bottom attached segment text center noborder text center" > | |||
{{if .IsSigned}} | |||
<a style="width: 80%;" class="ui green button bpadding" href="{{AppSubUrl}}/course/create"><i class="ri-folder-add-line" style="vertical-align: middle;"></i> {{.i18n.Tr "org.release_course"}} </a> | |||
{{else}} | |||
<a style="width: 80%;" class="ui green button bpadding" href="{{AppSubUrl}}/user/login"><i class="ri-folder-add-line" style="vertical-align: middle;"></i> {{.i18n.Tr "org.release_course"}} </a> | |||
{{end}} | |||
<a style="width: 80%;" class="ui green button bpadding" href="https://git.openi.org.cn/course/create" target="_blank"><i class="ri-folder-add-line" style="vertical-align: middle;"></i> {{.i18n.Tr "org.release_course"}} </a> | |||
</div> | |||
</div> | |||
</div> | |||
@@ -209,7 +205,7 @@ | |||
{{if .IsSigned}} | |||
<a class="ui blue basic button" onclick="jion_course_team()" style="width: 80%;"> <i class="ri-user-add-line"></i> {{.i18n.Tr "org.teams.join_teams"}}</a> | |||
{{else}} | |||
<a class="ui blue basic button" href="{{AppSubUrl}}/user/login" style="width: 80%;"> <i class="ri-user-add-line"></i> {{.i18n.Tr "org.teams.join_teams"}}</a> | |||
<a class="ui blue basic button" href="https://git.openi.org.cn/user/login?course=true" style="width: 80%;" target="_blank"> <i class="ri-user-add-line"></i> {{.i18n.Tr "org.teams.join_teams"}}</a> | |||
{{end}} | |||
</div> | |||
</div> | |||
@@ -29,7 +29,11 @@ | |||
<div class="ui grid"> | |||
<div class="column"> | |||
<form class="ui form" action="{{.SignInLink}}" method="post"> | |||
{{if .IsCourse}} | |||
<form class="ui form" action="{{.SignInLink}}?course=true" method="post"> | |||
{{else}} | |||
<form class="ui form" action="{{.SignInLink}}" method="post"> | |||
{{end}} | |||
{{.CsrfTokenHtml}} | |||
<div class="field"> | |||
<div class="ui left icon input {{if and (.Err_UserName) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeSignIn))}}error{{end}}"> | |||
@@ -604,10 +604,13 @@ display: block; | |||
font-weight: bold !important; | |||
} | |||
.a_width{ | |||
width: 50% !important; | |||
display:inline-block !important; | |||
// width: 50% !important; | |||
margin-left: 20em; | |||
// display:inline-block !important; | |||
} | |||
.a_width i{ | |||
vertical-align:middle!important; | |||
} | |||
.footer_icon{ | |||
display: inline-block !important; | |||
vertical-align: middle !important; | |||
Dear OpenI User
Thank you for your continuous support to the Openl Qizhi Community AI Collaboration Platform. In order to protect your usage rights and ensure network security, we updated the Openl Qizhi Community AI Collaboration Platform Usage Agreement in January 2024. The updated agreement specifies that users are prohibited from using intranet penetration tools. After you click "Agree and continue", you can continue to use our services. Thank you for your cooperation and understanding.
For more agreement content, please refer to the《Openl Qizhi Community AI Collaboration Platform Usage Agreement》