Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: telegram chat authorization via jira
Browse files Browse the repository at this point in the history
boggard committed Jun 27, 2023
1 parent 864c9a4 commit 56c106e
Showing 14 changed files with 81 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -13,8 +13,8 @@ data class Chat(
@GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Int?,

@Column(name = "jira_id", nullable = false)
val jiraId: String,
@Column(name = "jira_id")
var jiraId: String?,

@Column(name = "telegram_id", nullable = false)
val telegramId: Long,
Original file line number Diff line number Diff line change
@@ -18,16 +18,20 @@ class ChatService(private val chatRepository: ChatRepository, private val chatTa
val validatedJiraLogin = validateJiraLogin(jiraLogin)
val validatedTelegramId = validateTelegramId(telegramId)

val chat = Chat(null, validatedJiraLogin, validatedTelegramId, State.INIT)
chatRepository.save(chat)
addChatInState(validatedTelegramId, validatedJiraLogin, State.INIT)
}

fun addChatInState(telegramId: Long, jiraId: String?, state: State) {
val chat = Chat(null, jiraId, telegramId, state)
save(chat)
}

fun getAll() : List<Chat> {
return chatRepository.findAll()
}

fun getAllLogins() : List<String> {
return chatRepository.findAll().map { it.jiraId }
return chatRepository.findAll().map { it.jiraId }.filterNotNull()
}

fun findByJiraId(jiraId: String): Chat? {
@@ -47,6 +51,13 @@ class ChatService(private val chatRepository: ChatRepository, private val chatTa
}
}

fun updateJiraId(telegramId: Long, jiraId: String) {
findByTelegramId(telegramId)?.let {
it.jiraId = jiraId
save(it)
}
}

fun save(chat: Chat): Chat {
return chatRepository.save(chat)
}
Original file line number Diff line number Diff line change
@@ -18,6 +18,6 @@ class TagService(private val repository: TagRepository) {
@Transactional
fun getJiraLoginsByTagKey(key: String): List<String> {
val tag = getTagByKey(key) ?: return emptyList()
return tag.chats.map { it.jiraId }
return tag.chats.mapNotNull { it.jiraId }
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.github.mikesafonov.jira.telegram.service.jira

import com.atlassian.jira.rest.client.api.domain.Issue
import com.atlassian.jira.rest.client.api.domain.User
import com.atlassian.jira.rest.client.internal.async.AsynchronousHttpClientFactory
import com.github.mikesafonov.jira.telegram.config.conditional.ConditionalOnJiraOAuth
import org.springframework.stereotype.Service

@@ -41,4 +43,10 @@ class JiraApiService(private val jiraRestClientFactory: JiraRestClientFactory) {
.getIssue(issueKey)
.claim()
}

fun getMySelf(telegramId: Long): User? {
return jiraRestClientFactory.createMySelfRestClient(telegramId)
.getMySelf()
.claim()
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.github.mikesafonov.jira.telegram.service.jira

import com.atlassian.jira.rest.client.api.JiraRestClient
import com.atlassian.jira.rest.client.internal.async.AsynchronousHttpClientFactory
import com.atlassian.jira.rest.client.internal.async.AsynchronousJiraRestClientFactory
import com.github.mikesafonov.jira.telegram.config.JiraOAuthProperties
import com.github.mikesafonov.jira.telegram.config.conditional.ConditionalOnJiraOAuth
@@ -26,4 +27,12 @@ class JiraRestClientFactory(
JiraOAuthAuthenticationHandler(oAuthParameters)
)
}

fun createMySelfRestClient(telegramId: Long): MySelfRestClient {
val oAuthParameters = authService.getOAuthParameters(telegramId)
val serverUri = URI(jiraProperties.baseUrl)
val httpClient = AsynchronousHttpClientFactory().createClient(serverUri,
JiraOAuthAuthenticationHandler(oAuthParameters))
return MySelfRestClient(httpClient, serverUri)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.github.mikesafonov.jira.telegram.service.jira

import com.atlassian.httpclient.api.HttpClient
import com.atlassian.jira.rest.client.api.domain.User
import com.atlassian.jira.rest.client.internal.async.AbstractAsynchronousRestClient
import com.atlassian.jira.rest.client.internal.json.UserJsonParser
import io.atlassian.util.concurrent.Promise
import java.net.URI
import javax.ws.rs.core.UriBuilder


class MySelfRestClient(httpClient: HttpClient, serverUri: URI) : AbstractAsynchronousRestClient(httpClient) {

private val baseUri: URI
private val userJsonParser = UserJsonParser()

init {
baseUri = UriBuilder.fromUri(serverUri).path("/rest/api/latest").build()
}

fun getMySelf(): Promise<User> {
val userUri = UriBuilder.fromUri(baseUri).path("myself").build()
return getAndParse(userUri, userJsonParser)
}
}
Original file line number Diff line number Diff line change
@@ -46,6 +46,6 @@ data class TelegramCommand(
}

fun isAnonymous() : Boolean{
return chat == null
return chat?.jiraId == null && chat?.state != State.WAIT_APPROVE
}
}
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@ import com.github.mikesafonov.jira.telegram.service.AuthorizationService
import com.github.mikesafonov.jira.telegram.service.ChatService
import mu.KotlinLogging
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import org.telegram.telegrambots.meta.api.objects.Message
import org.telegram.telegrambots.meta.api.objects.Update

@@ -22,6 +23,7 @@ class TelegramUpdateManager(
/**
* process [update]
*/
@Transactional
fun onUpdate(update: Update) {
if (update.hasMessage() && update.message.hasText()) {
val telegramCommand = toCommand(update.message)
@@ -45,7 +47,9 @@ class TelegramUpdateManager(
command: TelegramCommand,
nextState: State
) {
if (command.chat != null && command.chat.state != nextState) {
if (command.chat == null) {
chatService.addChatInState(command.chatId, null, nextState)
} else if (command.chat.state != nextState) {
command.chat.state = nextState
chatService.save(command.chat)
}
Original file line number Diff line number Diff line change
@@ -2,6 +2,8 @@ package com.github.mikesafonov.jira.telegram.service.telegram.handlers

import com.github.mikesafonov.jira.telegram.config.conditional.ConditionalOnJiraOAuth
import com.github.mikesafonov.jira.telegram.dao.State
import com.github.mikesafonov.jira.telegram.service.ChatService
import com.github.mikesafonov.jira.telegram.service.jira.JiraApiService
import com.github.mikesafonov.jira.telegram.service.jira.JiraAuthService
import com.github.mikesafonov.jira.telegram.service.telegram.TelegramClient
import com.github.mikesafonov.jira.telegram.service.telegram.TelegramCommand
@@ -18,6 +20,8 @@ private val logger = KotlinLogging.logger {}
@ConditionalOnJiraOAuth
class JiraAuthApproveTelegramCommandHandler(
private val jiraAuthService: JiraAuthService,
private val jiraApiService: JiraApiService,
private val chatService: ChatService,
telegramClient: TelegramClient
) : BaseCommandHandler(telegramClient) {

@@ -33,7 +37,13 @@ class JiraAuthApproveTelegramCommandHandler(
} else {
try {
jiraAuthService.createAccessToken(id, command.text!!)
replaceUserMessage(id, messageId, "Authorization success!")
val username = jiraApiService.getMySelf(id)?.name
if (username == null) {
replaceUserMessage(id, messageId, "Can't get username from jira!")
} else {
chatService.updateJiraId(id, username)
replaceUserMessage(id, messageId, "Authorization success!")
}
} catch (e: HttpResponseException) {
logger.error(e.message, e)
val message = "${e.statusCode} ${e.content}"
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ class JiraAuthTelegramCommandHandler(
telegramClient: TelegramClient
) : BaseCommandHandler(telegramClient) {
override fun isHandle(command: TelegramCommand): Boolean {
return command.isInState(State.INIT) && command.isMatchText("/auth")
return command.isAnonymous()
}

override fun handle(command: TelegramCommand): State {
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@ class MyIssuesTelegramCommandHandler(
override fun handle(command: TelegramCommand): State {
val jiraId = command.chat!!.jiraId
val telegramId = command.chat.telegramId
if(command.authorization == null){
if(command.authorization == null || jiraId == null){
telegramClient.sendTextMessage(telegramId, "You must be logged in to use this command. Use the /auth to log in to JIRA")
} else {
val myIssues = jiraApiService.getMyIssues(telegramId, jiraId)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE chats ALTER COLUMN jira_id DROP NOT NULL;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE chats MODIFY COLUMN jira_id varchar(100);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ALTER TABLE chats ALTER COLUMN jira_id DROP NOT NULL;

0 comments on commit 56c106e

Please sign in to comment.